<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7432762749103693871</id><updated>2012-01-26T12:19:57.025Z</updated><title type='text'>WPF Mentor</title><subtitle type='html'>&lt;br&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-2567794026042218642</id><published>2009-02-09T17:53:00.003Z</published><updated>2009-02-09T20:16:49.617Z</updated><title type='text'>How to use the controls from NavigationWindow in your own Window</title><content type='html'>I've made a control containing &lt;b&gt;back and forward buttons&lt;/b&gt; and a &lt;b&gt;history&lt;/b&gt; menu in the style of IE 7. The XAML has been lifted directly from the WPF NavigationWindow template and converted to a control so it can be used in the normal way.
&lt;br/&gt;&lt;br/&gt;
Here's a screenshot of the controls I am talking about (magnified 2x here):
&lt;br/&gt;&lt;br/&gt;

&lt;img src="http://sites.google.com/a/wpfmentor.com/resources/Home/navigationwindow.PNG"/&gt;&lt;br/&gt;

&lt;br/&gt;&lt;br/&gt;
These are the step I went through to do this:
&lt;br/&gt;&lt;br/&gt;
&lt;ul&gt;
&lt;li&gt;A new Custom Control was created named &lt;b&gt;NavigationControl&lt;/b&gt;. This was changed to derive from &lt;b&gt;System.Windows.Controls.Selector&lt;/b&gt; as the control will contain a list of items of which one can be selected.&lt;/li&gt;

&lt;li&gt;The &lt;a href="http://blog.lutzroeder.com/2007/01/baml-viewer-add-in-for-net-reflector.html"&gt;BAML Viewer&lt;/a&gt; plugin for &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt; was used to extract the default style for the Navigation Window. The template XAML was copied and pasted to the template for NavigationControl.&lt;/li&gt;
&lt;li&gt;The various components were extracted out into separate resource dictionaries for the different components to aid readability.&lt;/li&gt;
&lt;li&gt;The button XAML was repeated for the two buttons. This was converted into one and a trigger was added to switch between the two.&lt;/li&gt;
&lt;li&gt;A class called &lt;b&gt;ThemedResourceDictionarySelector&lt;/b&gt; was created to assist in defining the themed parts of the template. This meant that the entire template did not need to be repeated for each theme.&lt;/li&gt;
&lt;li&gt;Code behind was added so that the menu was correctly populated when the items of NavigationControl changed.&lt;/li&gt;
&lt;/ul&gt;


&lt;br/&gt;&lt;br/&gt;
&lt;a target="_blank" href="http://sites.google.com/a/wpfmentor.com/resources/navigation"&gt;Download source code&lt;/a&gt;

&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-2567794026042218642?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/2567794026042218642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=2567794026042218642' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/2567794026042218642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/2567794026042218642'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/02/how-to-use-controls-from.html' title='How to use the controls from NavigationWindow in your own Window'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-3039996046035010617</id><published>2009-01-30T17:06:00.008Z</published><updated>2009-01-31T13:13:37.813Z</updated><title type='text'>How to recreate the Microsoft Office Access welcome page in XAML</title><content type='html'>I've recreated the Microsoft Office Access welcome/home page using XAML.
&lt;br/&gt;&lt;br/&gt;
This is the kind of thing that WPF is so great for...and is a complete nightmare to do in WinForms. You can download the source using the link at the bottom of the post.
&lt;br/&gt;&lt;br/&gt;
Click &lt;a target="_blank" href="http://sites.google.com/a/wpfmentor.com/resources/Home/access_full.PNG"&gt;here&lt;/a&gt; for the full screen shot.&lt;br/&gt;
&lt;a target="_blank" href="http://sites.google.com/a/wpfmentor.com/resources/Home/access_full.PNG"&gt;&lt;img width="577" height="480" src="http://sites.google.com/a/wpfmentor.com/resources/Home/access.PNG"&gt;&lt;/a&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;a target="_blank" href="http://sites.google.com/a/wpfmentor.com/resources/accesshomepage"&gt;Download source code&lt;/a&gt;

&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-3039996046035010617?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/3039996046035010617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=3039996046035010617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/3039996046035010617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/3039996046035010617'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-re-create-microsoft-access.html' title='How to recreate the Microsoft Office Access welcome page in XAML'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-4959328189132205372</id><published>2009-01-28T14:33:00.005Z</published><updated>2009-01-29T15:52:35.528Z</updated><title type='text'>How to add custom data to an AutomationPeer</title><content type='html'>In a recent project, we needed to provide extra data through Automation in order to achieve more rigorous testing. We wanted some of our own properties and data types unrelated to the available control patterns and properties.
&lt;br/&gt;&lt;br/&gt;
After spending some time searching for a mechanism to add new properties we came to the conclusion that there wasn't one - the only choice is to hijack an existing property. As far as I can tell the only automation property you're allowed to put whatever you want in is &lt;b&gt;ItemStatus&lt;/b&gt;. 
&lt;br/&gt;&lt;br/&gt;
The &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.automation.automationproperties.itemstatus.aspx"&gt;MSDN page for ItemStatus&lt;/a&gt; says:

&lt;ul&gt;
&lt;li&gt;Gets or sets a description of the status of an item within an element.&lt;/li&gt;
&lt;li&gt;This property enables a client to ascertain whether an element is conveying status about an item. For example, an item associated with a contact in a messaging application might be "Busy" or "Connected". &lt;/li&gt;
&lt;/ul&gt;

That sounds pretty hijackable to me.
&lt;br/&gt;&lt;br/&gt;
ItemStatus is hidden by default in UISpy but you can show it by going to:&lt;br/&gt; 
View -&gt; Configure Properties -&gt; AutomationElement -&gt; Misc
&lt;br/&gt;&lt;br/&gt;
You set it in your automation peer by overriding &lt;b&gt;GetItemStatusCore()&lt;/b&gt;. You can then serialize any type and send it through:

&lt;pre name="code" class="c#"&gt;
public class Window1AutomationPeer : WindowAutomationPeer
{
    public Window1AutomationPeer(Window1 owner)
        : base(owner)
    {
    }

    protected override string GetItemStatusCore()
    {
        // use XmlSerializer to serialize custom data
        
        XmlSerializer serializer = new XmlSerializer(typeof(CustomData));
        CustomData data = new CustomData(...);
        StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
        serializer.Serialize(stringWriter, data);
        return stringWriter.ToString();
    }
}

&lt;/pre&gt;

The &lt;a href="http://sites.google.com/a/wpfmentor.com/resources/customautomationdata"&gt;example&lt;/a&gt; contains a working example complete with app, automation-client and XML serialization.

&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-4959328189132205372?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/4959328189132205372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=4959328189132205372' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4959328189132205372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4959328189132205372'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-add-custom-data-to.html' title='How to add custom data to an AutomationPeer'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-4046918331035179858</id><published>2009-01-27T17:00:00.002Z</published><updated>2009-01-27T19:14:44.594Z</updated><title type='text'>How to find out what that XamlParseException really means using MarkupSource tracing</title><content type='html'>It's sometimes pretty difficult to work out what the &lt;b&gt;XamlParseException&lt;/b&gt; thrown when your app starts really means. WPF Markup tracing logs everything in the output window as the XAML is loaded - this nearly always gets you to the source of the problem.
&lt;br/&gt;&lt;br/&gt;

&lt;img width=581 height=416 src="http://sites.google.com/a/wpfmentor.com/resources/Home/markupsourcelog.PNG"&gt;
&lt;br/&gt;&lt;br/&gt;
You can turn it on like this:
&lt;pre name="code" class="c#"&gt;
public Window1()
{
    PresentationTraceSources.Refresh();
    PresentationTraceSources.MarkupSource.Switch.Level = SourceLevels.All;
    PresentationTraceSources.MarkupSource.Listeners.Add(new DefaultTraceListener());
    ...
}
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-4046918331035179858?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/4046918331035179858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=4046918331035179858' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4046918331035179858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4046918331035179858'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-find-out-what-that.html' title='How to find out what that XamlParseException really means using MarkupSource tracing'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-8918821256545507071</id><published>2009-01-27T15:04:00.007Z</published><updated>2009-01-29T15:54:35.814Z</updated><title type='text'>How to add a binding to the CommandParameter of a KeyBinding or MouseBinding</title><content type='html'>You can't add a binding to the command parameter of an InputBinding. Although InputBinding does derive from DependencyObject, the CommandParameter property is a CLR property. It was implemented in this way as InputBindings don't sit in an inheritance context and so normal bindings are not supported.
&lt;br/&gt;&lt;br/&gt;
Fortunately, this can be worked around in the same way as in my previous post:

&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window.Resources&amp;gt;
    &amp;lt;my:DataResource x:Key="cp" BindingTarget="{Binding MyCommandParameter}"/&amp;gt;
&amp;lt;/Window.Resources&amp;gt;
&amp;lt;TextBox&amp;gt;
    &amp;lt;TextBox.InputBindings&amp;gt;
        &amp;lt;MouseBinding 
            Command="ApplicationCommands.Open" 
            MouseAction="LeftDoubleClick"&amp;gt;
            &amp;lt;MouseBinding.CommandParameter&amp;gt;
                &amp;lt;my:DataResourceBinding DataResource="{StaticResource cp}"/&amp;gt;
            &amp;lt;/MouseBinding.CommandParameter&amp;gt;
        &amp;lt;/MouseBinding&amp;gt;
    &amp;lt;/TextBox.InputBindings&amp;gt;
&amp;lt;/TextBox&amp;gt;

&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/dataresource"&gt;DataResource.cs&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/commandparameterbindings"&gt;Download sample app with source code&lt;/a&gt;


&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-8918821256545507071?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/8918821256545507071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=8918821256545507071' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/8918821256545507071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/8918821256545507071'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-add-binding-to-commandparameter.html' title='How to add a binding to the CommandParameter of a KeyBinding or MouseBinding'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-1191057948311695077</id><published>2009-01-27T14:39:00.004Z</published><updated>2009-01-29T16:00:31.145Z</updated><title type='text'>How to add a binding to a property on a ValidationRule</title><content type='html'>You can't add bindings to properties on classes that derive from ValidationRule in the normal way. This is because validation rules don't sit in an inheritance context and don't derive from DependencyObject.

&lt;br/&gt;&lt;br/&gt;

Fortunately, this can easily be worked around using the &lt;b&gt;DataResource&lt;/b&gt; technique from a previous post. Here's how you would use this technique for max/min integer validation.

&lt;br/&gt;&lt;br/&gt;
First create the rule class:
&lt;pre name="code" class="c#"&gt;
public class IntValidationRule : ValidationRule
{
    public int Max { get; set; }
    public int Min { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        try
        {
            int i = Convert.ToInt32(value);
            return (i &lt; Min || i &gt; Max) ?
                new ValidationResult(false, "int out of range") :
                new ValidationResult(true, null);
        }
        catch (FormatException fe)
        {
            return new ValidationResult(false, fe.Message);
        }
    }
}
&lt;/pre&gt;

...the DataResources and the associated bindings should then simply be set up like this:

&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window.Resources&amp;gt;
    &amp;lt;my:DataResource x:Key="max" BindingTarget="{Binding Max}"/&amp;gt;
    &amp;lt;my:DataResource x:Key="min" BindingTarget="{Binding Min}"/&amp;gt;
&amp;lt;/Window.Resources&amp;gt;

&amp;lt;TextBox&amp;gt;
    &amp;lt;TextBox.Text&amp;gt;
        &amp;lt;Binding UpdateSourceTrigger="PropertyChanged" Path="Value"&amp;gt;
            &amp;lt;Binding.ValidationRules&amp;gt;
                &amp;lt;my:IntValidationRule 
                    ValidatesOnTargetUpdated="True" 
                    Min="{my:DataResourceBinding DataResource={StaticResource min}}"
                    Max="{my:DataResourceBinding DataResource={StaticResource max}}"&amp;gt;
                &amp;lt;/my:IntValidationRule&amp;gt;
            &amp;lt;/Binding.ValidationRules&amp;gt;
        &amp;lt;/Binding&amp;gt;
    &amp;lt;/TextBox.Text&amp;gt;
&amp;lt;/TextBox&amp;gt;

&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/dataresource"&gt;DataResource.cs&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/validationrulebindings"&gt;Download sample app with source code&lt;/a&gt;


&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-1191057948311695077?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/1191057948311695077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=1191057948311695077' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/1191057948311695077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/1191057948311695077'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-add-binding-to-property-on.html' title='How to add a binding to a property on a ValidationRule'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-8184229156521708882</id><published>2009-01-23T18:51:00.002Z</published><updated>2009-01-29T16:01:43.829Z</updated><title type='text'>How to get the HWND and hook into the WndProc of a WPF application</title><content type='html'>I've written a quick sample which hooks into the WM_ messages and displays them real-time. It looks like this:
&lt;br/&gt;&lt;br/&gt;

&lt;img src="http://sites.google.com/a/wpfmentor.com/resources/Home/windowsmessages.PNG"/&gt;
&lt;br/&gt;&lt;br/&gt;
This is the code that does the work:

&lt;pre name="code" class="C#"&gt;

private void Window1_Loaded(object sender, RoutedEventArgs e)
{
    // do this to get the HWND and set up the window hook
    WindowInteropHelper helper = new WindowInteropHelper(this);
    HwndSource.FromHwnd(helper.Handle).AddHook(HwndSourceHookHandler);
}

private IntPtr HwndSourceHookHandler(IntPtr hwnd, int msg, IntPtr wParam, 
    IntPtr lParam, ref bool handled)
{
    // this is the window hook handler
}

&lt;/pre&gt;

&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/win32"&gt;Download sample app with source code&lt;/a&gt;

&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-8184229156521708882?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/8184229156521708882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=8184229156521708882' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/8184229156521708882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/8184229156521708882'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-get-hwnd-and-hook-into-wndproc.html' title='How to get the HWND and hook into the WndProc of a WPF application'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-7916111852513499903</id><published>2009-01-22T18:05:00.007Z</published><updated>2009-01-29T15:59:10.777Z</updated><title type='text'>How to debug triggers using Trigger-Tracing</title><content type='html'>Debugging triggers is a painful process: they work behind the scenes, there's nowhere to put a breakpoint and no call-stack to help you. The usual approach taken is trial and error based and it nearly always takes longer than it should to work out what's going wrong.

&lt;br/&gt;&lt;br/&gt;

This post describes a new technique for debugging triggers allowing you to log all trigger actions along with the elements being acted upon:
&lt;br/&gt;&lt;br/&gt;
&lt;img width=694 height=220 src="http://sites.google.com/a/wpfmentor.com/resources/Home/traceoutput.PNG"/&gt;
&lt;br/&gt;

It's good because it:
&lt;ul&gt;
&lt;li&gt;helps you fix all manner of problems :)&lt;/li&gt;
&lt;li&gt;works on all types of trigger: Trigger, DataTrigger, MultiTrigger etc.&lt;/li&gt;
&lt;li&gt;allows you to add breakpoints when any trigger is entered and/or exited&lt;/li&gt;
&lt;li&gt;is easy to set up: just drop one source file &lt;i&gt;(TriggerTracing.cs)&lt;/i&gt; into your app and set these attached properties to the trigger to be traced:

&lt;pre name="code" class="xaml"&gt;
&amp;lt;Trigger my:TriggerTracing.TriggerName="BoldWhenMouseIsOver"
         my:TriggerTracing.TraceEnabled="True"
         Property="IsMouseOver"
         Value="True"&amp;gt;
    &amp;lt;Setter Property="FontWeight" Value="Bold"/&amp;gt;
&amp;lt;/Trigger&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
It works by:

&lt;ul&gt;
&lt;li&gt;using attached properties to add dummy animation storyboards to the trigger&lt;/li&gt;
&lt;li&gt;activating WPF animation tracing and filtering the results to only the entries with the dummy storyboards&lt;/li&gt;
&lt;/ul&gt;

&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/triggertracingsample"&gt;Download sample app with source code&lt;/a&gt;


&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-7916111852513499903?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/7916111852513499903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=7916111852513499903' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/7916111852513499903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/7916111852513499903'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-debug-triggers-using-trigger.html' title='How to debug triggers using Trigger-Tracing'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-6411616620624136236</id><published>2009-01-16T15:25:00.003Z</published><updated>2009-01-29T15:45:41.650Z</updated><title type='text'>How to transfer rich text from a FlowDocument to a FormattedText object</title><content type='html'>The &lt;b&gt;FormattedText&lt;/b&gt; class provides low-level control for drawing text. It gives you high performance multi-line text rendering in which each character in the text can be individually formatted.
&lt;br/&gt;&lt;br/&gt;
Other aspects of text in WPF handle text in the context of controls that are dedicated to text (TextBlock, TextBox, RichTextBox), implement the &lt;b&gt;FlowDocument&lt;/b&gt; model. As far as I can tell, there is no direct way to transfer text from a FlowDocument to a FormattedText object. This post outlines how it can be done with a bit of jiggery poker.
&lt;br/&gt;&lt;br/&gt;

The tricky part of this process is traversing through the runs and paragraphs in the FlowDocument:

&lt;pre name="code" class="c#"&gt;
private IEnumerable&amp;lt;TextElement&amp;gt; GetRunsAndParagraphs(FlowDocument doc)
{
    // use the GetNextContextPosition method to iterate through the
    // FlowDocument
    
    for (TextPointer position = doc.ContentStart;
        position != null &amp;&amp; position.CompareTo(doc.ContentEnd) &lt;= 0;
        position = position.GetNextContextPosition(LogicalDirection.Forward))
    {
        if (position.GetPointerContext(LogicalDirection.Forward) == 
            TextPointerContext.ElementEnd)
        {
            // return solely the Runs and Paragraphs. all other elements are 
            // ignored since they aren't supported by FormattedText.
            
            Run run = position.Parent as Run;

            if (run != null)
            {
                yield return run;
            }
            else
            {
                Paragraph para = position.Parent as Paragraph;

                if (para != null)
                {
                    yield return para;
                }
            }
        }
    }
}
&lt;/pre&gt;

The rest of process is fairly straightforward. Use the GetRunsAndParagraphs method and build up the formatting on a FormattedText object:

&lt;pre name="code" class="c#"&gt;
public FormattedText GetFormattedText(FlowDocument doc)
{
    if (doc == null)
    {
        throw new ArgumentNullException("doc");
    }

    FormattedText output = new FormattedText(
        GetText(doc),
        CultureInfo.CurrentCulture,
        doc.FlowDirection,
        new Typeface(doc.FontFamily, doc.FontStyle, doc.FontWeight, doc.FontStretch),
        doc.FontSize,
        doc.Foreground);

    int offset = 0;

    foreach (TextElement el in GetRunsAndParagraphs(doc))
    {
        Run run = el as Run;

        if (run != null)
        {
            int count = run.Text.Length;

            output.SetFontFamily(run.FontFamily, offset, count);
            output.SetFontStyle(run.FontStyle, offset, count);
            output.SetFontWeight(run.FontWeight, offset, count);
            output.SetFontSize(run.FontSize, offset, count);
            output.SetForegroundBrush(run.Foreground, offset, count);
            output.SetFontStretch(run.FontStretch, offset, count);
            output.SetTextDecorations(run.TextDecorations, offset, count);

            offset += count;
        }
        else
        {
            offset += Environment.NewLine.Length;
        }
    }

    return output;
}

private string GetText(FlowDocument doc)
{
    StringBuilder sb = new StringBuilder();

    foreach (TextElement el in GetRunsAndParagraphs(doc))
    {
        Run run = el as Run;
        sb.Append(run == null ? Environment.NewLine : run.Text);
    }
    return sb.ToString();
}
&lt;/pre&gt;

You can download the source code and demo &lt;a href="http://sites.google.com/a/wpfmentor.com/resources/richtext"&gt;here&lt;/a&gt;.


&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-6411616620624136236?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/6411616620624136236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=6411616620624136236' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/6411616620624136236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/6411616620624136236'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-transfer-rich-text-from.html' title='How to transfer rich text from a FlowDocument to a FormattedText object'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-197608306166406579</id><published>2009-01-15T13:00:00.000Z</published><updated>2009-01-15T13:01:01.487Z</updated><title type='text'>How to ensure a new instance of a resource is returned every time it is requested</title><content type='html'>There's a little known attribute named &lt;b&gt;x:Shared&lt;/b&gt; for this purpose. It's little known since it doesn't appear in Intellisense for some reason. Add the attribute it to any item in a resource dictionary and set its value to &lt;b&gt;False&lt;/b&gt; to ensure each request returns a new instance. 
&lt;br/&gt;&lt;br/&gt;
The value of the attribute is &lt;b&gt;True&lt;/b&gt; by default. This means that any given resource request always returns the same instance by default.
&lt;br/&gt;&lt;br/&gt;
This code snippet demonstrates its usage:

&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window.Resources&amp;gt;
    &amp;lt;ContextMenu x:Shared="False" x:Key="menu"&amp;gt;
        &amp;lt;ContextMenu.Items&amp;gt;
            &amp;lt;MenuItem Header="A Menu Item"/&amp;gt;
        &amp;lt;/ContextMenu.Items&amp;gt;
    &amp;lt;/ContextMenu&amp;gt;
&amp;lt;/Window.Resources&amp;gt;

&amp;lt;StackPanel&amp;gt;
    &amp;lt;Button Content="Button1" ContextMenu="{StaticResource menu}" Click="Btn_Click"/&amp;gt;
    &amp;lt;Button Content="Button2" ContextMenu="{StaticResource menu}" Click="Btn_Click"/&amp;gt;
&amp;lt;/StackPanel&amp;gt;
&lt;/pre&gt;

&lt;pre name="code" class="c#"&gt;
private void Btn_Click(object sender, RoutedEventArgs e)
{
    Button b = (Button)sender;
    MenuItem item = (MenuItem)b.ContextMenu.Items[0];
    item.IsChecked = !item.IsChecked;
}

&lt;/pre&gt;

Visit the &lt;a href="http://msdn.microsoft.com/en-us/library/aa970778.aspx"&gt;MSDN page&lt;/a&gt; for more info about this attribute.


&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-197608306166406579?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/197608306166406579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=197608306166406579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/197608306166406579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/197608306166406579'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-ensure-new-instance-of-resource.html' title='How to ensure a new instance of a resource is returned every time it is requested'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-1883272615576082434</id><published>2009-01-13T15:19:00.002Z</published><updated>2009-01-13T15:20:17.772Z</updated><title type='text'>How to intercept a copy or paste operation</title><content type='html'>I've just found these static methods on the &lt;b&gt;System.Windows.DataObject&lt;/b&gt; class.

&lt;pre name="code" class="c#"&gt;
DataObject.AddPastingHandler(dependencyObject, handler);
DataObject.RemovePastingHandler(dependencyObject, handler);

DataObject.AddCopyingHandler(dependencyObject, handler);
DataObject.RemovePastingHandler(dependencyObject, handler);

DataObject.AddSettingDataHandler(dependencyObject, handler);
DataObject.RemoveSettingDataHandler(dependencyObject, handler);
&lt;/pre&gt;

Very useful!!
&lt;br/&gt;&lt;br/&gt;
You can use these to inspect an object before it is pasted/copied/drag-dropped and change the course of the action by doing stuff like Cancel or Change Format.



  &lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-1883272615576082434?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/1883272615576082434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=1883272615576082434' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/1883272615576082434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/1883272615576082434'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-intercept-copy-or-paste.html' title='How to intercept a copy or paste operation'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-3953208258220670228</id><published>2009-01-12T19:44:00.009Z</published><updated>2009-01-13T15:17:42.277Z</updated><title type='text'>How to assign a URL to one or more CLR namespaces</title><content type='html'>Look at the way the XML namespaces are defined in the snippet below. The &lt;i&gt;'local'&lt;/i&gt; definition is mapped directly to a CLR namespace in the normal way but the first two definitions are just URLs. What do thes URLs represent and where are they defined? 

&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window x:Class="WpfLibrary.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfLibrary"&amp;gt;
    
    &amp;lt;Window.Resources&amp;gt;
        &amp;lt;SolidColorBrush Color="AliceBlue"/&amp;gt;
    &amp;lt;/Window.Resources&amp;gt;
    
    &amp;lt;TextBox/&amp;gt;
    
    &lt;!-- TextBox and SolidColorBrush are in different CLR namespaces but are --&gt;
    &lt;!-- referenced using the same (default) XML namespace --&gt;
&amp;lt;/Window&amp;gt;

&lt;/pre&gt;

The URLs have been setup to represent multiple CLR namespaces in the &lt;b&gt;AssemblyInfo&lt;/b&gt; of the assembly in which they are defined. Notice that both the TextBox and SolidColorBrush classes are referenced using the default XML namespace even though the classes are actually defined in different CLR namespaces.
&lt;br/&gt;&lt;br/&gt;
To find out which CLR namespaces are assigned to a particular URL then you can look at the assembly
definition in &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt;.
&lt;br/&gt;&lt;br/&gt;

Here's the syntax to set this up in the AssemblyInfo of your assembly:

&lt;pre name="code" class="c#"&gt;
[assembly:XmlnsDefinition("http://myorganization.com", "WpfLibrary")]
[assembly:XmlnsDefinition("http://myorganization.com", "WpfLibrary.Pens")]
[assembly:XmlnsDefinition("http://myorganization.com", "WpfLibrary.Brushes")]
&lt;/pre&gt;

Consumers of your assembly can then use the XML namespace to reference all of the associated CLR namespaces in one swoop:

&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window x:Class="WpfApplication1.Window1"
 xmlns:myorg="http://myorganization.com"
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;




  &lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-3953208258220670228?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/3953208258220670228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=3953208258220670228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/3953208258220670228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/3953208258220670228'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/01/how-to-assign-url-to-one-or-more-clr.html' title='How to assign a URL to one or more CLR namespaces'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-5925214973999055378</id><published>2009-01-10T15:54:00.000Z</published><updated>2009-03-09T22:18:22.679Z</updated><title type='text'>How to make the text of a CheckBox wrap across multiple lines</title><content type='html'>Just a quick one about how to make CheckBox text wrap across multiple lines while showing text accelerators correctly.
&lt;br/&gt;&lt;br/&gt;
You might have noticed that a CheckBox doesn't have properties like &lt;b&gt;TextWrapping&lt;/b&gt; and &lt;b&gt;TextTrimming&lt;/b&gt;. This is because CheckBox derives from &lt;b&gt;ContentControl&lt;/b&gt; and can therefore take any element as its content - it doesn't have to be a string like in the bad old WinForms days.
&lt;br/&gt;&lt;br/&gt;
In order to add text wrapping, you could add a &lt;b&gt;TextBlock&lt;/b&gt; to the Content of the CheckBox like this:
&lt;pre name="code" class="xaml"&gt;
&amp;lt;CheckBox&amp;gt;
    &amp;lt;TextBlock TextWrapping="Wrap"
        Text="_This is a long piece of text attached to a checkbox."/&amp;gt;
&amp;lt;/CheckBox&amp;gt;
&lt;/pre&gt;

There is a problem regarding accelerator keys here though. Look at the output from the last example:
&lt;br/&gt;&lt;br/&gt;
&lt;img src="http://sites.google.com/a/wpfmentor.com/resources/Home/accelerator.PNG"/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;
...the accelerator isn't display correctly. TextBlocks don't support accelerator keys. In order to do this properly you should use an &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.accesstext.aspx"&gt;AccessText&lt;/a&gt; element to display your text:
&lt;pre name="code" class="xaml"&gt;
&amp;lt;CheckBox&amp;gt;
    &amp;lt;AccessText TextWrapping="Wrap"
        Text="_This is a long piece of text attached to a checkbox."/&amp;gt;
&amp;lt;/CheckBox&amp;gt;
&lt;/pre&gt;
This will ensure that the underscore is correctly displayed.
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-5925214973999055378?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/5925214973999055378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=5925214973999055378' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/5925214973999055378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/5925214973999055378'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2009/02/how-to-make-text-of-checkbox-wrap.html' title='How to make the text of a CheckBox wrap across multiple lines'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-4584359811668505619</id><published>2008-12-12T15:05:00.008Z</published><updated>2009-01-29T15:56:50.363Z</updated><title type='text'>How to sort a BindingList using CollectionViewSource</title><content type='html'>If you've ever tried to sort a BindingList (or any other collection implementing IBindingList) using CollectionViewSource 
then you've most probably not had much luck. The BindingListCollectionView used for this task
lacks the functionality of ListCollectionView and on top of that has a bug making it even more onerous to use.
This post describes a workaround so you can use ListCollectionView instead.
&lt;br/&gt;&lt;br/&gt;
BindingListCollectionView unfortunately doesn't have the sorting capabilities of ListCollectionView. It only
uses the in-built sorting defined in IBindingList instead of doing it itself and if
that's not enabled it will throw an exception. Not very useful.
&lt;br/&gt;&lt;br/&gt;
On top of that, if your BindingList doesn't implement ITypedList then the sorting fails silently even if you
have implemented the sorting!
&lt;br/&gt;&lt;br/&gt;


Here's a nice trick to adapt a BindingList to an ObservableCollection and therefore make the CollectionViewSource use the ListCollectionView implementation for sorting:
&lt;br/&gt;&lt;br/&gt;


&lt;pre name="code" class="c#"&gt;
class ExtendedCollectionViewSource : CollectionViewSource
{
    private BindingListAdapter mAdapter;

    static ExtendedCollectionViewSource()
    {
        CollectionViewSource.SourceProperty.OverrideMetadata(
            typeof(ExtendedCollectionViewSource),
            new FrameworkPropertyMetadata(null, CoerceSource));
    }

    private static object CoerceSource(DependencyObject d, object baseValue)
    {
        ExtendedCollectionViewSource cvs = (ExtendedCollectionViewSource)d;
        if (cvs.mAdapter != null)
        {
            cvs.mAdapter.Dispose();
            cvs.mAdapter = null;
        }
        IBindingList bindingList = baseValue as IBindingList;
        if (bindingList != null)
        {
            cvs.mAdapter = new BindingListAdapter(bindingList);
            return cvs.mAdapter;
        }
        return baseValue;
    }
}

&lt;/pre&gt;

&lt;pre name="code" class="c#"&gt;
private class BindingListAdapter : ObservableCollection&amp;lt;object&amp;gt;, IDisposable
{
    private readonly IBindingList mBindingList;
    private bool mIsDisposed;

    public BindingListAdapter(IBindingList bindingList)
    {
        if (bindingList == null)
        {
            throw new ArgumentNullException("bindingList");
        }

        mBindingList = bindingList;

        foreach (object item in mBindingList)
        {
            Items.Add(item);
        }

        mBindingList.ListChanged += BindingList_ListChanged;
    }

    private void BindingList_ListChanged(object sender, ListChangedEventArgs e)
    {
        if (e.ListChangedType == ListChangedType.ItemAdded)
        {
            InsertItem(e.NewIndex, mBindingList[e.NewIndex]);
        }
        else if (e.ListChangedType == ListChangedType.ItemChanged)
        {
            SetItem(e.NewIndex, mBindingList[e.NewIndex]);
        }
        else if (e.ListChangedType == ListChangedType.ItemDeleted)
        {
            RemoveItem(e.NewIndex);
        }
        else if (e.ListChangedType == ListChangedType.ItemMoved)
        {
            MoveItem(e.OldIndex, e.NewIndex);
        }
        else if (e.ListChangedType == ListChangedType.Reset)
        {
            Items.Clear();

            foreach (object item in mBindingList)
            {
                Items.Add(item);
            }
            
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Reset));
        }
    }

    #region IDisposable Members

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!mIsDisposed)
        {
            if (disposing)
            {
                mBindingList.ListChanged -= BindingList_ListChanged;
            }
        }
        mIsDisposed = true;
    }

    #endregion
}

&lt;/pre&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/extendedcollectionviewsource"&gt;ExtendedCollectionViewSource.cs&lt;/a&gt;

  &lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-4584359811668505619?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/4584359811668505619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=4584359811668505619' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4584359811668505619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4584359811668505619'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2008/12/how-to-sort-bindinglist-using.html' title='How to sort a BindingList using CollectionViewSource'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-4971200981973829221</id><published>2008-12-11T16:23:00.010Z</published><updated>2009-01-29T15:47:18.385Z</updated><title type='text'>How to set the size and position of a scroll bar thumb</title><content type='html'>The WPF scrollbars seem to be unduly difficult to use. This post describes why and defines some extension methods to make 
life a little easier.
&lt;br/&gt;&lt;br/&gt;

The ScrollBar class has these properties to specify the thumb location and the thumb size:

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Value&lt;/b&gt; - represents the thumb position &lt;/li&gt;
&lt;li&gt;&lt;b&gt;ViewportSize&lt;/b&gt; - represents the thumb location&lt;/li&gt;
&lt;/ul&gt;

Value varies between &lt;b&gt;Maximum&lt;/b&gt; and &lt;b&gt;Minimum&lt;/b&gt;. So if Maximum=100, Minimum=0 and Value=50. Then the thumb is in the middle,
this is definitely the more sensible of the two properties. However, it's not great: it doesn't directly represent the absolute position of the
thumb on the track.

&lt;br/&gt;&lt;br/&gt;
ViewportSize varies between &lt;b&gt;0&lt;/b&gt; and &lt;b&gt;double.MaxValue&lt;/b&gt;. What!? What use is this to anyone?
&lt;br/&gt;&lt;br/&gt;
What you nearly always have when you are implementing your own scrolling is the length of the thumb and the 
absolute position of the thumb. Here are some extension methods that convert these to and from the WPF properties.


&lt;pre name="code" class="c#"&gt;
public static class ScrollBarExtensions
{
    public static double GetThumbCenter(this ScrollBar s)
    {
        double thumbLength = GetThumbLength(s);
        double trackLength = s.Maximum - s.Minimum;        

        return thumbLength / 2 + s.Minimum + (s.Value - s.Minimum) * 
            (trackLength - thumbLength) / trackLength;
    }

    public static void SetThumbCenter(this ScrollBar s, double thumbCenter)
    {
        double thumbLength = GetThumbLength(s);
        double trackLength = s.Maximum - s.Minimum;

        if (thumbCenter &gt;= s.Maximum - thumbLength / 2)
        {
            s.Value = s.Maximum;
        }
        else if (thumbCenter &lt;= s.Minimum + thumbLength / 2)
        {
            s.Value = s.Minimum;
        }
        else if (thumbLength &gt;= trackLength )
        {
            s.Value = s.Minimum;
        }
        else
        {
            s.Value = s.Minimum + trackLength  * 
                ((thumbCenter - s.Minimum - thumbLength / 2) 
                / (trackLength - thumbLength));
        }
    }

    public static double GetThumbLength(this ScrollBar s)
    {
        double trackLength = s.Maximum - s.Minimum;
        return trackLength * s.ViewportSize / 
            (trackLength + s.ViewportSize);
    }

    public static void SetThumbLength(this ScrollBar s, double thumbLength)
    {
        double trackLength = s.Maximum - s.Minimum;

        if (thumbLength &lt; 0)
        {
            s.ViewportSize = 0;
        }
        else if (thumbLength &lt; trackLength )
        {
            s.ViewportSize = trackLength * thumbLength / (trackLength - thumbLength);
        }
        else
        {
            s.ViewportSize = double.MaxValue;
        }
    }
}
&lt;/pre&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/scrollbarextensions"&gt;ScrollBarExtensions.cs&lt;/a&gt;

  &lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-4971200981973829221?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/4971200981973829221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=4971200981973829221' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4971200981973829221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4971200981973829221'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2008/12/how-to-set-thumb-position-and-length-of.html' title='How to set the size and position of a scroll bar thumb'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-2089698076307175106</id><published>2008-12-11T10:28:00.011Z</published><updated>2009-01-29T15:43:11.216Z</updated><title type='text'>Observable collections independent of WPF</title><content type='html'>I've recently been working with a client who has made the decision to keep 
the business logic assembly of their WPF application independent of WPF. This is fair enough, keeping the business logic separate
from the presentation code and independent of WPF will promote decoupled design and reduce the pain down the line if
the business logic needs to be transplanted elsewhere.
&lt;br/&gt;&lt;br/&gt;
The client had the further requirement that the collections within the businsess logic should be 
observable by WPF in order to avoid the overhead of creating an entire View-Model layer to support the UI. Even though I'm 
unsure as to whether there's anyone else out there being so strict about their
dependencies, implementing this
turns out to be less straightforward than you'd expect, so I thought I'd write a post about it anyway.

&lt;br/&gt;&lt;br/&gt;


First of all, here's a quick reminder of the interfaces that WPF data binding generally uses to observe the contents of a collection:
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;IList&lt;/b&gt; -  used to traverse the items in a collection.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;INotifyPropertyChanged&lt;/b&gt; -  used to inform listeners that the value of a property of a collection has changed i.e. the count
and the indexer properties.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;INotifyCollectionChanged&lt;/b&gt; -  used to inform listeners that a collection has changed in some way
e.g. an item has been added, removed, moved etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;

The problem here is that INotifyCollectionChanged is part of WPF as it is defined in WindowsBase and therefore can't be
used in the proposed structure. An alternative to using INotifyCollectionChanged is to use the somewhat older interface, 
&lt;b&gt;System.ComponentModel.IBindingList&lt;/b&gt;, which has been around since .NET 1.0 supporting 
data binding in Windows Forms. IBindingList is also supported by WPF data binding and this post
focuses on it as an alternative to INotifyCollectionChanged thus removing the dependency on WPF.


&lt;br/&gt;&lt;br/&gt;
As well as change notification, IBindingList contains functionality for Adding, Removing, Sorting and Searching (it's a bit of
a bizarre interface really, containing all this different functionality). 


In this
implementation, sorting will be
disabled since it was desired that it is handled in the view as it is for collections implementating INotifyCollectionChanged. Adding,
removing and searching can all be implemented as you see fit but in this example I will be disabling them.
&lt;br/&gt;&lt;br/&gt;

Implementing IBindingList is straightforward enough. If you were to implement it on your collection, 
it should end up looking something like this:

&lt;pre name="code" class="c#"&gt;
class MyObservableCollection&amp;lt;T&amp;gt; : Collection&amp;lt;T&amp;gt;, IBindingList
{
    protected override void ClearItems()
    {
        base.ClearItems();
        OnListChanged(new ListChangedEventArgs(ListChangedType.Reset), -1);
    }

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index));
    }

    protected override void RemoveItem(int index)
    {
        base.RemoveItem(index);
        OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index));
    }

    protected override void SetItem(int index, T item)
    {
        base.SetItem(index, item);
        OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index));
    }

    protected virtual void OnListChanged(ListChangedEventArgs e)
    {
        var handler = ListChanged;
        if (handler != null) handler(this, e);
    }

    // IBindingList Members 
    public void AddIndex(PropertyDescriptor property) {}
    public object AddNew() {}
    public void ApplySort(PropertyDescriptor property, ListSortDirection direction) {}
    public int Find(PropertyDescriptor property, object key) {}
    public void RemoveIndex(PropertyDescriptor property) {}
    public void RemoveSort() {}
    public event ListChangedEventHandler ListChanged;
    public bool SupportsChangeNotification { get { return true; } } // Must return true
    public bool AllowEdit { get { return false; } }
    public bool AllowNew { get { return false; } }
    public bool AllowRemove { get { return false; } }
    public bool IsSorted { get { return false; } }
    public ListSortDirection SortDirection
    { get { throw new NotSupportedException(); } }
    public PropertyDescriptor SortProperty
    { get { throw new NotSupportedException(); } }
    public bool SupportsChangeNotification { get { return true; } }
    public bool SupportsSearching { get { return false; } }
    public bool SupportsSorting { get { return false; } }
}&lt;/pre&gt;

So far, so good. We now have a collection that implements IBindingList and can therefore be used for data binding. So let's try it by binding
a ListBox to the new collection:
&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window ...&amp;gt;
    &amp;lt;StackPanel&amp;gt;
        &amp;lt;Button Content="Add" Click="ButtonAdd_Click"/&amp;gt;
        &amp;lt;ListBox ItemsSource="{Binding}"/&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;

&lt;pre name="code" class="csharp"&gt;
public partial class Window1 : Window
{
    private readonly MyObservableCollection&amp;lt;int&amp;gt; mCollection;
    private int mCounter;

    public Window1()
    {
        InitializeComponent();
        mCollection = new MyObservableCollection&amp;lt;int&amp;gt;();
        DataContext = mCollection;
    }

    private void ButtonAdd_Click(object sender, RoutedEventArgs e)
    {
        mCollection.Add(mCounter++);
    }
}
&lt;/pre&gt;

It works! You can click on the Add button and the listbox correctly updates. Now let's try sorting a view of the collection 
using a &lt;b&gt;CollectionViewSource&lt;/b&gt;:
&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window ...&amp;gt;
    &amp;lt;Window.Resources&amp;gt;
        &amp;lt;CollectionViewSource x:Key="cvs" Source="{Binding}"&amp;gt;
            &amp;lt;CollectionViewSource.SortDescriptions&amp;gt;
                &amp;lt;compModel:SortDescription Direction="Descending"/&amp;gt;
            &amp;lt;/CollectionViewSource.SortDescriptions&amp;gt;
        &amp;lt;/CollectionViewSource&amp;gt;
    &amp;lt;/Window.Resources&amp;gt;
    &amp;lt;StackPanel&amp;gt;
        &amp;lt;Button Content="Add" Click="ButtonAdd_Click"/&amp;gt;
        &amp;lt;ListBox ItemsSource="{Binding Source={StaticResource cvs}}"/&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;
Hmmm...this isn't nearly so successful. The window now throws an exception on startup:
&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;InvalidOperationException:&lt;/b&gt;&lt;i&gt; 'System.Windows.Data.BindingListCollectionView' view does not support sorting.&lt;/i&gt;
&lt;br/&gt;&lt;br/&gt; 
This is because the &lt;b&gt;BindingListCollectionView&lt;/b&gt;, the implementation of &lt;b&gt;ICollectionView&lt;/b&gt; created 
by the CollectionViewSource for viewing collections implementing IBindingList is using the internal sorting mechanism provided 
by the IBindingList interface. Since SupportsSorting is set to false, an exception now gets thrown when an attempt is made to 
sort the collection. SupportsSorting can't be set to true as then sorting would have to actually be implemented by the collection 
and the requirement is for it to be handled in the view as it is for collections implementing INotifyCollectionChanged.

&lt;br/&gt;&lt;br/&gt; 
This poses a bit of a problem. Luckily, we have a dirty workaround to rememdy the situation.
&lt;br/&gt;&lt;br/&gt; 
CollectionViewSource can be subclassed and its Source property coerced into using an adapted version of original collection 
which implements INotifyCollectionChanged. This adapter maps the change events from the IBindingList interface
to the equivalents on the INotifyCollectionChanged interface.
&lt;br/&gt;&lt;br/&gt; 
But...there's another problem. There isn't enough information from IBindingList's &lt;b&gt;ListChangedEventArgs&lt;/b&gt; to fully populate
INotifyCollectionChanged's &lt;b&gt;NotifyCollectionChangedEventArgs&lt;/b&gt;. So we'll also need to subclass the 
ListChangedEventArgs class before raising the change events from the collection.
&lt;br/&gt;&lt;br/&gt; 

Here's a rundown of all the bits that are required. Firstly, here's the new CollectionViewSource which coerces an instance of the 
new &lt;b&gt;BindingListAdapter&lt;/b&gt; class
when its Source property gets set:

&lt;pre name="code" class="csharp"&gt;
class ExtendedCollectionViewSource : CollectionViewSource
{
    private BindingListAdapter mAdapter;

    static ExtendedCollectionViewSource()
    {
        CollectionViewSource.SourceProperty.OverrideMetadata(
            typeof(ExtendedCollectionViewSource),
            new FrameworkPropertyMetadata(null, CoerceSource));
    }

    // This class should be kept internal as the Coerce is a little dodgy. 
    // Consumers of this class could reasonably expect the Source property
    // to return the same instance that was set to it.
    
    private static object CoerceSource(DependencyObject d, object baseValue)
    {
        ExtendedCollectionViewSource cvs = (ExtendedCollectionViewSource)d;
        if (cvs.mAdapter != null)
        {
            cvs.mAdapter.Dispose();
            cvs.mAdapter = null;
        }
        IBindingList bindingList = baseValue as IBindingList;
        if (bindingList != null)
        {
            cvs.mAdapter = new BindingListAdapter(bindingList);
            return cvs.mAdapter;
        }
        return baseValue;
    }
}
&lt;/pre&gt;

Next, the BindingListAdapter class, which adapts a class implementing IBindingList into one
which implements INotifyCollectionChanged.

&lt;pre name="code" class="csharp"&gt;
class BindingListAdapter : IList, IDisposable, INotifyPropertyChanged, 
    INotifyCollectionChanged
{
    private readonly IBindingList mBindingList;

    public BindingListAdapter(IBindingList bindingList)
    {
        mBindingList = bindingList;
        mBindingList.ListChanged += mBindingList_ListChanged;
    }

    private void mBindingList_ListChanged(object sender, ListChangedEventArgs e)
    {
        ExtendedListChangedEventArgs ee = (ExtendedListChangedEventArgs)e;
        
        if (e.ListChangedType == ListChangedType.ItemAdded)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Add, mBindingList[e.NewIndex],
                e.NewIndex));
        }
        else if (e.ListChangedType == ListChangedType.ItemChanged)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Replace, mBindingList[e.NewIndex],
                ee.Item));
        }
        else if (e.ListChangedType == ListChangedType.ItemDeleted)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Remove, ee.Item, e.NewIndex));
        }
        else if (e.ListChangedType == ListChangedType.ItemMoved)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Move, ee.Item, e.NewIndex, e.OldIndex));
        }
        else if (e.ListChangedType == ListChangedType.Reset)
        {
            OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Reset, null, -1));
        }
    }
    
    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, e);
    }
    
    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        var handler = CollectionChanged;
        if (handler != null) handler(this, e);
    }

    // I've excluded the implementation of these interfaces here. 
    // Source code is available at the foot of the post.
    
    // IList Members
    // ICollection Members
    // IEnumerable Members
    // INotifyPropertyChanged Members
    // INotifyCollectionChanged Members
    // IDisposable
}
&lt;/pre&gt;

...and the ExtendedListChangedEventArgs class which contains extra information required to populate the
INotifyCollectionChangedEventArgs.

&lt;pre name="code" class="csharp"&gt;
class ExtendedListChangedEventArgs : ListChangedEventArgs
{
    public object Item { get; private set; }

    public ExtendedListChangedEventArgs(ListChangedType listChangedType, object item, 
        int newIndex) : base(listChangedType, newIndex)
    {
        Item = item;
    }

    public ExtendedListChangedEventArgs(ListChangedType listChangedType, object item, 
        int newIndex, int oldIndex) : base(listChangedType, newIndex, oldIndex)
    {
        Item = item;
    }
}
&lt;/pre&gt;

...and finally, the original collection, updated to use ExtendedListChangedEventArgs:

&lt;pre name="code" class="csharp"&gt;
class MyObservableCollection&amp;lt;T&amp;gt; : Collection&amp;lt;T&amp;gt;, IBindingList
{
    protected override void ClearItems()
    {
        base.ClearItems();
        OnListChanged(
            new ExtendedListChangedEventArgs(ListChangedType.Reset, null, -1));
    }

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        OnListChanged(
            new ExtendedListChangedEventArgs(ListChangedType.ItemAdded, item, index));
    }

    protected override void RemoveItem(int index)
    {
        T item = base[index];
        base.RemoveItem(index);
        OnListChanged(new ExtendedListChangedEventArgs(
            ListChangedType.ItemDeleted, item, index));
    }

    protected override void SetItem(int index, T item)
    {
        T oldItem = base[index];
        base.SetItem(index, item);
        OnListChanged(new ExtendedListChangedEventArgs(
            ListChangedType.ItemChanged, oldItem, index));
    }

    protected virtual void OnListChanged(ListChangedEventArgs e)
    {
        var handler = ListChanged;
        if (handler != null) handler(this, e);
    }

    // IBindingList Members (not shown here)
}
&lt;/pre&gt;

...and that (believe it or not) actually works. The ExtendedCollectionViewSource successfully coerces the collection into 
an adapted version of the original before passing it on to CollectionViewSource. The sorting is now entirely handled
in the view as it is for collections implementing INotifyCollectionChanged.
&lt;br/&gt;&lt;br/&gt;
As far as I know this approach has no disadvantages to using INotifyCollectionChanged (except that you have to write all
of this rhubarb to make it work of course.)

&lt;br/&gt;&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/observable"&gt;Download Full Source Code&lt;/a&gt;

  &lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-2089698076307175106?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/2089698076307175106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=2089698076307175106' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/2089698076307175106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/2089698076307175106'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2008/12/observable-collections-independent-of.html' title='Observable collections independent of WPF'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-7354762378016499530</id><published>2008-12-01T17:05:00.014Z</published><updated>2009-01-29T15:37:03.077Z</updated><title type='text'>Setting the Context Menu on an editable ComboBox</title><content type='html'>There's a bug in the .NET 3.5 SP1 ComboBox template which stops you setting the context menu
on the TextBox part of an editable ComboBox using a &lt;b&gt;Style&lt;/b&gt;. This post describes the problem and 
outlines two workarounds.

&lt;br/&gt;&lt;br/&gt;

This code snippet recreates the issue:

&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window.Resources&amp;gt;
    &amp;lt;ContextMenu x:Key="contextMenu"&amp;gt;
        &amp;lt;ContextMenu.Items&amp;gt;
            &amp;lt;MenuItem Header="A Menu Item"/&amp;gt;
        &amp;lt;/ContextMenu.Items&amp;gt;
    &amp;lt;/ContextMenu&amp;gt;

    &amp;lt;Style TargetType="{x:Type TextBox}"&amp;gt;
        &amp;lt;Setter Property="ContextMenu" Value="{StaticResource contextMenu}"/&amp;gt;
    &amp;lt;/Style&amp;gt;

    &amp;lt;Style TargetType="{x:Type ComboBox}"&amp;gt;
        &amp;lt;Setter Property="ContextMenu" Value="{StaticResource contextMenu}"/&amp;gt;
    &amp;lt;/Style&amp;gt;
&amp;lt;/Window.Resources&amp;gt;

&amp;lt;ComboBox IsEditable="True"/&amp;gt;

&lt;/pre&gt;

The context menu on the button part of the ComboBox gets set correctly, but the
TextBox part is left with its default context menu:
&lt;br/&gt;&lt;br/&gt;

&lt;img src="http://sites.google.com/a/wpfmentor.com/resources/Home/context_menu.PNG"&gt;
&lt;br/&gt;&lt;br/&gt;

The reason for this is that there is a missing &lt;b&gt;TemplateBinding&lt;/b&gt; between the ComboBox
and the contained TextBox in the default template. The TextBox style in the code snippet also fails
to set the context menu; this is because the ComboBox itself internally sets a style to the TextBox,
and it not permissable to have two different styles set to any one instance of a FrameworkElement.
&lt;br/&gt;&lt;br/&gt;
The first workaround to the problem is to subclass the ComboBox and add the required template binding:

&lt;pre name="code" class="csharp"&gt;
class ExtendedComboBox : ComboBox
{
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        
        // Use Snoop to find the name of the TextBox part
        // http://wpfmentor.blogspot.com/2008/11/understand-bubbling-and-tunnelling-in-5.html
        TextBox textBox = (TextBox)Template.FindName("PART_EditableTextBox", this);
        
        // Create a template-binding in code
        Binding binding = new Binding("ContextMenu");
        binding.RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent);
        BindingOperations.SetBinding(textBox, 
            FrameworkElement.ContextMenuProperty, binding);
        
    }
}
&lt;/pre&gt;
This approach does the job. The TextBox's ContextMenu property is now bound to the
parent ComboBox and displays correctly.
&lt;br/&gt;&lt;br/&gt;
The obvious problem with this approach is that all the ComboBoxes that require
the new context menu now need to be replaced with this new class. This might well not be
acceptable, perhaps the ComboBox has been subclassed already - you would need to
create new versions for those too. 
&lt;br/&gt;&lt;br/&gt;
This second workaround avoids subclassing by using an &lt;b&gt;Attached Behavior&lt;/b&gt;. If
you are unfamiliar with the Attached Behavior pattern, go 
&lt;a href="http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx"&gt;here&lt;/a&gt; for a 
great article by Josh Smith.

&lt;br/&gt;&lt;br/&gt;

The Attached Behavior uses an &lt;b&gt;Attached Property&lt;/b&gt; which can be set by a Style
to create the Template Binding.&lt;br/&gt;

In order to create this, first write a new static class with an attached property thus:

&lt;pre name="code" class="csharp"&gt;
public static class ComboBoxContextMenuBehavior
{
    public static bool GetIsContextMenuBound(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsContextMenuBoundProperty);
    }

    public static void SetIsContextMenuBound(DependencyObject obj, bool value)
    {
        obj.SetValue(IsContextMenuBoundProperty, value);
    }

    public static readonly DependencyProperty IsContextMenuBoundProperty =
        DependencyProperty.RegisterAttached(
        "IsContextMenuBound",
        typeof(bool),
        typeof(ComboBoxContextMenuBehavior),
        new UIPropertyMetadata(false, IsContextMenuBoundChanged));
)]
&lt;/pre&gt;

...and add a method to handle changes in the attached property value:
&lt;pre name="code" class="csharp"&gt;
private static void IsContextMenuBoundChanged(DependencyObject d, 
    DependencyPropertyChangedEventArgs e)
{
    ComboBox comboBox = d as ComboBox;

    bool oldValue = e.OldValue is bool &amp;&amp; (bool)e.OldValue;
    bool newValue = e.NewValue is bool &amp;&amp; (bool)e.NewValue;

    if (comboBox != null &amp;&amp; oldValue != newValue)
    {
        // Use Dispatcher with Loaded priority to ensure template has been
        // applied before applying the TemplateBinding
        comboBox.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, 
            (DispatcherOperationCallback)delegate
        {
            TextBox textBox = (TextBox)comboBox.Template.FindName(
                "PART_EditableTextBox", comboBox);

            if (textBox != null)
            {
                if (!oldValue &amp;&amp; newValue)
                {
                    // Create TemplateBinding
                    Binding binding = new Binding("ContextMenu");
                    
                    binding.RelativeSource = new RelativeSource(
                        RelativeSourceMode.TemplatedParent);
                    
                    BindingOperations.SetBinding(textBox, 
                        FrameworkElement.ContextMenuProperty, 
                        binding);
                }
                else
                {
                    // Clear TemplateBinding
                    BindingOperations.ClearBinding(textBox, 
                        FrameworkElement.ContextMenuProperty);
                }
            }
            
            return null;
        }, null);
    }
}
&lt;/pre&gt;

The Attached Behavior can now be assigned to the ComboBox using a Style: 
  
  
&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window.Resources&amp;gt;
    &amp;lt;ContextMenu x:Key="contextMenu"&amp;gt;
        &amp;lt;ContextMenu.Items&gt;
            &amp;lt;MenuItem Header="A Menu Item"/&amp;gt;
        &amp;lt;/ContextMenu.Items&amp;gt;
    &amp;lt;/ContextMenu&amp;gt;

    &amp;lt;Style TargetType="{x:Type ComboBox}"&amp;gt;
        &amp;lt;Setter Property="ContextMenu" Value="{StaticResource contextMenu}"/&amp;gt;
        &amp;lt;Setter Property="local:ComboBoxContextMenuBehavior.IsContextMenuBound"
            Value="True"/&amp;gt;
    &amp;lt;/Style&amp;gt;
&amp;lt;/Window.Resources&amp;gt;

&amp;lt;ComboBox IsEditable="True"/&amp;gt;

&lt;/pre&gt;
 
...and that's all you need. You have now successfully added a TemplateBinding to
the ComboBox without subclassing it, and without individually referencing
each ComboBox as a Style is used to fix the problem.
  &lt;br/&gt;&lt;br/&gt; 
So, in conclusion, this bug is annoying but can be easily worked around whether it is acceptable
or not to subclass the ComboBox.
&lt;br/&gt;&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/comboboxcontextmenu"&gt;Download sample app with source code&lt;/a&gt;

  
  
  &lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-7354762378016499530?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/7354762378016499530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=7354762378016499530' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/7354762378016499530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/7354762378016499530'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2008/12/setting-context-menu-on-editable.html' title='Setting the Context Menu on an editable ComboBox'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-4582845844779520488</id><published>2008-11-28T11:36:00.015Z</published><updated>2009-01-29T15:49:27.259Z</updated><title type='text'>Setting up  Theme-Specific Resource Dictionaries</title><content type='html'>Configuring theme-specific resource dictionaries is a common stumbling block. Follow
these rules to ensure they are set up correctly:

&lt;br/&gt;&lt;br/&gt;
  &lt;LI&gt;1. In the &lt;b&gt;AssemblyInfo&lt;/b&gt; for your assembly, set the &lt;b&gt;ThemeInfo&lt;/b&gt; attribute. This will
  specify where the theme-specific and generic resource dictionaries for the styleable resources referenced 
  and defined in the assembly can be found.&lt;/li&gt;


&lt;pre name="code" class="csharp"&gt;
[assembly: ThemeInfo(
    ResourceDictionaryLocation.SourceAssembly, 
    // Where theme-specific resource dictionaries are located.
    // (Used if a resource is not found in the page, 
    // or application resource dictionaries.)
 
    ResourceDictionaryLocation.SourceAssembly 
    // Where the generic resource dictionary is located.
    // (Used if a resource is not found in the page, 
    // app, or any theme specific resource dictionaries.)
)]
&lt;/pre&gt;
  
  &lt;li&gt;2. Put your theme-specific resource dictionaries in the &lt;b&gt;Themes&lt;/b&gt; folder of the relevant assembly so
  they will be automatically picked up (do not use LoadComponent). Also add a generic resource dictionary with the name &lt;b&gt;generic.xaml&lt;/b&gt;.&lt;/li&gt;&lt;br/&gt;
  &lt;img src="http://sites.google.com/a/wpfmentor.com/resources/Home/themes.PNG"&gt;&lt;br/&gt;&lt;br/&gt;
  
  &lt;li&gt;3. Any control-specific theme-specific resource dictionaries should also be added to the Themes folder.
  The dictionary should then be merged into a main resource dictionary like this:&lt;/li&gt;
 
&lt;pre name="code" class="xaml"&gt;
&amp;lt;!-- Aero.NormalColor.xaml: --&amp;gt;
&amp;lt;ResourceDictionary.MergedDictionaries&amp;gt;
    &amp;lt;ResourceDictionary
        Source="/MyAssemblyName;component/Themes/MyControl.Aero.NormalColor.xaml"/&amp;gt;
&amp;lt;/ResourceDictionary.MergedDictionaries&amp;gt;
&lt;/pre&gt;
 &lt;li&gt;4. Do the same with any control-specific generic resource dictionaries:&lt;/li&gt;
&lt;pre name="code" class="xaml"&gt;
&amp;lt;!-- generic.xaml: --&amp;gt;
&amp;lt;ResourceDictionary.MergedDictionaries&amp;gt;
    &amp;lt;ResourceDictionary
        Source="/MyAssemblyName;component/Themes/UnthemedControl.generic.xaml"/&amp;gt;
&amp;lt;/ResourceDictionary.MergedDictionaries&amp;gt;
&lt;/pre&gt;  
 
 
 &lt;li&gt;5. Any resources defined in your assembly required to pick up styles from the theme-specific
 or generic resource dictionaries should override the default style key in their static constructor. You should
 also do this if you want to override the default style of the base class of the resource.&lt;/li&gt;
&lt;pre name="code" class="csharp"&gt;
// Register the default style for MyControl.
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), 
    new FrameworkPropertyMetadata(typeof(MyControl)));
&lt;/pre&gt;
  &lt;li&gt;6. If you want to set the style of a control not defined in your assembly, you will
need to explicitly load the resource dictionary:&lt;/li&gt;
&lt;pre name="code" class="csharp"&gt;
ResourceDictionary dict = Application.LoadComponent(
    new Uri("MyAssemblyName;component/Themes/NewDefaultStyle.xaml", UriKind.Relative))
    as ResourceDictionary;

Application.Current.Resources.MergedDictionaries.Add(dict);

&lt;/pre&gt;

  ...and that's it! That should cover everything you need to do
  to get your resources picking up their styles from the correct place.
  &lt;br/&gt;&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/themes"&gt;Download Full Source Code&lt;/a&gt;
  
  
  &lt;br/&gt;&lt;br/&gt; &lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-4582845844779520488?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/4582845844779520488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=4582845844779520488' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4582845844779520488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/4582845844779520488'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2008/11/setting-up-your-applications-resource.html' title='Setting up  Theme-Specific Resource Dictionaries'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-3449372335467531153</id><published>2008-11-27T11:55:00.006Z</published><updated>2008-12-15T23:44:45.722Z</updated><title type='text'>Notification when items are added or removed from an ItemsControl(ListBox, TabControl, TreeView etc.)</title><content type='html'>It's not obvious how to listen to changes to the &lt;b&gt;Items&lt;/b&gt; of an ItemsControl.
This post outlines various problems and identifies a simple way to listen to this collection regardless of how the ItemsControl was populated.
&lt;br/&gt;&lt;br/&gt;

In general, there are two ways to add items to an ItemsControl:
&lt;UL&gt;
  &lt;LI&gt;Manually add to the &lt;b&gt;ItemCollection&lt;/b&gt; of the control. This is accessed using the &lt;b&gt;Items&lt;/b&gt; property of the control.&lt;/li&gt;
  &lt;LI&gt;Assign a notifying source to the &lt;b&gt;ItemsSource&lt;/b&gt; of the control. This will update the Items of the
  control automatically as the collection changes.&lt;/LI&gt;
  &lt;/UL&gt;
  &lt;BR/&gt;
  
  If you are adding items manually to your ItemsControl, then listening to changes isn't such a big
  deal since you can just call a method after you have added an item. If you are using an ItemsSource, however, then
  listening to changes is often required for UI tasks such as bringing a new item into view.
  
  &lt;br/&gt;&lt;br/&gt;
  
  The standard way of listening to a notifying source is by using a &lt;b&gt;CollectionViewSource&lt;/b&gt;. If you
  were to attempt to use it to listen to the items of a ListBox you would do something like this:
     
&lt;pre name="code" class="xaml"&gt;
&amp;lt;Window.Resources&amp;gt;
    &amp;lt;CollectionViewSource x:Key="cvs" x:Name="cvs" Source="{Binding}"/&amp;gt;
&amp;lt;/Window.Resources&amp;gt;
       
&amp;lt;ListBox x:Name="mListBox" ItemsSource="{Binding}"/&amp;gt;
&lt;/pre&gt;

&lt;pre name="code" class="csharp"&gt;
public MyWindow()
{
    InitializeComponent();
    
    CollectionViewSource cvs = (CollectionViewSource)FindResource("cvs");
 cvs.View.CollectionChanged += View_CollectionChanged;
}

private void View_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        // scroll the new item into view
        mListBox.ScrollIntoView(e.NewItems[0]);
    }   
}
  
&lt;/pre&gt;
  
  To me, this is quite an ugly solution since it isn't resistant to a change
  of ItemsSource on the ListBox. At first, it seems this could be fixed by binding 
  the Source of the CollectionViewSource directly to the ListBox:
  
  &lt;pre name="code" class="xaml"&gt;
&amp;lt;Window.Resources&amp;gt;
    &amp;lt;CollectionViewSource x:Key="cvs" x:Name="cvs" 
        Source="{Binding ElementName=mListBox, Path=ItemsSource}"/&amp;gt;
&amp;lt;/Window.Resources&amp;gt;
       
&amp;lt;ListBox x:Name="mListBox" ItemsSource="{Binding}"/&amp;gt;
&lt;/pre&gt;
  &lt;br/&gt;
  But this doesn't help. Since the &lt;b&gt;View&lt;/b&gt; property of the CollectionViewSource
  has no update mechanism (it isn't a dependency property), there's no way
  of knowing when it changes.
  
  &lt;br/&gt;&lt;br/&gt;
  A different approach is required...
  &lt;br/&gt;&lt;br/&gt;
  
    The first thing most developers look for when attacking this problem is an event handler on Items. 
    But, when you look at the members generated by Intellisense you find...&lt;br/&gt;&lt;br/&gt;
  
  &lt;img src="http://sites.google.com/a/wpfmentor.com/resources/Home/intellisense.PNG"&gt;
  
  &lt;br/&gt;&lt;br/&gt;
  ...that there's no &lt;b&gt;CollectionChanged&lt;/b&gt; event handler here, so how do you listen to changes in the collection?&lt;br&gt;&lt;br&gt;
  The problem is that the &lt;b&gt;INotifyCollectionChanged&lt;/b&gt; interface which contains the event handler 
  is &lt;i&gt;explicitly&amp;nbsp;implemented&lt;/i&gt;, which means you have to first cast the ItemCollection before
  the event handler can be used:
  
&lt;br&gt;
  
&lt;pre name="code" class="csharp"&gt;
public MyWindow()
{
    InitializeComponent();
    
    ((INotifyCollectionChanged)mListBox.Items).CollectionChanged +=
        mListBox_CollectionChanged;
}

private void mListBox_CollectionChanged(object sender, 
    NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        // scroll the new item into view
        mListBox.ScrollIntoView(e.NewItems[0]);
    }    
}  
&lt;/pre&gt;
  &lt;br/&gt;
  
  Ta da! This is much better - it's simple and robust.&lt;br/&gt;&lt;br/&gt;
  
  So, in conclusion, this is the best way to listen to changes to the Items of an ItemsControl. There's no messing about with CollectionViewSource and worrying about
  updating when a new ItemsSource is assigned...it works regardless of whether ItemsSource is being used and 
  is resistant to changes in ItemsSource.
&lt;br/&gt;&lt;br/&gt; &lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-3449372335467531153?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/3449372335467531153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=3449372335467531153' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/3449372335467531153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/3449372335467531153'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2008/11/notification-when-items-are-added-or.html' title='Notification when items are added or removed from an ItemsControl&lt;br/&gt;(ListBox, TabControl, TreeView etc.)'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-2368161214553303022</id><published>2008-11-26T12:11:00.011Z</published><updated>2008-12-15T23:45:23.765Z</updated><title type='text'>Understand Bubbling and Tunnelling in 5 minutes</title><content type='html'>Here's a quick and visual way to understand
Routed Events and their bubbling and tunnelling nature.&lt;BR&gt;
&lt;UL&gt;
  &lt;LI&gt;1. Download and run &lt;a href="http://blois.us/Snoop/"&gt;Snoop&lt;/a&gt;. It is a fantastic utility for debugging WPF applications.&lt;/li&gt;
  &lt;LI&gt;2. Run a WPF application, and Snoop it using Snoop's binoculars button. I'm using &lt;b&gt;Expression
  Blend&lt;/b&gt; in this example.&lt;/LI&gt;
  &lt;LI&gt;3. Snoop can display the visual tree of your application at run time. Move your cursor over 
a visual element in your application and hold down the &lt;b&gt;Shift&lt;/b&gt; and &lt;b&gt;Control&lt;/b&gt; keys. The
element will now have a &lt;font color=red&gt;red&lt;/font&gt; border and Snoop will pop up the Visual Tree for your application
with the element selected like this:
  &lt;/UL&gt;
  &lt;BR/&gt;
  

&lt;IMG SRC="http://sites.google.com/a/wpfmentor.com/resources/Home/blend.PNG"/&gt;
  
  &lt;BR&gt;&lt;BR&gt;
&lt;UL&gt;
  &lt;LI&gt;4. Click on the &lt;b&gt;Events&lt;/b&gt; tab at the top of the right hand pane. This
  tab contains a list which records all routed events that hit the selected element.&lt;/li&gt;
  &lt;li&gt;5. Open the combo box at the top of the right hand pane. Here you can check the
  Routed Events that you are interested here.&lt;/li&gt;
  &lt;/ul&gt;
    &lt;BR/&gt;
  &lt;IMG SRC="http://sites.google.com/a/wpfmentor.com/resources/Home/choose_events.PNG" border="0"/&gt;
  
  &lt;br&gt;
  &lt;ul&gt;
  &lt;li&gt;6. In the list, uncheck everything except &lt;b&gt;MouseDown&lt;/b&gt; and &lt;b&gt;PreviewMouseDown&lt;/b&gt;.
  These are the routed events that we will look at.&lt;/li&gt;
  &lt;li&gt;7. Clear the list of recorded routed events by clicking the X button to the right
  of the combo box at the top of the right hand pane.&lt;/li&gt;
  &lt;li&gt;8. Go back to the selected element in your app and click on it. Notice that
  this will have been recorded in Snoop. If an entry is shown in &lt;font color=green&gt;green&lt;/font&gt;, then it
  has been handled.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;BR/&gt;
  &lt;IMG SRC="http://sites.google.com/a/wpfmentor.com/resources/Home/recorded_events_collapsed.PNG" border="0"/&gt;
  &lt;br&gt;
  &lt;ul&gt;
  &lt;li&gt;9. Now expand the PreviewMouseDown entry in the right hand pane and look
  at the list the elements which are shown. It will be something like this:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;IMG SRC="http://sites.google.com/a/wpfmentor.com/resources/Home/tunnelling.PNG" border="0"/&gt;
  
  &lt;ul&gt;
  &lt;li&gt;10. Here's the interesting bit. Click down the list one-by-one starting at the top.
  As you do this, notice that the selection in the Visual Tree in the left hand pane
  starts at the top and moves downwards. This is because PreviewMouseDown is a &lt;b&gt;Tunnelling&lt;/b&gt; 
  routed event, that is, it is first received by the top-most parent element and then 
  goes down the visual tree one by one until it reaches the bottom element. If any of the
  elements handle the event and set e.Handled = true then the event stops being routed there.
    &lt;/li&gt;
    &lt;li&gt;11. Now expand the MouseDown entry and look at the list of elements shown.&lt;/LI&gt;
    &lt;/ul&gt;
     &lt;IMG SRC="http://sites.google.com/a/wpfmentor.com/resources/Home/bubbling.PNG" border="0"/&gt;
     &lt;ul&gt;
     &lt;li&gt;12. Since MouseDown is a &lt;b&gt;Bubbling&lt;/b&gt; routed event,
  it is first received by the bottom element and then 
  bubbles up the visual tree one by one until it reaches the top element. If any of the
  elements handle the event and set e.Handled = true then the event stops being routed there.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;br/&gt;
  So there you have it, Snoop is a great tool for debugging WPF applications and
  an easy way to observe and unserstand what is going with your routed events.
  &lt;br/&gt;&lt;br/&gt;
  For more detailed information about the motivation for the design of routed events,
  visit the &lt;b&gt;MSDN&lt;/b&gt; page for routed events &lt;a href="http://msdn.microsoft.com/en-us/library/ms742806.aspx"&gt;here&lt;/a&gt;.
  &lt;br/&gt;&lt;br/&gt; &lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-2368161214553303022?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/2368161214553303022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=2368161214553303022' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/2368161214553303022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/2368161214553303022'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2008/11/understand-bubbling-and-tunnelling-in-5.html' title='Understand Bubbling and Tunnelling in 5 minutes'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7432762749103693871.post-2278768665444475840</id><published>2008-11-21T10:35:00.077Z</published><updated>2009-01-29T15:57:50.499Z</updated><title type='text'>How to set bindings on CLR Properties using DataResource</title><content type='html'>It can be pretty annoying that bindings are only allowed on dependency properties of elements that are part of an element tree. For example, in all of these scenarios binding isn't allowed:

&lt;ul&gt;
&lt;li&gt;on an InputBinding's CommandParameter (not a dependency property)&lt;/li&gt;
&lt;li&gt;on an object in an element's Resources if that object doesn't derive from Freezable (not part of an element tree)&lt;/li&gt;
&lt;li&gt;on an element set to a FrameworkElement’s Tag property (not part of an element tree)&lt;/li&gt;
&lt;li&gt;on a ValidationRule (not a dependency object)&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;&lt;br/&gt;
This post introduces a new technique allowing you to add bindings to CLR properties and is a perfectly good workaround for all the scenarios above.

it's good because it:

&lt;ul&gt;
&lt;li&gt;helps you use binding in many more scenarios :)&lt;/li&gt;
&lt;li&gt;is very easy to use: just drop &lt;b&gt;one source file&lt;/b&gt; &lt;i&gt;(DataResource.cs)&lt;/i&gt; into your app and use it like this:
&lt;pre name="code" class="xaml"&gt;
&lt;!-- This example binds a CLR property to the ActualWidth property of the Window --&gt;
&amp;lt;Window.Resources&amp;gt;
    &lt;!-- set up the binding using a DataResource object --&gt;
    &amp;lt;my:DataResource x:Key="actualWidth" BindingTarget="{Binding ActualWidth}"/&amp;gt;
&amp;lt;/Window.Resources&amp;gt;

&amp;lt;my:MyControl&amp;gt;
    &amp;lt;my:MyControl.MyClrProperty&amp;gt;
        &amp;lt;my:DataResourceBinding DataResource="{StaticResource actualWidth}"/&amp;gt;
    &amp;lt;/my:MyControl.MyClrProperty&amp;gt;
&amp;lt;/my:MyControl&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

It works by using:
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/mikehillberg/archive/2008/05/21/Model-see_2C00_-model-do.aspx"&gt;Mike Hillberg's&lt;/a&gt; technique of using Freezable to gain access to the DataContext of the host element&lt;/li&gt;
&lt;li&gt;a custom markup extension to retrieve the object that the DataResource is bound to and returns this as the host of the markup extension&lt;/li&gt;
&lt;/ul&gt;

&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/dataresource"&gt;DataResource.cs&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://sites.google.com/a/wpfmentor.com/resources/dataresources"&gt;Download sample app with source code&lt;/a&gt;

&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7432762749103693871-2278768665444475840?l=www.wpfmentor.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.wpfmentor.com/feeds/2278768665444475840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7432762749103693871&amp;postID=2278768665444475840' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/2278768665444475840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7432762749103693871/posts/default/2278768665444475840'/><link rel='alternate' type='text/html' href='http://www.wpfmentor.com/2008/11/adding-bindings-to-clr-properties-in.html' title='How to set bindings on CLR Properties using DataResource'/><author><name>Dan Lamping</name><uri>http://www.blogger.com/profile/16628647600777437764</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry></feed>
