<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The WPFGlue Blog</title>
	<atom:link href="http://wpfglue.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://wpfglue.wordpress.com</link>
	<description>How to stick UI and Model together</description>
	<lastBuildDate>Sat, 16 Jul 2011 09:19:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='wpfglue.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/b670acc5d4b33b6f947eefb5ee219381?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>The WPFGlue Blog</title>
		<link>http://wpfglue.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://wpfglue.wordpress.com/osd.xml" title="The WPFGlue Blog" />
	<atom:link rel='hub' href='http://wpfglue.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Validating Objects with ValidationRules</title>
		<link>http://wpfglue.wordpress.com/2010/12/31/validating-objects-with-validationrules/</link>
		<comments>http://wpfglue.wordpress.com/2010/12/31/validating-objects-with-validationrules/#comments</comments>
		<pubDate>Fri, 31 Dec 2010 16:39:41 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[Validation]]></category>
		<category><![CDATA[TypeValidationRuleSetter]]></category>
		<category><![CDATA[ValdiationRuleSetter]]></category>
		<category><![CDATA[ValidationRule]]></category>

		<guid isPermaLink="false">https://wpfglue.wordpress.com/2010/12/31/validating-objects-with-validationrules/</guid>
		<description><![CDATA[In examples about writing WPF applications with the MVVM pattern, normally one doesn’t find any reference to ValidationRules. The normal way to do things there is to wrap the business object into the ViewModel and to implement IDataErrorInfo on the ViewModel. However, there are several points about this approach which I don’t like: I don’t [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=138&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In examples about writing WPF applications with the MVVM pattern, normally one doesn’t find any reference to ValidationRules. The normal way to do things there is to wrap the business object into the ViewModel and to implement IDataErrorInfo on the ViewModel. However, there are several points about this approach which I don’t like:</p>
<ul>
<li>I don’t like to wrap classes into other classes. The kind of code this produces is exactly the kind of useless boilerplate code I want to get rid of by using a flexible data binding system like WPF’s. If it can’t be helped, this kind of code should be generated, but that is not the topic of this blog. </li>
<li>Validation on the ViewModel or Business level removes validation logic and error messages from the domain of the user interface definition to the domain of business logic. Now I like my business logic to be language independent, and it is absolutely valid for a user interface to implement different (more restrictive) checks on a property value than the business object it accesses. So, even if validation logic is implemented on the business level, I want to be able to choose how to use it and what error messages to display on the UI level, i.e. in XAML. </li>
</ul>
<p>That said, ValidationRules have another significant advantage: they can check values before they are passed to the properties of the bound object. This means that I don’t have to implement rollback capabilities on the business object, but can make sure on the UI level that only valid values are set on the business object. This will be covered in a later post.</p>
<p>With all these advantages, there is a serious drawback to ValidationRules: defining them in XAML is rather unwieldy. Done the traditional way, they tend to bloat the XAML code, and sometimes it is difficult to get at all the reference data they need for their checks.</p>
<p>This is where WPFGlue comes into the picture: here, I want to introduce some ideas which allow to define and apply ValidationRules in a more concise manner, and to do some basic checks even without specifying ValidationRules explicitly.</p>
<h4>The BindingGroup Class</h4>
<p>The BindingGroup class has been introduced in WPF 3.5 SP1. A BindingGroup can be set on every FrameworkElement. If set, it can define ValidationRules which are able to access multiple properties of the DataContext in order to validate them against each other. In order to afford this possibility, the BindingGroup class provides methods which can access all Bindings in the subtree under the element which defines the BindingGroup, as long as these Bindings have the same DataContext as that element.</p>
<p>The idea here is to use this ability of the BindingGroup class in order to set up ValidationRules for all bindings which share a given DataContext.</p>
<p>So, in order to validate objects of a given class, first of all one would use a container like a StackPanel, Grid or GroupBox to combine a group of controls which share an instance of that class as their DataContext. Then, one would create a BindingGroup object and set it to the BindingGroup property of that container. Further, one would define a set of ValidationRules for a given class. Some of them would be at the property level, others would access multiple properties, as would be normal for ValidationRules on a BindingGroup object. Then, one would apply this set of ValidationRules to the container, instead of the separate controls which edit the object’s properties. One could reuse the set of ValidationRules wherever an instance of the DataContext class was used.</p>
<p>Using the BindingGroup’s ability for finding Bindings which have the same DataContext, one would add the ValidationRules&#160; to the appropriate Bindings inside the container.</p>
<h4></h4>
<h4>How to Modify Bindings Which are Defined in XAML</h4>
<p>The documentation says that Bindings can not be modified after they have been used. However, there is an event that comes right between the time when the Bindings have all been created, and when they are used for the first time: Initialized. If the DataContext is not null and a BindingGroup is present on a FrameworkElement, this BindingGroup can access and modify those Bindings during the FrameworkElement’s Initialized event.</p>
<p>So, one would need a couple of things:</p>
<ul>
<li>A way to define sets of ValidationRules. </li>
<li>A <a href="http://wpfglue.wordpress.com/2009/12/11/the-sticky-component-framework/">Sticky Component</a> which handles distributing the ValidationRules to the Bindings. </li>
<li>A <a href="http://wpfglue.wordpress.com/2009/11/05/list-of-useful-design-patterns-for-wpf-glue/">Sticky Property</a> which attaches an instance of a set of ValidationRules to a container. </li>
</ul>
<h4>Defining Sets of ValidationRules</h4>
<p>First of all, I said that I wanted to be able to define error messages in XAML. Using the techniques from the <a href="http://wpfglue.wordpress.com/category/localization/">WPFGlue Localization</a> namespace, I can handle multiple languages quite conveniently in XAML, and there might be other considerations like the intended audience of an application which might induce me to change the text of error messages. So, my first addition to a WPFGlue ValidationRule base class would be a Message property, which allows me to set the error message in XAML. In addition to that, I just added the functionality to format the property value into the error message.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5ff439bb-1f89-4b32-b6df-b8d8fa1f3a40" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"><span style="color:#0000ff;">Namespace</span> Validation<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">MustInherit</span> <span style="color:#0000ff;">Class</span> <span style="color:#2b91af;">ValidationRule</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Inherits</span> System.Windows.Controls.<span style="color:#2b91af;">ValidationRule</span></p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Private</span> _Message <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span> = <span style="color:#0000ff;">String</span>.Empty<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Property</span> Message() <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _Message<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Set</span>(<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;_Message = value<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Set</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span></p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Overrides</span> <span style="color:#0000ff;">Function</span> Validate(<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> cultureInfo <span style="color:#0000ff;">As</span> System.Globalization.<span style="color:#2b91af;">CultureInfo</span>) <span style="color:#0000ff;">As</span> System.Windows.Controls.<span style="color:#2b91af;">ValidationResult</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> result <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">ValidationResult</span> = <span style="color:#2b91af;">ValidationResult</span>.ValidResult<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> <span style="color:#0000ff;">Not</span> ValidateCore(value, cultureInfo) <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> message <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span> = <span style="color:#0000ff;">Me</span>.FormatMessage(value)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;result = <span style="color:#0000ff;">New</span> <span style="color:#2b91af;">ValidationResult</span>(<span style="color:#0000ff;">False</span>, message)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> result<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span></p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Protected</span> <span style="color:#0000ff;">MustOverride</span> <span style="color:#0000ff;">Function</span> ValidateCore(<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> cultureInfo <span style="color:#0000ff;">As</span> System.Globalization.<span style="color:#2b91af;">CultureInfo</span>) <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Boolean</span></p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Protected</span> <span style="color:#0000ff;">Overridable</span> <span style="color:#0000ff;">Function</span> FormatMessage(<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>) <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> <span style="color:#0000ff;">String</span>.Format(<span style="color:#0000ff;">Me</span>.Message, value)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Namespace</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>The set of ValidationRules would be defined as a resource in XAML. In order to be able to do that, I create several classes which allow to define collections of ValidationRules grouped by property name:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0b8ca252-71bb-4ed5-a203-6bb888160be6" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"><span style="color:#0000ff;">Namespace</span> Validation<br /> &#160;&#160;&#160;&#160;&lt;System.Windows.Markup.<span style="color:#2b91af;">ContentProperty</span>(<span style="color:#a31515;">&quot;Setters&quot;</span>)&gt;<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> <span style="color:#2b91af;">ValidationRuleSetter</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Inherits</span> <span style="color:#2b91af;">DependencyObject</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Implements</span> <span style="color:#2b91af;">IStickyComponent</span></p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> _DummyDataContext <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span> = <span style="color:#0000ff;">New</span> <span style="color:#0000ff;">Object</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Protected</span> <span style="color:#0000ff;">Overridable</span> <span style="color:#0000ff;">ReadOnly</span> <span style="color:#0000ff;">Property</span> DummyDataContext <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _DummyDataContext<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span></p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Private</span> _Setters <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">New</span> <span style="color:#2b91af;">PropertyValidationRuleSetterCollection</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">ReadOnly</span> <span style="color:#0000ff;">Property</span> Setters <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">PropertyValidationRuleSetterCollection</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _Setters<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>The collection Setters contains collections of ValidationRules, grouped under different property names.</p>
<p>The ValidationRuleSetter class is a Sticky Component: in addition to defining the set of ValidationRules, it also has the ability to set the ValidationRules on the Bindings which belong to the container’s BindingGroup. The following method will be called during the container’s Initialized event:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:eeaec22f-3b8e-42cf-8339-5867ea0deba0" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"><span style="color:#0000ff;">Protected</span> <span style="color:#0000ff;">Overridable</span> <span style="color:#0000ff;">Sub</span> AttachRules(<span style="color:#0000ff;">ByVal</span> base <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>)</p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> f <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">FrameworkElement</span> = <span style="color:#0000ff;">TryCast</span>(base, <span style="color:#2b91af;">FrameworkElement</span>)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> f <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> bg <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">BindingGroup</span> = f.BindingGroup<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> bg <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">For</span> <span style="color:#0000ff;">Each</span> be <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">BindingExpression</span> <span style="color:#0000ff;">In</span> bg.BindingExpressions.OfType(<span style="color:#0000ff;">Of</span> <span style="color:#2b91af;">BindingExpression</span>)()<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> Setters.Contains(be.ParentBinding.Path.Path) <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">For</span> <span style="color:#0000ff;">Each</span> v <span style="color:#0000ff;">As</span> System.Windows.Controls.<span style="color:#2b91af;">ValidationRule</span> <span style="color:#0000ff;">In</span> Setters.Item(be.ParentBinding.Path.Path).ValidationRules<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;be.ParentBinding.ValidationRules.Add(v)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Next</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> Setters.Contains(<span style="color:#0000ff;">String</span>.Empty) <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">For</span> <span style="color:#0000ff;">Each</span> v <span style="color:#0000ff;">As</span> System.Windows.Controls.<span style="color:#2b91af;">ValidationRule</span> <span style="color:#0000ff;">In</span> Setters.Item(<span style="color:#0000ff;">String</span>.Empty).ValidationRules<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;bg.ValidationRules.Add(v)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Next</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Next</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span></p>
<p> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>For each Binding that is accessible to the BindingGroup, it looks up the name of the bound property and attaches all ValidationRules which are grouped under that name, if any. By convention, ValidationRules which have an empty String as property name are attached to the BindingGroup itself.</p>
<h4>How to Use ValidationRuleSetter on a Container</h4>
<p>In order to be able to attach the Sticky Component to a container, one defines a custom attached property like this:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f4ab5530-66f7-4b28-aeef-b5e11a78b3d0" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">ReadOnly</span> RuleSetterProperty <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">DependencyProperty</span> = <span style="color:#2b91af;">DependencyProperty</span>.RegisterAttached(<span style="color:#a31515;">&quot;RuleSetter&quot;</span>, <span style="color:#0000ff;">GetType</span>(<span style="color:#2b91af;">ValidationRuleSetter</span>), <span style="color:#0000ff;">GetType</span>(<span style="color:#2b91af;">Validation</span>), <span style="color:#0000ff;">New</span> <span style="color:#2b91af;">PropertyMetadata</span>(<span style="color:#0000ff;">AddressOf</span> WPFGlue.Framework.<span style="color:#2b91af;">StickyComponentManager</span>.OnStickyComponentChanged))<br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Function</span> GetRuleSetter(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">DependencyObject</span>) <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">ValidationRuleSetter</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> d.GetValue(RuleSetterProperty)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span><br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> SetRuleSetter(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">DependencyObject</span>, <span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#2b91af;">ValidationRuleSetter</span>)<br /> &#160;&#160;&#160;&#160;d.SetValue(RuleSetterProperty, value)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>This is actually the standard way of defining a sticky property in the WPFGlue framework.</p>
<p>One would then define the container in XAML like this:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ec11b5fb-9647-42f4-836d-bb5784aa5318" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">StackPanel</span><span style="color:#ff0000;"> v</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Validation.RuleSetter</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> vrules}</span><span style="color:#0000ff;">&quot; &gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">StackPanel.BindingGroup</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">BindingGroup</span><span style="color:#0000ff;">/&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">StackPanel.BindingGroup</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> StringProperty</span><span style="color:#0000ff;">,</span><span style="color:#ff0000;"> UpdateSourceTrigger</span><span style="color:#0000ff;">=PropertyChanged}&quot;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Validation.ErrorTemplate</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> ValidationTemplate}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> IntegerProperty</span><span style="color:#0000ff;">,</span><span style="color:#ff0000;"> UpdateSourceTrigger</span><span style="color:#0000ff;">=PropertyChanged}&quot;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Validation.ErrorTemplate</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> ValidationTemplate}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> DoubleProperty</span><span style="color:#0000ff;">,</span><span style="color:#ff0000;"> UpdateSourceTrigger</span><span style="color:#0000ff;">=PropertyChanged}&quot;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Validation.ErrorTemplate</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> ValidationTemplate}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<h4>Side Effects of Using BindingGroups</h4>
<p>The presence of a BindingGroup on a container has various effects: </p>
<ul>
<li>Any failed ValidationRule on any Binding inside the BindingGroup will make Validation.HasError return true on the container. </li>
<li>The BindingGroup’s own ValidationRules will cause the Validation.ErrorTemplate to be displayed on the container. ValidationRules on the Bindings will show the ErrorTemplate on the respective control and also the container’s ErrorTemplate. </li>
<li>The UpdateSourceTrigger on all Bindings inside the BindingGroup will be set to Explicit by default, which means that one would have to call BindingGroup.CommitEdit in order to have the Bindings update their sources. However, if the UpdateSourceTrigger on a Binding is set to another value in XAML, this value will be honoured. </li>
</ul>
<h4>Conclusion</h4>
<p>Using this technique, it is possible to separate the definition of validation rules both from the model and from the view. This overcomes the main disadvantage of ValidationRules and opens up the way for further applications. </p>
<p>In posts to come, I intend to cover how to extend this technique in order to do type checks on property values before they are committed to the bound properties, and how to connect this with general data entry handling.</p>
<p>On the <a href="http://wpfglue.wordpress.com/downloads/">Downloads page</a>, you can find the full code of the examples, plus some additions which will be covered in a later post. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/138/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=138&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2010/12/31/validating-objects-with-validationrules/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>
	</item>
		<item>
		<title>WPFGlue goes WPF 4.0</title>
		<link>http://wpfglue.wordpress.com/2010/05/23/wpfglue-goes-wpf-4-0/</link>
		<comments>http://wpfglue.wordpress.com/2010/05/23/wpfglue-goes-wpf-4-0/#comments</comments>
		<pubDate>Sun, 23 May 2010 17:48:27 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[WPFGlue]]></category>
		<category><![CDATA[WPF 4.0]]></category>

		<guid isPermaLink="false">https://wpfglue.wordpress.com/2010/05/23/wpfglue-goes-wpf-4-0/</guid>
		<description><![CDATA[When VS 2010 was released, I was quite eager to shift to the new version of the framework: the last two releases had brought a lot of real improvements, so I expected the new release to do likewise. Therefore, I upgraded the WPFGlue code to .Net 4.0 and tried it out. These were my experiences: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=133&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When VS 2010 was released, I was quite eager to shift to the new version of the framework: the last two releases had brought a lot of real improvements, so I expected the new release to do likewise. Therefore, I upgraded the WPFGlue code to .Net 4.0 and tried it out. These were my experiences:</p>
<h4>Upgrade Experience</h4>
<p>Upgrading went real smooth: it’s possible to install VS 2010 parallel to VS 2008, so I did that, copied my projects to the new version’s project folder, and opened them. After completing an Upgrade Wizard, there I was… No problem at all, and the Upgrade Wizard didn’t have to change any code, it just set the projects to target the .Net 4.0 Framework instead of .Net 3.5 . (Cool feature: in VS 2010 Express you can select the targeted framework version in the compile options, and you can select older and (hopefully) even newer versions than the one that comes with the VS installation). I have been running VS 2010 and VS 2008 in parallel ever since, and so far haven’t experinced any problems with that.</p>
<p>However, when testing the examples again, there were a few glitches:</p>
<ul>
<li>The LocalizedList in the WPFGlue.Localization namespace caused an error message in the XAML designer. </li>
<li>There was a problem with Bindings when navigating backwards through the navigation history in a NavigationWindow. </li>
</ul>
<h4>Error Message in the XAML Designer</h4>
<p>The new XAML designer is supposed to be more robust and to be more consistent with the Blend XAML designer. However, one of the tricks I did with the LocalizedList class caused it to hiccup: On this class, I implemented IList so one could set the child elements directly. This was due to the fact that the VS 2008 XAML designer was not handling this very graceful, and I wrote the class before I found out what one has to do to have proper support for typed collections. At the same time, this class can be used as a converter in bindings, in order to translate Enum values into human readable localized strings.</p>
<p>The combination of IList and IValueConverter seemed to be too much for the designer: while the application was compiling and running alright, the designer kept showing squiggly lines about an unset object reference in the XAML pane.</p>
<p>Debugging custom mark-up extensions in VS 2010 Express Edition is a little bit painful. I would recommend to buy the full version if you consider this, and meanwhile I’d recommend to keep away from them… Anyway, I found out that the error message goes away if you don’t implement IList on the same class as IValueConverter, so I just followed the pattern described in <a href="http://wpfglue.wordpress.com/2010/04/01/coding-for-xaml/">the Coding for XAML post</a>.</p>
<p>I posted this problem on the <a href="http://connect.microsoft.com/">Connect website</a> as product feedback, but they decided to not do anything about it, which I can understand.</p>
<h4>TextBox Bindings not Restored when Navigating Backwards</h4>
<p>I found this problem first in <a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/eee3ea2e-2156-45c9-aa0b-68e8a43f4615" target="_blank">this thread</a> in the <a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/threads" target="_blank">MSDN WPF forum</a>. When you have a page that has data-bound TextBoxes, navigate away from the page and then go back using the Back button of the NavigationWindow that contains the page, the TextBoxes come up blank, even though the DataContext of the page and TextBox is set correctly. It seems that the XAML of the Page is not read the same way when the page is re-displayed; I tried to solve the problem with a custom mark-up extension, and the extension was not instantiated when the page was revisited. So, I tried a DataTemplate instead, and that worked. Finally, I came up with wrapping the page contents into a UserControl. The UserControl seems to read its XAML definition every time it is displayed, and since it inherits the correct DataContext, the problem goes away.</p>
<p>Still, I think this is quite a serious glitch. I posted it to Connect as well, the answer is pending.</p>
<h4>Conclusion</h4>
<p>Having these strange kinds of errors was a little bit sobering about .Net 4.0. Even so, since I found workarounds, and since the new framework has some cool new features I hope to be using soon, I’m going to stick to it.</p>
<p>So, I updated the <a href="http://wpfglue.wordpress.com/downloads/">downloads page</a> with projects targeting the new version. I’m still keeping copies of the WPF 3.5 version, as well, but I’m not going to include new code into these versions. </p>
<h4></h4>
<h4>Coming Soon…</h4>
<p>The next thing I’m planning to do is to research the object lifetime events in WPF 4.0. I was stopped in my tracks a little bit when I found out that the pattern of Loaded and Unloaded events is not quite what one expects (this was still under WPF 3.5), and I’d like to find out what happens there exactly.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/133/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=133&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2010/05/23/wpfglue-goes-wpf-4-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>
	</item>
		<item>
		<title>Coding for XAML</title>
		<link>http://wpfglue.wordpress.com/2010/04/01/coding-for-xaml/</link>
		<comments>http://wpfglue.wordpress.com/2010/04/01/coding-for-xaml/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 14:15:22 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://wpfglue.wordpress.com/2010/04/01/coding-for-xaml/</guid>
		<description><![CDATA[XAML is basically a way of describing object structures, which will be instantiated by the XAML parser when a page, resource or template is used. Since one of the ideas in WPFGlue is to configure components in XAML, I had to wrestle a bit with the VS XAML designer and my classes in order to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=117&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>XAML is basically a way of describing object structures, which will be instantiated by the XAML parser when a page, resource or template is used. Since one of the ideas in WPFGlue is to configure components in XAML, I had to wrestle a bit with the VS XAML designer and my classes in order to make them work well with each other. This post is about what patterns you can use in order to make classes nice to use in XAML, and how to implement them.</p>
<h4></h4>
<h4>Basics</h4>
<p>A XAML tag is basically nothing but a class name and some attributes. The class name stands for the component, the attributes, for its properties. What the XAML parser will do is to create an instance of the class using a parameterless constructor, and to set the properties which have the same names as the attributes to the provided attribute values. So, the basic rules for creating a class for use in XAML are:</p>
<ul>
<li>The class must be public. </li>
<li>It must have a public, parameterless constructor. </li>
<li>All properties that will be accessed in XAML must be public. </li>
</ul>
<p>Two other best practices turned out to influence the XAML experience of my custom components, even though I didn’t quite find out why, and I expect this behaviour to change with version 4.0… Well, the problem was that the VS 2008 XAML editor didn’t recognize collection types properly, and that its Intellisense function would suggest every available element, not only the one which are allowed in the collection.</p>
<p>In order to fix that, I did the following:</p>
<ul>
<li>Move all components I want to use in XAML to a separate DLL (i.e. not the project they are used in) </li>
<li>Declare an XML Namespace for this DLL. When I use the components, I don’t declare a XML prefix for their CLR namespace, but use this declared namespace instead.      <br /> 
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:48efdf82-f91b-46ff-a8d7-0e25f4abc03b" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;">&lt;Assembly: System.Windows.Markup.XmlnsDefinition(<span style="color:#a31515;">&quot;http://wpfglue.wordpress.com/samples/codingforxaml&quot;</span>, <span style="color:#a31515;">&quot;CodingForXAML&quot;</span>)&gt; <br /> &lt;Assembly: System.Windows.Markup.XmlnsPrefix(<span style="color:#a31515;">&quot;http://wpfglue.wordpress.com/samples/codingforxaml&quot;</span>, <span style="color:#a31515;">&quot;cfx&quot;</span>)&gt;</div>
</p></div>
</p></div>
</li>
</ul>
<ul></ul>
<h4>Using the ContentProperty Attribute</h4>
<p>XAML elements can have one or many content elements. A content element is something like the “natural” or most important child element of its parent. It is special because you can set it in XAML without mentioning the name of the property which references it. However, in order to create an object structure, the XAML parser needs to know the property name. Therefore, you can set the name of the property which holds the child element by adding the System.Windows.Markup.ContentProperty(“MyChild”) attribute to the class declaration, where “MyChild” would be the name of the property which holds the child.</p>
<p>If the property is of an collection type, the element can contain multiple child elements, and they will all be added to the collection which the property holds.</p>
<h4>Collections for XAML</h4>
<p>If you set up your project like I explained in the first section, all you have to do is to derive a collection class from List(Of T) or ObservableCollection(Of T), where T is your item type.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ad969549-6d85-4c94-a2f3-d311f819f405" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> XamlCollection<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Inherits</span> List(<span style="color:#0000ff;">Of</span> XamlCollectionItem)</p>
<p> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span></p>
<p> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> XamlCollectionItem</p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Private</span> _IntegerValue <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Property</span> IntegerValue() <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _IntegerValue<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Set</span>(<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;_IntegerValue = value<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Set</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span></p>
<p> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span></div>
</p></div>
</p></div>
<p>If you do it this way, the XAML will display and compile without problems, and Intellisense will offer you only the available classes of the correct type. Normally, since we are talking about configuring components through XAML, the collection is not expected to change during run time, so it would be enough to use List(Of T). </p>
<p>If you want to use a collection type as the content for an element, you’d have to do the following further steps:</p>
<ul>
<li>Create a read-only property which holds an instance of the collection type. </li>
<li>Initialize it with an empty collection in the elements constructor. </li>
<li>Set the ContentProperty attribute to the property’s name. </li>
</ul>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a0837f08-8aff-477f-96a5-83af237ac945" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;">&lt;System.Windows.Markup.ContentProperty(<span style="color:#a31515;">&quot;Children&quot;</span>)&gt; _<br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> XamlCollectionParent<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Private</span> _Children <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">New</span> XamlCollection<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">ReadOnly</span> <span style="color:#0000ff;">Property</span> Children() <span style="color:#0000ff;">As</span> XamlCollection<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _Children<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span></div>
</p></div>
</p></div>
</p>
<h4>Referring to Objects by Name I: Keyed Collections</h4>
<p>Sometimes you want to refer to be able to refer to specific children of an element. The best way to make sure that you get the correct child is to name the children and to refer to them by name. In XAML, you would do this in a binding’s property path, like this: {Binding Path=MyParentElement.Children[ChildName]} </p>
<p>In order to be able to do that, you’d derive the collection class from KeyedCollection(Of T). Then you’d have to override the GetKeyForItem function, which is supposed to create a unique string key from an item of type T.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:60eed291-7c1e-4a38-b844-6862f0613b3b" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> XamlDictionary<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Inherits</span> System.Collections.ObjectModel.KeyedCollection(<span style="color:#0000ff;">Of</span> <span style="color:#0000ff;">String</span>, XamlDictionaryItem)</p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Protected</span> <span style="color:#0000ff;">Overrides</span> <span style="color:#0000ff;">Function</span> GetKeyForItem(<span style="color:#0000ff;">ByVal</span> item <span style="color:#0000ff;">As</span> XamlDictionaryItem) <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> item.Key<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span></p>
<p> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> XamlDictionaryItem<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Private</span> _Key <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Property</span> Key() <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _Key<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Set</span>(<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;_Key = value<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Set</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span></p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Private</span> _IntegerValue <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Property</span> IntegerValue() <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _IntegerValue<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Set</span>(<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;_IntegerValue = value<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Set</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span></div>
</p></div>
</p></div>
</p>
<p>You may ask why I don’t use Dictionary(Of TKey, TValue). Well, it seems that XAML’s support for dictionaries is very much geared towards the special needs of ResourceDictionaries, and I believe it is not intended to be used generally. However, KeyedCollection offers you the additional benefit that you can simply iterate over the items and don’t have to worry about mapping Key / Value pairs, since the keys are taken directly from the items.</p>
<h4>Referring to Objects by Name II: NameScopes</h4>
<p>A NameScope in WPF is what makes element names in a page unique and allows to reference elements by name using their x:Name attribute. If you have a tree structure of elements, but need to reference single elements by name also, a NameScope is the thing to use.</p>
<p>A Namescope is defined through a root element XAML. All descendants of this element which have an x:Name attribute will automatically be registered to the Namescope. In order for this to work, you have to do the following:</p>
<ul>
<li>The class which is the root element has to implement the System.Windows.Markup.INameScope interface. Internally, the implementation can be based on the NameScope class, which comes with the WPF framework. </li>
<li>The classes which are used as descendants of the root element need to use the System.Windows.Markup.RuntimeNameProperty attribute in their declaration, so that the XAML parser knows which property of the class stores the name. </li>
<li>In order to access the items by name, one needs an indexer. XAML is a little bit limited in its support for indexed properties: you have to have a class which declares the indexer as its default property. In order to provide indexed access to the named elements, this examples uses a nested class which does nothing but find the elements through its parent’s NameScope. </li>
</ul>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:79b7cc41-11ac-4c4d-925f-7b82dc0b7c0a" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"> <span style="color:#0000ff;">Private</span> _Indexer <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">New</span> NamescopeIndexer(<span style="color:#0000ff;">Me</span>)<br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">ReadOnly</span> <span style="color:#0000ff;">Property</span> Node() <span style="color:#0000ff;">As</span> NamescopeIndexer<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _Indexer<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span></p>
<p> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> NamescopeIndexer<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Private</span> _Root <span style="color:#0000ff;">As</span> XamlNamescopeRoot<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Friend</span> <span style="color:#0000ff;">Sub</span> <span style="color:#0000ff;">New</span>(<span style="color:#0000ff;">ByVal</span> root <span style="color:#0000ff;">As</span> XamlNamescopeRoot)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">MyBase</span>.New()<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;_Root = root<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Default</span> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">ReadOnly</span> <span style="color:#0000ff;">Property</span> Item(<span style="color:#0000ff;">ByVal</span> name <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span>) <span style="color:#0000ff;">As</span> NamescopeNode<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> _Root.Namescope.FindName(name)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Get</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Property</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<h4>Markup Extensions</h4>
<p>Markup extensions are helpful in situations where you have to do more complicated things than just creating an instance of a class and assign it some values. For example, you can use a Markup extension if you want to establish a binding, or if you want to access a backing store which itself is not accessible to XAML, like application settings, localized resources or a configuration file.</p>
<p>However, I am not very fond of markup extensions. They are basically a convenience: normally, you can achieve the same using just a more verbose syntax. And the convenience comes at a price:</p>
<p>Markup extensions have to execute well both at runtime and in the VS designer. Both environments are radically different, and it is not trivial to find out the difference from inside the markup extension. Also, if there is any problem in design mode, there is no debugging support, since the designer always uses the release compiled version of the markup extension. Moreover, I even couldn’t use structured error handling inside the class, since my catch blocks never were called, and sometimes VS crashes when compiling or editing markup extensions.</p>
<p>Anyway, for the sake of completeness, here what I learned:</p>
<ul>
<li>Derive a markup extension from System.Windows.Markup.MarkupExtension and override the ProvideValue method. </li>
<li>Set the MarkupExtensionReturnType attribute to the correct type. </li>
<li>If the type of the serviceProvider parameter is System.Windows.Markup.ProvideValueServiceProvider, you are in runtime mode, otherwise, you are in design mode. </li>
<li>Use serviceProvider.GetService(GetType(IProvideValueTarget)) in order to retrieve information about the property which will receive the value. If the TargetProperty parameter is of type DependencyProperty, the property is a dependency property and you can do things like set up a binding, so that the value will be updated automatically if the underlying data source changes. </li>
<li>Always return a valid value of the correct type, even if the value is some message like “I couldn’t find what you wanted”. </li>
<li>Whatever you do, avoid exceptions in the ProvideValue method at all costs. In this case this doesn’t mean “catch”, but really “avoid”, since structured exception handling doesn’t seem to work when the extension is used in the designer. </li>
</ul>
<h4></h4>
<h4>Reporting Configuration Errors</h4>
<p>As a rule, your component shouldn’t raise any exceptions if it doesn’t have all the information it needs to do its job, but just make do without it, using intelligent default behaviour or gracefully reducing the functionality. However, sometimes you just have to report something.</p>
<p>In this case, you can raise an ArgumentException with an appropriate message in the property setter which receives the invalid value. Exceptions that are raised in this way will show up in the VS Error List and keep the project from building.</p>
<h4>Other Best Practices</h4>
<ul>
<li>Don’t do complex things like e.g. accessing a database in a constructor. Constructors will run at design time as well as at run time. So, if they need information from the application they are running in, this information might not be accessible at design time. Therefore, one might see strange error messages at design time which are difficult to debug. </li>
<li>Don’t rely on a certain order in which the properties of your component should be set. If you need several property values in order to do a job, either don’t access the values until you need to do the job, or check whether you have a complete set of values each time any of the properties changes, and start the job as soon as you have a valid set of values. </li>
</ul>
<h4>Conclusion</h4>
<p>If you follow these guidelines, your components will behave similar to the components that come with the WPF framework, and they will integrate into the support given by the VS XAML editor.</p>
<p>There are some other techniques which I haven’t covered here, but which I would like to mention: using dependency properties and using type converters. You can find examples for dependency properties all over this blog, e.g. here: <a href="http://wpfglue.wordpress.com/2009/12/16/the-sticky-viewmodel-pattern/">http://wpfglue.wordpress.com/2009/12/16/the-sticky-viewmodel-pattern/</a> . An example for using type converters is given in this post: <a href="http://wpfglue.wordpress.com/2009/11/30/css-class-equivalent-in-wpf/">http://wpfglue.wordpress.com/2009/11/30/css-class-equivalent-in-wpf/</a> . Otherwise, you will find the patterns which I discussed here everywhere in the WPFGlue code. A special example project for this post is available for download here:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:F60BB8FA-6F02-4999-8F5E-9DD4E92C4DA7:183a9fb5-a8e1-4088-8893-c3374a5e9676" class="wlWriterEditableSmartContent">
<div><a href="http://wpfglue.files.wordpress.com/2010/04/codingforxaml-zip_.doc" target="_self">CodingForXAML.zip.doc</a></div>
</div>
<p>(as always on wordpress.com, you will have to rename it to a .zip extension in order to extract it).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/117/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/117/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=117&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2010/04/01/coding-for-xaml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>
	</item>
		<item>
		<title>Implementing the Sticky Command Design Pattern</title>
		<link>http://wpfglue.wordpress.com/2010/02/13/implementing-the-sticky-command-design-pattern-2/</link>
		<comments>http://wpfglue.wordpress.com/2010/02/13/implementing-the-sticky-command-design-pattern-2/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 10:02:49 +0000</pubDate>
		<dc:creator>wpfglue</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[Sticky Command]]></category>
		<category><![CDATA[WPFGlue]]></category>

		<guid isPermaLink="false">http://wpfglue.wordpress.com/2010/02/13/implementing-the-sticky-command-design-pattern-2/</guid>
		<description><![CDATA[The Sticky Command design pattern is one of the patterns in WPFGlue which allow to add custom functionality to out-of-the-box WPF controls. Adding a Sticky Command to a FrameworkElement gives it a certain new behaviour, and makes this behaviour available to the element and all its child elements through a routed command, while the implementation [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=115&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The Sticky Command design pattern is one of the <a href="http://wpfglue.wordpress.com/2009/11/05/list-of-useful-design-patterns-for-wpf-glue/">patterns in WPFGlue</a> which allow to add custom functionality to out-of-the-box WPF controls. Adding a Sticky Command to a FrameworkElement gives it a certain new behaviour, and makes this behaviour available to the element and all its child elements through a routed command, while the implementation of the element remains separate and independent of the implementation of the behaviour.</p>
<p>Let’s take an example. A very common need in data oriented applications is a submit command which sends the values of a group of controls to the underlying data store. This command should be disabled when the data is invalid, and it should be possible to connect it to a KeyGesture which allows to call the command by pressing a given key when entering data.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">GroupBox</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;CustomerGroupBox&quot;</span> <span class="attr">Header</span><span class="kwrd">=&quot;Customer&quot;</span>
          <span class="attr">v:Submit</span>.<span class="attr">Command</span><span class="kwrd">=&quot;{StaticResource SubmitCommand}&quot;</span>
          <span class="attr">v:Submit</span>.<span class="attr">KeyGesture</span><span class="kwrd">=&quot;Enter&quot;</span><span class="kwrd">&gt;</span> <span class="kwrd">&lt;!</span>—- Content left out for clarity --<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">GroupBox</span><span class="kwrd">&gt;</span></pre>
<p>The Sticky Command is stuck to the GroupBox by setting the Submit.Command Sticky Property. Optionally, one can add a KeyGesture which invokes the command, in this case pressing the Enter key. The SubmitCommand is just a standard RoutedCommand:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Window.Resources</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">RoutedCommand</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;SubmitCommand&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Window.Resources</span><span class="kwrd">&gt;</span></pre>
<p>By itself it doesn’t provide any functionality; it’s just kind of an identifier for the behaviour we want to add to the GroupBox.</p>
<h4>Creating a Sticky Property</h4>
<p>A Sticky Property is an attached property that, in addition to storing a value on the target element, does some work in its PropertyChanged handler. In our case, this work consists of creating a CommandBinding and setting it on the target element, or removing the created CommandBinding, respectively.</p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Class</span> Submit
    <span class="kwrd">Inherits</span> DependencyObject

    <span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">ReadOnly</span> CommandProperty <span class="kwrd">As</span> DependencyProperty = _
            DependencyProperty.RegisterAttached(<span class="str">&quot;Command&quot;</span>, _
            <span class="kwrd">GetType</span>(RoutedCommand), <span class="kwrd">GetType</span>(Submit), _
            <span class="kwrd">New</span> PropertyMetadata(<span class="kwrd">AddressOf</span> OnCommandChanged))
    <span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">Function</span> GetCommand(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> DependencyObject) _
            <span class="kwrd">As</span> RoutedCommand
        <span class="kwrd">Return</span> d.GetValue(CommandProperty)
    <span class="kwrd">End</span> <span class="kwrd">Function</span>
    <span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> SetCommand(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> DependencyObject, _
            <span class="kwrd">ByVal</span> value <span class="kwrd">As</span> RoutedCommand)
        d.SetValue(CommandProperty, value)
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
    <span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> OnCommandChanged(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> DependencyObject, _
        <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> DependencyPropertyChangedEventArgs)
        <span class="kwrd">Dim</span> f <span class="kwrd">As</span> FrameworkElement = <span class="kwrd">TryCast</span>(d, FrameworkElement)
        <span class="kwrd">If</span> f IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
            <span class="kwrd">If</span> e.OldValue IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
                Detach(f, e.OldValue)
            <span class="kwrd">End</span> <span class="kwrd">If</span>
            <span class="kwrd">If</span> e.NewValue IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
                Attach(f, e.NewValue)
            <span class="kwrd">End</span> <span class="kwrd">If</span>
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="rem">'...</span>
<span class="kwrd">End</span> Class</pre>
<p>The implementation of OnCommandChanged is quite simple: if the property already has a value, the command should be detached from the target, and if a new value is provided, this value should be attached to it. One might ask why it is necessary to provide a Detach procedure as well. Why not just leave the CommandBinding in place? If the command can be removed by changing setting the value of Submit.Command to Nothing, then the command can be attached and detached through triggers, which opens up a whole new line of uses…</p>
<h4>Attaching and Detaching the CommandBinding</h4>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> Attach(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> FrameworkElement, _
                          <span class="kwrd">ByVal</span> command <span class="kwrd">As</span> RoutedCommand)
    d.CommandBindings.Add(<span class="kwrd">New</span> SubmitCommandBinding(command))
    <span class="kwrd">Dim</span> gesture <span class="kwrd">As</span> KeyGesture = GetKeyGesture(d)
    AttachKeyGesture(d, command, gesture)
    <span class="kwrd">If</span> d.BindingGroup <span class="kwrd">Is</span> <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
        d.BindingGroup = <span class="kwrd">New</span> BindingGroup
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> Detach(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> FrameworkElement, _
                          <span class="kwrd">ByVal</span> command <span class="kwrd">As</span> RoutedCommand)
    <span class="kwrd">For</span> <span class="kwrd">Each</span> b <span class="kwrd">As</span> SubmitCommandBinding <span class="kwrd">In</span> _
            d.CommandBindings.OfType(Of SubmitCommandBinding)()
        d.CommandBindings.Remove(b)
    <span class="kwrd">Next</span>
    DetachKeyGesture(d)
<span class="kwrd">End</span> <span class="kwrd">Sub</span></pre>
<p>The Attach procedure creates a new CommandBinding that connects the provided RoutedCommand to its implementation, and adds it to the targets CommandBindings collection.</p>
<p>The Detach procedure removes the CommandBinding from the collection. In order to be able to find the correct CommandBinding, Attach uses a class derived from CommandBinding, in order to use its type as marker. This way, one doesn’t have to store a reference to the created CommandBinding in order to be able to remove it later. The dummy class is a private nested class inside the Submit class:</p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Class</span> SubmitCommandBinding
    <span class="kwrd">Inherits</span> CommandBinding
    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> <span class="kwrd">New</span>(<span class="kwrd">ByVal</span> command <span class="kwrd">As</span> RoutedCommand)
        <span class="kwrd">MyBase</span>.<span class="kwrd">New</span>(command, <span class="kwrd">AddressOf</span> OnExecutedSubmit, _
                   <span class="kwrd">AddressOf</span> OnCanExecuteSubmit)
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">End</span> Class</pre>
<h4>The Command’s Implementation</h4>
<p>The procedures OnExecutedSubmit and OnCanExecuteSubmit handle the RoutedCommand.CanExecute and RoutedCommand.Executed events that are sent out by the CommandBinding. It is useful to separate the code specific to event handling from the code that does the actual work:</p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> OnCanExecuteSubmit(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, _
        <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> CanExecuteRoutedEventArgs)

    <span class="kwrd">Dim</span> result <span class="kwrd">As</span> <span class="kwrd">Boolean</span> = <span class="kwrd">False</span>
    <span class="kwrd">Dim</span> target <span class="kwrd">As</span> FrameworkElement = <span class="kwrd">TryCast</span>(sender, FrameworkElement)
    <span class="kwrd">If</span> target IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
        <span class="rem">' Separate event specific code from domain specific code...</span>
        result = CanExecuteSubmit(target,e.Parameter)
    <span class="kwrd">End</span> <span class="kwrd">If</span>
    e.CanExecute = result
    e.Handled = <span class="kwrd">True</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>

<span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">Function</span> CanExecuteSubmit(<span class="kwrd">ByVal</span> target <span class="kwrd">As</span> FrameworkElement, _
        <span class="kwrd">ByVal</span> parameter <span class="kwrd">As</span> <span class="kwrd">Object</span>) <span class="kwrd">As</span> <span class="kwrd">Boolean</span>
    <span class="kwrd">Dim</span> result <span class="kwrd">As</span> <span class="kwrd">Boolean</span> = <span class="kwrd">False</span>
    <span class="kwrd">If</span> target IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
        result = (target.BindingGroup IsNot <span class="kwrd">Nothing</span> <span class="kwrd">AndAlso</span> <span class="kwrd">Not</span> _
                  System.Windows.Controls.Validation.GetHasError(target))
    <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">Return</span> result
<span class="kwrd">End</span> <span class="kwrd">Function</span>

<span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> OnExecutedSubmit(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, _
                                    <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> ExecutedRoutedEventArgs)
    <span class="kwrd">Dim</span> target <span class="kwrd">As</span> FrameworkElement = <span class="kwrd">TryCast</span>(sender, FrameworkElement)
    <span class="kwrd">If</span> target IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
        <span class="kwrd">If</span> CanExecuteSubmit(target, e.Parameter) <span class="kwrd">Then</span>
            ExecuteSubmit(target, e.Parameter)
        <span class="kwrd">End</span> <span class="kwrd">If</span>
        e.Handled = <span class="kwrd">True</span>
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>

<span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> ExecuteSubmit(<span class="kwrd">ByVal</span> target <span class="kwrd">As</span> FrameworkElement, _
        <span class="kwrd">ByVal</span> parameter <span class="kwrd">As</span> <span class="kwrd">Object</span>)
    target.BindingGroup.UpdateSources()
<span class="kwrd">End</span> <span class="kwrd">Sub</span></pre>
<h4>Providing a KeyGesture</h4>
<p>In order to be able to specify a KeyGesture for the command on the target, we need to create a second Sticky Property, which is able to add the KeyGesture to the target’s InputBindings collection. The method is similar to the one used with the CommandBinding itself. However, there is one point of note: We cannot be sure of the order in which the attached properties are set on the target. So, we have to make sure that CommandBinding and InputBinding are set up correctly no matter which is specified first. Since the InputBinding depends on the CommandBinding, one could say that Submit.Command is the main Sticky Property, while Submit.KeyGesture is a supporting Sticky property. The rule would then be that the Attach and Detach procedures for the main Sticky property would have to call the Attach procedures for all supporting properties in turn, while the Attach procedures of the supporting properties only attach something if the main Sticky Property has already been set.</p>
<p>The implementation of the KeyGesture functionality looks like this:</p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">ReadOnly</span> KeyGestureProperty <span class="kwrd">As</span> DependencyProperty = _
        DependencyProperty.RegisterAttached(<span class="str">&quot;KeyGesture&quot;</span>, _
                    <span class="kwrd">GetType</span>(KeyGesture), <span class="kwrd">GetType</span>(Submit), _
                    <span class="kwrd">New</span> PropertyMetadata(<span class="kwrd">AddressOf</span> OnKeyGestureChanged))
<span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">Function</span> GetKeyGesture(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> DependencyObject) _
        <span class="kwrd">As</span> KeyGesture
    <span class="kwrd">Return</span> d.GetValue(KeyGestureProperty)
<span class="kwrd">End</span> <span class="kwrd">Function</span>
<span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> SetKeyGesture(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> DependencyObject, _
                                <span class="kwrd">ByVal</span> value <span class="kwrd">As</span> KeyGesture)
    d.SetValue(KeyGestureProperty, value)
<span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> OnKeyGestureChanged(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> DependencyObject, _
        <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> DependencyPropertyChangedEventArgs)
    <span class="kwrd">Dim</span> f <span class="kwrd">As</span> FrameworkElement = <span class="kwrd">TryCast</span>(d, FrameworkElement)
    <span class="kwrd">If</span> f IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
        <span class="kwrd">If</span> e.OldValue IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
            DetachKeyGesture(f)
        <span class="kwrd">End</span> <span class="kwrd">If</span>
        <span class="kwrd">If</span> e.NewValue IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
            AttachKeyGesture(f, GetCommand(f), e.NewValue)
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> AttachKeyGesture(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> FrameworkElement, _
                                    <span class="kwrd">ByVal</span> command <span class="kwrd">As</span> RoutedCommand, _
                                    <span class="kwrd">ByVal</span> gesture <span class="kwrd">As</span> KeyGesture)
    <span class="kwrd">If</span> command IsNot <span class="kwrd">Nothing</span> <span class="kwrd">And</span> gesture IsNot <span class="kwrd">Nothing</span> <span class="kwrd">Then</span>
        d.InputBindings.Add(<span class="kwrd">New</span> SubmitKeyBinding(command, gesture))
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Sub</span> DetachKeyGesture(<span class="kwrd">ByVal</span> d <span class="kwrd">As</span> FrameworkElement)
    <span class="kwrd">For</span> <span class="kwrd">Each</span> i <span class="kwrd">As</span> SubmitKeyBinding <span class="kwrd">In</span> _
            d.InputBindings.OfType(Of SubmitKeyBinding)()
        d.InputBindings.Remove(i)
    <span class="kwrd">Next</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>

<span class="kwrd">Private</span> <span class="kwrd">Class</span> SubmitKeyBinding
    <span class="kwrd">Inherits</span> InputBinding
    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> <span class="kwrd">New</span>(<span class="kwrd">ByVal</span> command <span class="kwrd">As</span> RoutedCommand, _
            <span class="kwrd">ByVal</span> gesture <span class="kwrd">As</span> KeyGesture)
        <span class="kwrd">MyBase</span>.<span class="kwrd">New</span>(command, gesture)
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
<span class="kwrd">End</span> <span class="kwrd">Class</span></pre>
<h4>Reusability</h4>
<p>Once we have this submit command, we can reuse it as it is, in any project, with any kind of control or data. But what about reusability of the pattern implementation itself?</p>
<p>The whole Submit class consists of static members, only. This has the advantage of not creating dependent object references with the command bindings, which could interfere with the garbage collection of the page on which the command is used. Unfortunately, shared members cannot be overridden, which means that it is not straight forward to create a common base class for Sticky Commands and derive new implementations from that class. However, the domain specific code and the pattern specific code are quite easy to separate into different procedures, so that it might be an option to use Item Templates or Code Snippets in order to reuse the pattern specific code.</p>
<h4>Conclusion</h4>
<p>The Sticky Command pattern offers a powerful and flexible way of modifying the behaviour of standard controls without changing their implementation. Because it is used through declarative syntax, it can leverage the full power of WPF style, trigger and template mechanisms. In addition to that, a new implementation of the pattern can be created from an existing one with minimal changes.</p>
<h4>Downloads</h4>
<p>The example solution on the <a href="http://wpfglue.wordpress.com/downloads/">Downloads page</a> contains a project called SubmitCommandExample which has the complete code for this example.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/115/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=115&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2010/02/13/implementing-the-sticky-command-design-pattern-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0e29454d34d36a3626eeaae152ecfd38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">wpfglue</media:title>
		</media:content>
	</item>
		<item>
		<title>Localized Value Formatting in WPF</title>
		<link>http://wpfglue.wordpress.com/2010/01/14/localized-value-formatting-in-wpf/</link>
		<comments>http://wpfglue.wordpress.com/2010/01/14/localized-value-formatting-in-wpf/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 13:07:59 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[Localization]]></category>
		<category><![CDATA[Formatting]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://wpfglue.wordpress.com/2010/01/14/localized-value-formatting-in-wpf/</guid>
		<description><![CDATA[When I introduced the WPFGlue localization components, I concentrated mainly on displaying localized strings and other static information in the user interface. Today I want to complete the WPFGlue localization section by discussing localized value formatting. The Problem Number and date formats vary from culture to culture. 30/12/2009, 12/30/2009 and 30.12.2009 all refer to the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=114&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When I introduced the <a href="http://wpfglue.wordpress.com/2009/12/05/using-net-localized-string-resources-in-wpf/">WPFGlue localization components</a>, I concentrated mainly on displaying localized strings and other static information in the user interface. Today I want to complete the WPFGlue localization section by discussing localized value formatting.</p>
<h4>The Problem</h4>
<p>Number and date formats vary from culture to culture. 30/12/2009, 12/30/2009 and 30.12.2009 all refer to the same day, and 12.345,67 and 12,345.67 are actually the same number, but will turn out very different if the computer doesn’t know which format the user assumed. Since the early days of computers, this problem has been solved by defining the culture under which the system runs as a system property. Then there would be a set of predefined formats for each given culture which implement the usual standards in that culture. Applications would take number and date formats from these system settings, so they could use the local standards even though they were developed in a different language.</p>
<p>A special case of this problem are enumerated lists. Usually, there is a short text that describes each option. In a localized application, this text should be translated according to the current culture, and it would also be necessary to sort the list differently in different languages in order to keep up an alphabetic order of the items.</p>
<h4>Specifying the Formatting Culture in WPF</h4>
<p>In WPF, value formatting is part of data binding: if a control needs to display a bound value, it converts it into a string and displays the string. The culture which is used can come from three sources:</p>
<ul>
<li>Default: if you don’t do anything special to tell the system from which culture it should derive its number and date formats, it will just take standard US English. Makes sense to define one culture so that by default the application will look the same on whatever system it runs. But actually, in the rest of Dot.NET the rule is that the application should take the installed system culture as default for these purposes, so WPF breaks the expectations of especially us poor Non-Americans… </li>
<li>The Language property or xml:lang attribute: WPF FrameworkElements have a Language property, which can accept a IETF language tag like en-US or de-DE, and will set the date and number formats according to this language and culture’s properties. The definitions for the formats come from a set of preinstalled cultures which are part of the Dot.Net framework. The Language property is inherited, so if it is specified on top of a page, it will take effect on the whole page. </li>
<li>The ConverterCulture property on the Binding: This property accepts a Globalization.CultureInfo object. This object might come from any source. Especially, if the user changed the standard number and date formats on the system using the Language and Regional Settings in Control Panel, these changes will be visible in the CurrentCulture object of the application, while they won’t be visible if one just sets the Language property. </li>
</ul>
<p>So, setting the ConverterCulture on the bindings would be the preferred way to respect the system’s and user’s formatting preferences. However, there are two drawbacks: first of all there is no built-in way to get at the system culture in XAML, and second one would have to specify the culture on each and every binding, since there is no way to apply this setting in a way that is global to the application.</p>
<p>In order to solve this problem, I added another MarkupExtension to the WPFGlue localization namespace: Binding. This is actually nothing more than a normal Binding with the ConverterCulture preset to the CurrentCulture of the system:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:191ce82b-b5b2-469f-b905-1cf9decdfa1f" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Namespace</span> Localization<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> Binding<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Inherits</span> System.Windows.Data.Binding</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Sub</span> <span style="color:#0000ff;">New</span>()<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">MyBase</span>.New()<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ConverterCulture = System.Globalization.CultureInfo.CurrentCulture<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Sub</span> <span style="color:#0000ff;">New</span>(<span style="color:#0000ff;">ByVal</span> path <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">MyBase</span>.New(path)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ConverterCulture = System.Globalization.CultureInfo.CurrentCulture<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Class</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Namespace</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>So, one can use it everywhere instead of the default Binding, and get date and number formats that behave according to the system settings. I’m not especially proud of this solution, but for the time being it seems to be the best compromise.</p>
<p>The LocalizationExample which you find in the WPFGluePublished solution on the <a title="Downloads" href="http://wpfglue.wordpress.com/downloads/">Downloads page</a> demonstrates this behaviour. This XAML code:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:abdf730f-e6a9-4d4e-b6f8-f67b55e71c57" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;">&#160;&#160;&#160;<span style="color:#ff0000;"> Title</span><span style="color:#0000ff;">=&quot;LocalizedPage&quot;</span><span style="color:#ff0000;"> Language</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">UILanguage}</span><span style="color:#0000ff;">&quot;</span><span style="color:#ff0000;"> FlowDirection</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">FlowDirection}</span><span style="color:#0000ff;">&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Page.Resources</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">s</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">DateTime</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Key</span><span style="color:#0000ff;">=&quot;Value&quot;&gt;</span><span style="color:#a31515;">#12/30/2009#</span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">s</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">DateTime</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Page.Resources</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Grid</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">StackPanel</span><span style="color:#ff0000;"> HorizontalAlignment</span><span style="color:#0000ff;">=&quot;Center&quot;</span><span style="color:#ff0000;"> VerticalAlignment</span><span style="color:#0000ff;">=&quot;Center&quot; &gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBlock</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">String</span><span style="color:#ff0000;"> TestString}</span><span style="color:#0000ff;">&quot; /&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBlock</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> Source</span><span style="color:#0000ff;">={</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> Value}}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBlock</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> Source</span><span style="color:#0000ff;">={</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> Value}}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Image</span><span style="color:#ff0000;"> Stretch</span><span style="color:#0000ff;">=&quot;None&quot;</span><span style="color:#ff0000;"> Source</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">BitmapImage</span><span style="color:#ff0000;"> FlagURI}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Grid</span><span style="color:#0000ff;">&gt;</span><br /> <span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Page</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>produces the following output:</p>
<p><a href="http://wpfglue.files.wordpress.com/2010/01/image.png"><img style="display:block;float:none;margin-left:auto;margin-right:auto;border-width:0;" title="image" border="0" alt="image" src="http://wpfglue.files.wordpress.com/2010/01/image_thumb.png?w=244&#038;h=244" width="244" height="244" /></a> </p>
<p>&#160;</p>
</p>
<p>Notice that setting the page’s Language property to the UILanguage (German in my case) causes the first binding to display its value in the default German date format, while using the localized binding causes the same value to be displayed in the format YYYY-MM-DD, which is what I specified in Control Panel as the standard short date format.</p>
<h4>Localized Lists</h4>
<p>In Dot.NET, sets of options can and should be summarized in enumeration types, with a named constant for each available option. The Dot.NET formatting engine, which is called through the String.Format method, supports converting the numeric enumeration values to strings and vice versa using the constant names that are defined for the enumeration in code. However, this option is only useful for debug output. If the values must be displayed to users, they must be translated into their languages, and actually this is not the job of the code which defines the enumeration.</p>
<p>A user interface which wants to use enumeration values needs the following functions:</p>
<ul>
<li>translate numerical values to string descriptions (for read-only display of values). </li>
<li>translate string descriptions into numerical values (for cases where the user can enter text). </li>
<li>create a mapped list of values and descriptions (for ComboBoxes and the like where the user just picks a value from a list). </li>
</ul>
<p>The LocalizedList class provides these functions. It works both as a collection of value / description pairs and as a IValueConverter that converts the descriptions forwards and backwards.</p>
<p>In order to define a LocalizedList, you have several options:</p>
<ul>
<li>Just set the ValueEnum to an enumeration type and let the LocalizedList generate the entries from the enumeration’s definition (actually, this is not localizing anything yet…)</li>
<li>Set the LocalizedList’s Definition property to a string in the format “value1=name1,value2=name2…”, where the values are the constant names or values from the enum definition, and the names the localized display names. Typically, the definition string would itself be a localized string resource.</li>
<li>Define Entry objects directly in the XAML, which map string keys to arbitrary typed values.</li>
</ul>
<p>The definition string format is actually quite flexible. So, you can change the default list and value separator characters (“,” and “=”). You could also leave out the values and just specify the enumeration type, so that the LocalizedList assumes that you specified the descriptions for the numeric values in their natural order. On the other hand, you could specify both names and values, but change the order, or use a subset of the available values, only. And finally, you could leave out the ValueEnum altogether and use String codes instead, as it is done in the language selection list in the example:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:af117db6-4154-4a73-83e9-ee74067ade6a" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">LocalizedList</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Key</span><span style="color:#0000ff;">=&quot;languageList&quot;</span><span style="color:#ff0000;"> Definition</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">String</span><span style="color:#ff0000;"> LanguageList}</span><span style="color:#0000ff;">&quot;/&gt;</span></div>
</p></div>
</p></div>
<p>where e.g. the English version of the referenced string resource is</p>
<p>de-DE=German,en-US=English,ar-SA=Arabic</p>
<p>The other LocalizedList in the example maps String keys directly to objects:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c49b12e2-0817-4518-9aaf-71b62dc0e0a3" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">LocalizedList</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Key</span><span style="color:#0000ff;">=&quot;assemblies&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">Entry</span><span style="color:#ff0000;"> Key</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">String</span><span style="color:#ff0000;"> InternalLabel}</span><span style="color:#0000ff;">&quot;</span><span style="color:#ff0000;"> Value</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">x</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">Null}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">Entry</span><span style="color:#ff0000;"> Key</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">String</span><span style="color:#ff0000;"> ExternalLabel}</span><span style="color:#0000ff;">&quot;</span><span style="color:#ff0000;"> Value</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">x</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">Type</span><span style="color:#ff0000;"> r</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Dummy}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">LocalizedList</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>Using this list, it is possible to change the resource assembly of the example purely in XAML, with no code behind:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2df0480e-531c-470a-bd0b-302091103584" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ComboBox</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Name</span><span style="color:#0000ff;">=&quot;SelectAssembly&quot;</span><span style="color:#ff0000;"> ItemsSource</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> assemblies}</span><span style="color:#0000ff;">&quot;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> DisplayMemberPath</span><span style="color:#0000ff;">=&quot;Key&quot;</span><span style="color:#ff0000;"> SelectedValuePath</span><span style="color:#0000ff;">=&quot;Value&quot;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> SelectedValue</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> RelativeSource</span><span style="color:#0000ff;">={</span><span style="color:#a31515;">RelativeSource</span> <br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Mode</span><span style="color:#0000ff;">=FindAncestor,</span><span style="color:#ff0000;"> AncestorType</span><span style="color:#0000ff;">={</span><span style="color:#a31515;">x</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">Type</span><span style="color:#ff0000;"> NavigationWindow}}</span><span style="color:#0000ff;">,</span> <br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Path</span><span style="color:#0000ff;">=(l:Localization.ResourceReferenceType)}&quot;/&gt;</span></div>
</p></div>
</p></div>
<h4>&#160;</h4>
<h4>Conclusion</h4>
<p>Using localized resources on the one hand and providing localized value formatting on the other hand are about all that comes to my mind under the heading of localization. I’ll be glad to react to feedback or criticism…</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/114/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=114&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2010/01/14/localized-value-formatting-in-wpf/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>

		<media:content url="http://wpfglue.files.wordpress.com/2010/01/image_thumb.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>The Sticky ViewModel Pattern</title>
		<link>http://wpfglue.wordpress.com/2009/12/16/the-sticky-viewmodel-pattern/</link>
		<comments>http://wpfglue.wordpress.com/2009/12/16/the-sticky-viewmodel-pattern/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 20:16:10 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[Patterns]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Sticky ViewModel]]></category>

		<guid isPermaLink="false">http://wpfglue.wordpress.com/2009/12/16/the-sticky-viewmodel-pattern/</guid>
		<description><![CDATA[A Sticky ViewModel is a special type of Sticky Component which adds functionality to the ViewModel instead of to the View. By binding to the DataContext of its base element, the Sticky ViewModel is able to provide services which the ViewModel itself doesn’t include. In this respect, it is similar to the Mini-ViewModel pattern, which [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=105&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A Sticky ViewModel is a special type of <a title="The Sticky Component Framework" href="http://wpfglue.wordpress.com/2009/12/11/the-sticky-component-framework/">Sticky Component</a> which adds functionality to the ViewModel instead of to the View. By binding to the DataContext of its base element, the Sticky ViewModel is able to provide services which the ViewModel itself doesn’t include. In this respect, it is similar to the <a href="http://www.scottlogic.co.uk/blog/wpf/2009/08/the-mini-viewmodel-pattern/" target="_blank">Mini-ViewModel pattern</a>, which you might prefer if you want to provide an encapsulated reusable View for the added functionality as well.</p>
<h4>An Example</h4>
<p>The model or ViewModel might have a property which contains a persons name. In the View, you might want to be able to edit first name and last name separately. I have already discussed this example in the context of the <a href="http://wpfglue.wordpress.com/2009/12/06/the-stateless-sticky-viewmodel-pattern/">Stateless Sticky ViewModel</a> pattern, so here I want to add some extra: the new implementation should format the name either John Smith or Smith, John, depending on a boolean property LastNameFirst which one can use to configure the behaviour.</p>
<p>The example is contained in the StickyComponentExample project which you will find in the WPFGluePublished solution on the <a title="Downloads" href="http://wpfglue.wordpress.com/downloads/">Downloads page</a>.</p>
<h4>Using a Sticky ViewModel</h4>
<p>Like any other Sticky Component, you would initialize a Sticky ViewModel in the resources of an element that wants to use them:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b09292d6-d2af-438e-b672-422a20694402" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Grid.Resources</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ex</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">NameStickyViewModel</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Key</span><span style="color:#0000ff;">=&quot;viewModel&quot;</span> <br /> &#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> LastNameFirst</span><span style="color:#0000ff;">=&quot;True&quot;</span><span style="color:#ff0000;"> FullName</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">f</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">StickyBinding</span><span style="color:#ff0000;"> Name}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Grid.Resources</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p>Using the LastNameFirst property, we specify that we want the full name displayed in the Smith, John format.</p>
<p>But what is the meaning of the {f:StickyBinding } markup extension? It is understood that the Sticky ViewModel somehow accesses the DataContext of its base element in order to enhance it. In fact, there is a DataContext property in the StickyViewModel base class which is synchronized with the base’s DataContext automatically. </p>
<p>However, if the Sticky ViewModel would get the information it needs directly from the DataContext, it would have to know its type, thus being closely coupled to the ViewModel, which we want to avoid, since we want to be able to re-use the Sticky ViewModel wherever we need its functionality. So, the idea is to get the necessary information from the DataContext through data binding. Unfortunately, since the Sticky ViewModel is not part of the logical WPF tree, normal bindings cannot access the base element’s DataContext implicitly, like child controls. So, we use a special binding class, the StickyBinding, which allows us to bind to the DataContext of the StickyViewModel, instead. By writing FullName=”{f:StickyBinding Name}” we instruct the StickyViewModel to look for the value it should edit in the Name property of the model the element is bound to.</p>
<p>As usual, the Sticky ViewModel is attached to its base through an attached property:</p>
</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:47a39254-e296-489b-ae95-9bc460ba6d54" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Grid</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Name</span><span style="color:#0000ff;">=&quot;base&quot;</span> <br /> &#160;<span style="color:#ff0000;"> ex</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">NameStickyViewModel.ViewModel</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">DynamicResource</span><span style="color:#ff0000;"> viewModel}</span><span style="color:#0000ff;">&quot;</span> <br /> &#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> HorizontalAlignment</span><span style="color:#0000ff;">=&quot;Stretch&quot;&gt;</span></div>
</p></div>
</p></div>
</p>
<p>In this case, we have to refer to it with a DynamicResource extension, since it is contained in the resources of the element it is used on and thus is referred to before it is declared. We could also put it into the page’s resources and use a StaticResource extension. (StaticResource extensions are less complicated, so they are a little bit safer and faster, but they can only be specified where the definition comes before the reference in the XAML). However, in the example, the NameStickyViewModel is used in a DataTemplate for a ListView. So, every row of the ListView needs its own instance of the Sticky ViewModel, otherwise the names from different rows will start mixing. We can make sure of this either by putting the declaration of the StickyViewModel into the DataTemplate itself, as I have done here, or by setting x:Shared=”False” where we declare it, which tells WPF to create a new instance of a resource every time it is accessed.</p>
<p>The rest of the DataTemplate defines three TextBoxes for each row:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5a310732-f9f7-416e-83aa-7a763913ba01" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> Name</span><span style="color:#0000ff;">,</span><span style="color:#ff0000;"> TargetNullValue</span><span style="color:#0000ff;">=&#39;[New</span><span style="color:#ff0000;"> Customer</span><span style="color:#0000ff;">]&#39;}&quot;</span> <br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Margin</span><span style="color:#0000ff;">=&quot;30,0,0,0&quot;/&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:#ff0000;"> Grid.Column</span><span style="color:#0000ff;">=&quot;1&quot;</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> ElementName</span><span style="color:#0000ff;">=base,</span> <br /> &#160;<span style="color:#ff0000;"> Path</span><span style="color:#0000ff;">=(ex:NameStickyViewModel.ViewModel).</span><span style="color:#ff0000;">LastName}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:#ff0000;"> Grid.Column</span><span style="color:#0000ff;">=&quot;2&quot;</span><span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> ElementName</span><span style="color:#0000ff;">=base,</span> <br /> &#160;<span style="color:#ff0000;"> Path</span><span style="color:#0000ff;">=(ex:NameStickyViewModel.ViewModel).</span><span style="color:#ff0000;">FirstName}</span><span style="color:#0000ff;">&quot;/&gt;</span></div>
</p></div>
</p></div>
<p>The first TextBox is bound directly to the DataContext of the DataTemplate. It refers to the property in the model that contains the full name of a person. The other two TextBoxes are bound to the StickyViewModel that lives on the element named “base”; this element is the Grid from above.</p>
<h4>Implementing the Sticky ViewModel Pattern</h4>
<p>In order to support binding on their properties, Sticky ViewModels are derived from DependencyObject and expose their working properties as DependencyProperties. Configuration properties don’t need to be data bound, so they are defined as normal properties.</p>
<p>Like in the Stateless Sticky ViewModel, after implementing the logic which does what the model should do, the main point is distributing the change notifications from the different properties so that the logic is called at the right time. This happens in the OnPropertyChanged method of the Sticky ViewModel, which is originally defined in DependencyObject:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:54d7e32f-ef08-41b6-a4d3-e2225b678805" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Protected</span> <span style="color:#0000ff;">Overrides</span> <span style="color:#0000ff;">Sub</span> OnPropertyChanged(<span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> System.Windows.DependencyPropertyChangedEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">MyBase</span>.OnPropertyChanged(e)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Static</span> changeInitiator <span style="color:#0000ff;">As</span> DependencyProperty = <span style="color:#0000ff;">Nothing</span></p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> changeInitiator <span style="color:#0000ff;">Is</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;changeInitiator = e.Property</p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Select</span> <span style="color:#0000ff;">Case</span> e.Property.Name<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Case</span> <span style="color:#a31515;">&quot;FullName&quot;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;FirstName = DetermineFirstName(FullName)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;LastName = DetermineLastName(FullName)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Case</span> <span style="color:#a31515;">&quot;FirstName&quot;</span>, <span style="color:#a31515;">&quot;LastName&quot;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;FullName = DetermineFullName(FirstName, LastName)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Select</span></p>
<p> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;changeInitiator = <span style="color:#0000ff;">Nothing</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>Again like in the Stateless Sticky ViewModel, we remember between invocations which property started the change and cancel subsequent invocations of the method. However, this time the code is a little bit shorter and cleaner and not distributed between different methods (I just notice that one could implement it the same way with a Stateless Sticky ViewModel, but alas… never get it perfect the first time.)</p>
<h4>Under the Hood</h4>
<p>The Sticky Component Framework supports the Sticky ViewModel pattern with two components: the StickyViewModel base class, which can be used to derive one’s own Sticky ViewModels, and the StickyBinding, which one needs to be able to bind to the properties of the Sticky ViewModel’s DataContext.</p>
<p>The StickyViewModel class mainly manages attaching and detaching the ViewModel on its base element:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:268fb21c-78f3-4d31-9770-a245b079379a" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Sub</span> OnAttach(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> System.EventArgs) <span style="color:#0000ff;">Implements</span> IStickyComponent.OnAttach<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Me</span>.DataContext = StickyComponentManager.GetDataContext(sender)<br /> &#160;&#160;&#160;&#160;StickyComponentManager.AttachDataContextChanged(sender, <span style="color:#0000ff;">AddressOf</span> _DataContextChanged)<br /> &#160;&#160;&#160;&#160;Attach(sender, e)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></p>
<p> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Sub</span> OnDetach(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> System.EventArgs) <span style="color:#0000ff;">Implements</span> IStickyComponent.OnDetach<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Me</span>.DataContext = <span style="color:#0000ff;">Nothing</span><br /> &#160;&#160;&#160;&#160;StickyComponentManager.DetachDataContextChanged(sender, <span style="color:#0000ff;">AddressOf</span> _DataContextChanged)<br /> &#160;&#160;&#160;&#160;Detach(sender, e)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>It adds a handler to the base’s DataContextChanged event, so that the DataContext stays synchronised with the base’s DataContext. DataContext is a DependencyProperty, so it provides its own change notifications. Furthermore, the class defines a generic ViewModel attached property which can be used in derived classes in order to attach the model to the element.</p>
<p>The StickyBindingExtension basically is a BindingExtension with a reduced set of properties (everything related to input and validation is not needed on the StickyBinding), and in principle delegates all it does to this binding:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fb1ca37f-ab49-4c73-bbd2-10151c74fc39" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Overrides</span> <span style="color:#0000ff;">Function</span> ProvideValue(<span style="color:#0000ff;">ByVal</span> serviceProvider <span style="color:#0000ff;">As</span> System.IServiceProvider) <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> target <span style="color:#0000ff;">As</span> System.Windows.Markup.IProvideValueTarget = serviceProvider.GetService(<span style="color:#0000ff;">GetType</span>(System.Windows.Markup.IProvideValueTarget))<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> target <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> <span style="color:#0000ff;">TypeOf</span> target.TargetProperty <span style="color:#0000ff;">Is</span> DependencyProperty <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> <span style="color:#0000ff;">TypeOf</span> target.TargetObject <span style="color:#0000ff;">Is</span> StickyViewModel <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> dataPath <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">String</span> = <span style="color:#a31515;">&quot;DataContext&quot;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> <span style="color:#0000ff;">Not</span> <span style="color:#0000ff;">String</span>.IsNullOrEmpty(Path) <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> Path.StartsWith(<span style="color:#a31515;">&quot;/&quot;</span>) <span style="color:#0000ff;">Or</span> Path.StartsWith(<span style="color:#a31515;">&quot;[&quot;</span>) <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;dataPath &amp;= Path<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;dataPath &amp;= <span style="color:#a31515;">&quot;.&quot;</span> &amp; Path<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> b <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">New</span> Binding(dataPath)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;b.Source = target.TargetObject<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;b.Mode = Mode<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;b.Converter = Converter<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;b.ConverterCulture = ConverterCulture<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;b.ConverterParameter = ConverterParameter<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> b.ProvideValue(serviceProvider)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> <span style="color:#0000ff;">Me</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span></div>
</p></div>
</p></div>
<p>&#160;</p>
</p>
<p>The trick here is to prefix the binding’s path with the DataContext property and always use the target object as source. Thus, following the principles of WPFGlue, I avoid to implement my own version of change notification listeners and instead use what is already there. Since the DataContext is always synchronized with the the base’s DataContext and provides change notification, the StickyBinding will always be able to find the correct property without any explicit dependencies. </p>
<p>Notice that the last line in the block that creates the binding returns Binding.ProvideValue. This is necessary in order to mimic Binding’s behaviour in all contexts.</p>
<h4>Comparing Stateless and Stateful Sticky ViewModel</h4>
<p>As mentioned before, the main advantage of the Stateful Sticky ViewModel is that it bundles configuration properties in one place and forms a better defined unit than the Stateless version. Its main focus is on the base’s DataContext. Sticky Bindings don’t support binding to properties of elements in the logical tree, as it would be possible with the ElementName or RelativeSource properties of a normal binding. However, if one needs that, one can combine the two patterns and define attached properties on the Sticky ViewModel for no other purpose than to be able to bind them to logical tree elements, and access them through a reference to the base that is acquired during Attach and of course released during Detach.</p>
<h4>Coming Soon…</h4>
<p>The Sticky Component Framework is still once removed from a real application… the next step will be a Commanding Framework based on Sticky Components which allows to define RoutedCommands, their keyboard shortcuts and display texts in one place, delegating their invocations to methods or ICommand implementations in the ViewModel or model.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/105/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=105&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2009/12/16/the-sticky-viewmodel-pattern/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>
	</item>
		<item>
		<title>Using Validation.ErrorTemplate</title>
		<link>http://wpfglue.wordpress.com/2009/12/16/using-validation-errortemplate/</link>
		<comments>http://wpfglue.wordpress.com/2009/12/16/using-validation-errortemplate/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 07:50:43 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[Validation]]></category>
		<category><![CDATA[ErrorTemplate]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://wpfglue.wordpress.com/2009/12/16/using-validation-errortemplate/</guid>
		<description><![CDATA[This was originally published as a thread in the MSDN WPF forum before I started this blog. However, today I revisited the thread and decided to maintain it here, now.. There are a couple of known problems and unknown features with Validation.ErrorTemplate that came up frequently, and I&#8217;d like to collect the workarounds for these [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=101&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This was originally published as a thread in the <a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/threads" target="_blank">MSDN WPF forum</a> before I started this blog. However, today I revisited the thread and decided to maintain it here, now..</p>
<p>There are a couple of known problems and unknown features with Validation.ErrorTemplate that came up frequently, and I&#8217;d like to collect the workarounds for these things in one place. This is how far I got:   </p>
<h4>Problem: The Content of the ErrorTemplate is not displayed correctly</h4>
<p>e.g. the red border doesn&#8217;t fit around the control, or parts of the error template are not drawn. The reason is that there may not be enough space around the control to display the error template, so the solution is to make the margin of the control big enough that the error template can be drawn.   <br /><strong></strong></p>
<h4>Unknown Feature: The DataContext of the ErrorTemplate is the Validation.Errors Collection</h4>
<p>Haven&#8217;t found this in the documentation, but it means that the easiest way to get at an error message in an error template is to use {Binding Path=/ErrorContent}.   <br /><strong></strong></p>
<h4><strong>Problem: Have to Change the Style of a Control in Order to Set the Error Message as ToolTip</strong></h4>
<p>It seems to be impossible to set the ToolTip of a control using Styles or Triggers in the error template. Usually this is worked around by modifying the Style of the control, as in the example from the WPF SDK. However, this has the disadvantage that one has to change the style of the control in order to accommodate Validation, which might interfere with other uses of the Style. There are better workarounds: most elegant by using a ToolTip on some error indicator that is part of the error template, or, if it must be the control itself, using a custom attached property on the AdornedElementPlaceholder like this:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:159e528b-bb97-4c2a-b695-0a76e4eb5bef" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">ReadOnly</span> AdornedElementToolTipProperty <span style="color:#0000ff;">As</span> DependencyProperty = DependencyProperty.RegisterAttached(<span style="color:#a31515;">&quot;AdornedElementToolTip&quot;</span>, <span style="color:#0000ff;">GetType</span>(<span style="color:#0000ff;">Object</span>), <span style="color:#0000ff;">GetType</span>(Validation), <span style="color:#0000ff;">New</span> PropertyMetadata(<span style="color:#0000ff;">Nothing</span>, <span style="color:#0000ff;">AddressOf</span> OnAdornedElementToolTipChanged))<br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Function</span> GetAdornedElementToolTip(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject) <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> d.GetValue(AdornedElementToolTipProperty)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span><br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> SetAdornedElementToolTip(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject, <span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>)<br /> &#160;&#160;&#160;&#160;d.SetValue(AdornedElementToolTipProperty, value)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> <span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> OnAdornedElementToolTipChanged(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> DependencyPropertyChangedEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> placeholder <span style="color:#0000ff;">As</span> AdornedElementPlaceholder = <span style="color:#0000ff;">TryCast</span>(d, AdornedElementPlaceholder)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> placeholder <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> control <span style="color:#0000ff;">As</span> Control = <span style="color:#0000ff;">TryCast</span>(placeholder.AdornedElement, Control)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> control <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;control.ToolTip = e.NewValue<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>One can bind the error message to this property, and this way the error template works without interfering with the control&#8217;s style.    <br /><strong></strong></p>
<h4><strong>Problem: The Error Template is not Displayed when a Page is Loaded</strong></h4>
<p>This is by design, since one could assume that the user doesn&#8217;t want to see error messages before he/she made any mistakes, but sometimes one needs this functionality. So, the ValidatesOnTargetUpdated property was introduced on the ValidationRule class; by setting it to true, one sees the validation result immediately. </p>
<p>However, there is one caveat: you must make sure that you set the DataContext after the page is initialized; this would be either in the constructor after the generated comment line that says that initialization code should go there, or in the Loaded event. If you want to set the DataContext in XAML, you find a solution for this problem here (among other things): <a href="http://wpfglue.wordpress.com/2009/12/08/navigating-from-object-to-object/">http://wpfglue.wordpress.com/2009/12/08/navigating-from-object-to-object/</a></p>
<p>Anyway, I hear this will be fixed in WPF 4.0.   <br /><strong></strong></p>
<h4><strong>Problem: When Using an Expander, the Error Template Remains Visible even if the Expander is Collapsed</strong></h4>
<p>This problem is a known bug, unfortunately as far as I know not yet scheduled for fixing. The workaround (found in the MSDN WPF forum) is binding the Visibility property of the outermost element of the error template to the AdornedElement.IsVisible property of the AdornedElementPlaceholder, using the BooleanToVisibilityConverter that comes with WPF.</p>
<h4></h4>
<h4>Standard Error Template</h4>
<p>So, this would be my standard error template:</p>
<p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:fc961450-e2b9-4d73-8978-12e9c8e30e97" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ControlTemplate</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Key</span><span style="color:#0000ff;">=&quot;errorTemplate&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Border</span><span style="color:#ff0000;"> BorderBrush</span><span style="color:#0000ff;">=&quot;Red&quot;</span><span style="color:#ff0000;"> BorderThickness</span><span style="color:#0000ff;">=&quot;1&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Border.Visibility</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> ElementName</span><span style="color:#0000ff;">=&quot;placeholder&quot;</span><span style="color:#ff0000;"> Path</span><span style="color:#0000ff;">=&quot;AdornedElement.IsVisible&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Binding.Converter</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">BooleanToVisibilityConverter</span><span style="color:#0000ff;">/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Binding.Converter</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Binding</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Border.Visibility</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">StackPanel</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">AdornedElementPlaceholder</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Name</span><span style="color:#0000ff;">=&quot;placeholder&quot;</span> <br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> v</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Validation.AdornedElementToolTip</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> Path</span><span style="color:#0000ff;">=</span>/<span style="color:#0000ff;">ErrorContent}&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Border</span><span style="color:#0000ff;">&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">ControlTemplate</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p> And this would be how I use it:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:db072f32-8a5f-4896-aa5a-40bbbd923a22" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">StackPanel</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Name</span><span style="color:#0000ff;">=&quot;Abox&quot;</span><span style="color:#ff0000;"> Margin</span><span style="color:#0000ff;">=&quot;3&quot;</span><span style="color:#ff0000;"> Validation.ErrorTemplate</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> errorTemplate}</span><span style="color:#0000ff;">&quot;</span> <br /> &#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> Path</span><span style="color:#0000ff;">=A,</span><span style="color:#ff0000;"> UpdateSourceTrigger</span><span style="color:#0000ff;">=PropertyChanged,</span> <br /> &#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> ValidatesOnDataErrors</span><span style="color:#0000ff;">=True}&quot; /&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Expander</span><span style="color:#ff0000;"> Header</span><span style="color:#0000ff;">=&quot;Test&quot;</span><span style="color:#ff0000;"> IsExpanded</span><span style="color:#0000ff;">=&quot;True&quot;</span><span style="color:#ff0000;"> Validation.ErrorTemplate</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">x</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">Null}</span><span style="color:#0000ff;">&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Expander.BindingGroup</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">BindingGroup</span><span style="color:#0000ff;">/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Expander.BindingGroup</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Name</span><span style="color:#0000ff;">=&quot;Bbox&quot;</span><span style="color:#ff0000;"> Margin</span><span style="color:#0000ff;">=&quot;3&quot;</span> <br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Validation.ErrorTemplate</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> errorTemplate}</span><span style="color:#0000ff;">&quot;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Text</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> Path</span><span style="color:#0000ff;">=B,</span><span style="color:#ff0000;"> UpdateSourceTrigger</span><span style="color:#0000ff;">=PropertyChanged,</span> <br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> ValidatesOnDataErrors</span><span style="color:#0000ff;">=True}&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Expander</span><span style="color:#0000ff;">&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/101/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/101/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/101/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=101&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2009/12/16/using-validation-errortemplate/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>
	</item>
		<item>
		<title>The Sticky Component Framework</title>
		<link>http://wpfglue.wordpress.com/2009/12/11/the-sticky-component-framework/</link>
		<comments>http://wpfglue.wordpress.com/2009/12/11/the-sticky-component-framework/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 14:43:34 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Sticky Component]]></category>
		<category><![CDATA[WPFGlue]]></category>

		<guid isPermaLink="false">http://wpfglue.wordpress.com/2009/12/11/the-sticky-component-framework/</guid>
		<description><![CDATA[What is a Sticky Component? A Sticky Component is a component that can be attached to any FrameworkElement or FrameworkContentElement in order to enhance its functionality, without the need to subclass the element or to write code behind for it. Because of this, Sticky Components can be used very effectively to encapsulate specialized behaviours in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=92&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>What is a Sticky Component? A Sticky Component is a component that can be attached to any FrameworkElement or FrameworkContentElement in order to enhance its functionality, without the need to subclass the element or to write code behind for it. Because of this, Sticky Components can be used very effectively to encapsulate specialized behaviours in a reusable way, and to enhance either the View or the ViewModel of an MVVM application without changing its code.</p>
<h4>Sticky Component Interaction Patterns</h4>
<p>In order to enhance the functionality of an element, the Sticky Component needs to interact with the element. There are several possible ways to connect the two:</p>
<ul>
<li>Through registering event handlers: The Sticky Component can subscribe to events of the element it is attached to, and trigger its own functionality through these events. </li>
<li>Through registering CommandBindings: The Sticky Component can add its own CommandBindings to the element’s CommandBindings collection, thus enabling the element to handle the specified command. </li>
<li>Through registering InputBindings: the Sticky Component can enable an element to invoke commands by adding InputBindings to its InputBindings collection. </li>
<li>Through data binding: the Sticky Component can bind its own properties to the properties of the element. These bindings could in principle have the element as target or as source. But since many properties in the WPF framework are readonly, it is less error prone to always make the Sticky Component the binding target by convention. </li>
<li>Through binding to the element’s DataContext: a special class of Sticky Component, the Sticky ViewModel, doesn’t enhance the View, but the ViewModel, by binding to its properties and adding functionality that isn’t present in the ViewModel without the need to change it. </li>
</ul>
<p>Some of these patterns require references between the Sticky ViewModel and the element it is attached to (its “base”). References are dangerous. They may cause memory leaks and unintended behaviour, e.g. if events are handled even if the view that established the event subscription is already out of scope. Therefore, the core of the Sticky Component Framework is concerned with managing the lifetime of a Sticky Component and its interaction patterns so that all these references are cleaned up when appropriate.</p>
<h4>Sticky Component Lifetime</h4>
<p>The life cycle of a Sticky Component looks like follows:</p>
<ul>
<li>It is defined and configured in the Resources of the application, a window, or an individual element. </li>
<li>It is referenced in an attached property on the base element it is attached to. This is the time when the Sticky Component is actually instantiated. </li>
<li>It attaches itself to the base. This can happen either immediately or delayed, depending on whether the base must be in initialized or loaded state before the component can attach to it. </li>
</ul>
<p>The end of the component’s relationship to the base could come in two ways:</p>
<ul>
<li>Either the attached property which connects the component to the base is reset, </li>
<li>or the base itself is unloaded. </li>
</ul>
<p>In both cases, all references between the Sticky Component and its base should be removed, leaving either object ready for garbage collection. If the component still exists after it has been detached from its base (e.g. because it is kept as a shared instance in a ResourceDictionary), it could be attached again to a different base, or even the same, if that still is available.</p>
<p>This lifetime pattern is expressed in the following interface definition:</p>
<div></div>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7fd2c663-734f-47cd-9448-7677df5b4a97" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Enum</span> AttachMode <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span><br /> &#160;&#160;&#160;&#160;Immediate = 0<br /> &#160;&#160;&#160;&#160;OnInitialized = 1<br /> &#160;&#160;&#160;&#160;OnLoaded = 2<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Enum</span></p>
<p> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Interface</span> IStickyComponent</p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Sub</span> OnAttach(<span style="color:#0000ff;">ByVal</span> base <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> EventArgs)</p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Sub</span> OnDetach(<span style="color:#0000ff;">ByVal</span> base <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> EventArgs)</p>
<p> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">ReadOnly</span> <span style="color:#0000ff;">Property</span> Mode() <span style="color:#0000ff;">As</span> AttachMode</p>
<p> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Interface</span></div>
</p></div>
</p></div>
<p>OnAttach will be called whenever the Sticky Component will be attached to a base, OnDetach will be called when it is detached. Both methods have EventHandler signatures, so that they can be invoked by the Initialized, Loaded or Unloaded events, respectively. The Mode property defines when the component should attach itself to the element. If possible, the component should attach itself immediately. However, if it needs to modify existing bindings, it will have to do that during the Initialized event, and if it needs to access properties that are data bound, like e.g. the DataContext of the base, it might have to wait until the Loaded event. Since these requirements depend on what the component does, it would be expected that a class that implements IStickyComponent would return a constant value here.</p>
<h4>The StickyComponentManager</h4>
<p>The StickyComponentManager is a static class that encapsulates the different ways to establish and remove interaction connections between a Sticky Component and its base. It offers overloaded Attach and Detach procedures in pairs with corresponding parameters. So, one would attach an event to a base using the Attach(base,event,handler) overload, and remove it again using the Detach(base, event,handler) overload. There are overloads for all cases discussed here; some of these overloads offer additional services; e.g. there are overloads for attaching event handlers which automatically remove the event handler after it has fired once (using the One Shot Event pattern), or if another specified event occurs before the event that the handler is supposed to handle.</p>
<p>In your Sticky Component, you would set up the connection to the base by calling the appropriate Attach methods of the StickyComponentManager in your OnAttach implementation, and remove the connection by calling the corresponding Detach methods in the OnDetach implementation.</p>
<p>The most important overloads of these methods are the ones that attach / detach Sticky Components. There is a special implementation of a DependencyPropertyChangedHandler that you can use with your attached properties that attach Sticky Components which calls these overloads:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8ac70815-e0d7-4b6b-92df-888332ae1d34" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> OnStickyComponentChanged(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> DependencyPropertyChangedEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> c <span style="color:#0000ff;">As</span> IStickyComponent<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> e.OldValue <span style="color:#0000ff;">IsNot</span> e.NewValue <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;c = <span style="color:#0000ff;">TryCast</span>(e.OldValue, IStickyComponent)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> c <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Detach(d, c)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;c = <span style="color:#0000ff;">TryCast</span>(e.NewValue, IStickyComponent)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> c <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Attach(d, c)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
</p>
<p>This will ensure that the lifetime of the sticky component is managed according to the life cycle described above.</p>
<p>In addition to the Attach and Detach methods, the StickyComponentManager contains several utility methods which hide the difference between FrameworkElement and FrameworkContentElement when attaching Sticky Components. So, elements derived from both of these classes could be the base for Sticky Components; on other elements, the Attach / Detach methods would simply do nothing.</p>
<h4>Using Sticky Components</h4>
<p>In XAML, you would normally declare and configure a Sticky Component in a Resources section, like this:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:009c412a-dc78-4fc6-a541-04cf23f2ae17" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;">&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ex</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">TestStickyPatterns</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Key</span><span style="color:#0000ff;">=&quot;UseEvents&quot;</span> <br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> Name</span><span style="color:#0000ff;">=&quot;UseEvents&quot;</span><span style="color:#ff0000;"> UseCommand</span><span style="color:#0000ff;">=&quot;False&quot;/&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Page.Resources</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p>This would define a Sticky Component of class TestStickyPatterns and configure it by setting its Name and UseCommand properties.</p>
<p>You would then use it on a base element like this:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8af98e23-9bfe-41e1-a196-9d4be6bafbb3" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;</span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Button</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Name</span><span style="color:#0000ff;">=&quot;TestEventPatternsButton&quot;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#ff0000;"> ex</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">TestStickyPatterns.Component</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:#ff0000;"> UseEvents}</span><span style="color:#0000ff;">&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;">Test Event Patterns</span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Button</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>If you need the Sticky Component more than once on your page, consider setting the x:Shared attribute to false on its declaration. Thus you make sure that each time the component is used, you start with a fresh instance. Otherwise it could happen that the component is attached to multiple elements on your page at the same time, with unwelcome results.</p>
<h4>Implementing Sticky Components</h4>
<p>The TestStickyPatterns.Component attached property would be defined like this:</p>
<p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ba79282e-1572-4901-9e1d-0a93936ce20d" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">ReadOnly</span> ComponentProperty <span style="color:#0000ff;">As</span> DependencyProperty = _<br /> &#160;&#160;&#160;&#160;DependencyProperty.RegisterAttached(<span style="color:#a31515;">&quot;Component&quot;</span>, _<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">GetType</span>(IStickyComponent), <span style="color:#0000ff;">GetType</span>(StickyTestComponent), _<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">New</span> PropertyMetadata(<span style="color:#0000ff;">AddressOf</span> StickyComponentManager.OnStickyComponentChanged))<br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Function</span> GetComponent(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject) <span style="color:#0000ff;">As</span> IStickyComponent<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> d.GetValue(ComponentProperty)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span><br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> SetComponent(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject, _<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> IStickyComponent)<br /> &#160;&#160;&#160;&#160;d.SetValue(ComponentProperty, value)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
</p>
<p>Notice that the property metadata refers to the shared (static in C#) method StickyComponentManager.OnStickyComponentChanged in order to enable lifecycle management for the component.</p>
<p>Its OnAttach and OnDetach implementations look as follows:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8ed622c1-0bea-4476-8f21-9d789a1f8244" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Sub</span> OnAttach(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> EventArgs) <span style="color:#0000ff;">Implements</span> IStickyComponent.OnAttach<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">MyBase</span>.OnAttach(sender, e)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> _UseCommand <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Attach(sender, MyCommand, <span style="color:#0000ff;">AddressOf</span> OnExecuted, <span style="color:#0000ff;">Nothing</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Attach(sender, <span style="color:#0000ff;">New</span> KeyGesture(Key.Space, ModifierKeys.Control), MyCommand)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Attach(sender, ButtonBase.ClickEvent, <span style="color:#0000ff;">AddressOf</span> OnClick)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Attach(sender, ButtonBase.ClickEvent, <span style="color:#0000ff;">AddressOf</span> OnClickOneShot, <span style="color:#0000ff;">True</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Attach(sender, ButtonBase.ClickEvent, <span style="color:#0000ff;">AddressOf</span> OnClickCancel, FocusManager.LostFocusEvent)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></p>
<p> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Sub</span> OnDetach(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> EventArgs) <span style="color:#0000ff;">Implements</span> IStickyComponent.OnDetach<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">MyBase</span>.OnDetach(sender, e)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> _UseCommand <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Detach(sender, <span style="color:#0000ff;">New</span> KeyGesture(Key.Space, ModifierKeys.Control))<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Detach(sender, MyCommand)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Detach(sender, ButtonBase.ClickEvent, <span style="color:#0000ff;">AddressOf</span> OnClick)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Detach(sender, ButtonBase.ClickEvent, <span style="color:#0000ff;">AddressOf</span> OnClickOneShot)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.Detach(sender, ButtonBase.ClickEvent, <span style="color:#0000ff;">AddressOf</span> OnClickCancel)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<h4>Grouping Sticky Components</h4>
<p>Since the idea in using Sticky Components is that their behaviour is very narrow and specialized, so that they are suitable for many different contexts, there is a need to be able to group Sticky Components and attach a whole group at once to the same base element. The Sticky Component Framework contains a generic collection to help with that: StickyComponentCollection(Of T as IStickyComponent). This collection attaches and detaches its items at the right times, provides change notification, and if you implement the INamedStickyComponent interface on the collection’s items, you even can refer to the components inside the collection using string indexers in XAML. Here is an example of the use of this collection:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7069d74c-84d2-4bba-a2e5-775452146349" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Page.Resources</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ex</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">StickyTestComponentSet</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Key</span><span style="color:#0000ff;">=&quot;test2&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ex</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">StickyTestComponent</span><span style="color:#ff0000;"> Name</span><span style="color:#0000ff;">=&quot;Page Immediate&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ex</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">StickyTestComponent</span><span style="color:#ff0000;"> Name</span><span style="color:#0000ff;">=&quot;Page OnInitialized&quot;</span><span style="color:#ff0000;"> AttachMode</span><span style="color:#0000ff;">=&quot;OnInitialized&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ex</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">StickyTestComponent</span><span style="color:#ff0000;"> Name</span><span style="color:#0000ff;">=&quot;Page OnLoaded&quot;</span><span style="color:#ff0000;"> AttachMode</span><span style="color:#0000ff;">=&quot;OnLoaded&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">ex</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">StickyTestComponentSet</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>StickyTestComponentSet is defined by inheriting a concrete type instance of the generic collection:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:48893996-e245-4d0c-bf96-ced5bb1e445a" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Class</span> StickyTestComponentSet<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Inherits</span> StickyComponentCollection(<span style="color:#0000ff;">Of</span> StickyTestComponent)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Implements</span> IStickyComponent, IList</div>
</p></div>
</p></div>
<p>&#160;</p>
<p>Notice that for some reason the Visual Studio XAML designer (Cider) will only let you add direct content to the class if you specify “Implements IList” again, even though this interface is already implemented by the base class.</p>
<h4>The StickyComponent Example</h4>
<p>On the <a title="Downloads" href="http://wpfglue.wordpress.com/downloads/">Downloads page</a> you will find the source code for the framework and an example project called StickyComponentExample. This project mainly focuses on demonstrating the different interaction techniques between StickyComponents, their usage patterns, and their life cycle. In order to trace the life cycle, a lot of debug output is written to Debug.Print, so you should run the project in the Visual Studio Debugger and follow the output in the Immediate window.</p>
<h4>Coming Soon…</h4>
<p>There is one special case of a Sticky Component: the Sticky ViewModel. It deserves special attention, and even though the example is already in the example solution, I’d like to cover it in a separate post.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7d2cb1e1-77f5-443e-81d6-03b76a8edc0f" class="wlWriterEditableSmartContent">Technorati-Tags: <a href="http://technorati.com/tags/MVVM" rel="tag">MVVM</a>,<a href="http://technorati.com/tags/WPF" rel="tag">WPF</a>,<a href="http://technorati.com/tags/Framework" rel="tag">Framework</a>,<a href="http://technorati.com/tags/WPFGlue" rel="tag">WPFGlue</a>,<a href="http://technorati.com/tags/design+pattern" rel="tag">design pattern</a></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/92/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=92&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2009/12/11/the-sticky-component-framework/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>
	</item>
		<item>
		<title>The Last Word on Localized Resources in WPF</title>
		<link>http://wpfglue.wordpress.com/2009/12/08/the-last-word-on-localized-resources-in-wpf/</link>
		<comments>http://wpfglue.wordpress.com/2009/12/08/the-last-word-on-localized-resources-in-wpf/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 19:47:21 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[Localization]]></category>

		<guid isPermaLink="false">http://wpfglue.wordpress.com/2009/12/08/the-last-word-on-localized-resources-in-wpf/</guid>
		<description><![CDATA[After finishing my last post on using localized resources in WPF, I had the following idea, which I should have included from the start: If you want to maintain your resources in a more WPF-ish and less WinForms-ish way, just do this: &#60;Window x:Class=&#34;Window1&#34; &#160;&#160;&#160; xmlns=&#34;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#34; &#160;&#160;&#160; xmlns:x=&#34;http://schemas.microsoft.com/winfx/2006/xaml&#34; &#160;&#160;&#160; xmlns:l=&#34;http://wpfglue.wordpress.com/localization&#34; &#160;&#160;&#160; Title=&#34;Window1&#34; Height=&#34;300&#34; Width=&#34;300&#34;&#62; &#160;&#160;&#60;Window.Resources&#62; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=91&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>After finishing my last post on <a href="http://wpfglue.wordpress.com/2009/12/05/using-net-localized-string-resources-in-wpf/">using localized resources in WPF</a>, I had the following idea, which I should have included from the start:</p>
<p>If you want to maintain your resources in a more WPF-ish and less WinForms-ish way, just do this:</p>
<p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a253c2ac-b5b4-43a8-9487-b7bfe0c71d4f" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Window</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Class</span><span style="color:#0000ff;">=&quot;Window1&quot;</span><br /> &#160;&#160;&#160;<span style="color:#ff0000;"> xmlns</span><span style="color:#0000ff;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span><br /> &#160;&#160;&#160;<span style="color:#ff0000;"> xmlns</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">x</span><span style="color:#0000ff;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><br /> &#160;&#160;&#160;<span style="color:#ff0000;"> xmlns</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">l</span><span style="color:#0000ff;">=&quot;http://wpfglue.wordpress.com/localization&quot;</span><br /> &#160;&#160;&#160;<span style="color:#ff0000;"> Title</span><span style="color:#0000ff;">=&quot;Window1&quot;</span><span style="color:#ff0000;"> Height</span><span style="color:#0000ff;">=&quot;300&quot;</span><span style="color:#ff0000;"> Width</span><span style="color:#0000ff;">=&quot;300&quot;&gt;</span><br /> &#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Window.Resources</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ResourceDictionary</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ResourceDictionary.MergedDictionaries</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">ResourceDictionary</span><span style="color:#ff0000;"> Source</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">l</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">URI</span><span style="color:#ff0000;"> MyUriToLocalizedDictionaries}</span><span style="color:#0000ff;">&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">ResourceDictionary.MergedDictionaries</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">ResourceDictionary</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Window.Resources</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p> Set up your localized resource satellite assemblies like described in the other post, but don’t put anything into them except the pack URI’s of your localized dictionary in the respective language. This way, you can include every type of resource that’s available in WPF, don’t have any WinForms dependencies, and still have the standard .Net way of selecting the right localized resources. You can maintain the consistency of the dictionaries using a normal diff tool, and are no longer annoyed by the Visual Studio resource designer’s bad habit of interrupting your typing while auto-saving and swallowing what you just typed if you are not lucky.</p>
<p>On the downside, however, all localized resources will be part of your main assembly, either directly or by reference, and it is less convenient to add support for new languages, except if you decide to store the resource dictionaries as uncompiled Content files.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/91/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/91/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/91/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=91&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2009/12/08/the-last-word-on-localized-resources-in-wpf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>
	</item>
		<item>
		<title>Navigating from Object to Object</title>
		<link>http://wpfglue.wordpress.com/2009/12/08/navigating-from-object-to-object/</link>
		<comments>http://wpfglue.wordpress.com/2009/12/08/navigating-from-object-to-object/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 16:52:29 +0000</pubDate>
		<dc:creator>hbarck</dc:creator>
				<category><![CDATA[Navigation]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[GoToPage]]></category>
		<category><![CDATA[OneShotEvent]]></category>
		<category><![CDATA[Sticky Command]]></category>
		<category><![CDATA[Sticky Component]]></category>
		<category><![CDATA[XAML only]]></category>

		<guid isPermaLink="false">http://wpfglue.wordpress.com/2009/12/08/navigating-from-object-to-object/</guid>
		<description><![CDATA[WPF offers a whole application paradigm based on navigation: The Navigation Application, hosted in a NavigationWindow, Frame or WebBrowser; consisting of XAML pages which are independent of each other; keeping track of the navigation history and restoring pages and their values while going forwards and backwards are supported out of the box. However, some things [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=87&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>WPF offers a whole application paradigm based on navigation: The Navigation Application, hosted in a NavigationWindow, Frame or WebBrowser; consisting of XAML pages which are independent of each other; keeping track of the navigation history and restoring pages and their values while going forwards and backwards are supported out of the box.</p>
<p>However, some things are lacking. Suppose you have a data object model. In your application, you want to be able to select an object from a list, then click on a link to open a new page and edit the details of the object. When you are done, you want to select another object, and&#160; when you have repeated this a couple of times, you want to be able to go backwards using the back button, returning to the objects you edited on each page.</p>
<p>What is the problem here? WPF offers no built-in way to pass an object from one page to the other using XAML only. This has consequences. If you use the approach suggested in the WPF documentation, you will have to instantiate a new page object, pass the object you want to edit to its constructor, and navigate to it using the NavigationService.Navigate(Object) overload. However, pages which are navigated to this way are not disposed when they are no longer displayed, but retained in memory as a whole, and this has some side effects which I already talked about in <a href="http://wpfglue.wordpress.com/2009/11/10/wpfglue-navigation/">this</a> post.</p>
<p>So, what can we do about it?</p>
<h4>The GoToPage Sticky Command</h4>
<p>A sticky command is a command binding that is attachable to any XAML element and adds a certain functionality to this element without changing its code.</p>
<p>The GoToPage navigation command was one of my first experiments with the WPFGlue programming style. Since then, I have learned a few things and changed it considerably. One of the changes being that now the command which is the navigation command is no longer hardcoded, but could be any routed command which is configured to use the Navigation command implementation. This is how you use it:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:33c22331-7b9f-45f9-80d8-f801b23e5ffc" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">NavigationWindow</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Class</span><span style="color:#0000ff;">=&quot;Window1&quot;</span><br /> &#160;&#160;&#160;<span style="color:#ff0000;"> xmlns</span><span style="color:#0000ff;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span><br /> &#160;&#160;&#160;<span style="color:#ff0000;"> xmlns</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">x</span><span style="color:#0000ff;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><br /> &#160;&#160;&#160;<span style="color:#ff0000;"> xmlns</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">n</span><span style="color:#0000ff;">=&quot;http://wpfglue.wordpress.com/navigation&quot;</span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br /> &#160;&#160;&#160;<span style="color:#ff0000;"> Title</span><span style="color:#0000ff;">=&quot;NavigationExample&quot;</span><span style="color:#ff0000;"> Height</span><span style="color:#0000ff;">=&quot;300&quot;</span><span style="color:#ff0000;"> Width</span><span style="color:#0000ff;">=&quot;300&quot;</span> <br /> &#160;&#160;&#160;<span style="color:#ff0000;"> n</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Navigation.Command</span><span style="color:#0000ff;">=&quot;GoToPage&quot;</span><span style="color:#ff0000;"> Source</span><span style="color:#0000ff;">=&quot;ListPage.xaml&quot;/&gt;</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>By setting the Navigation.Command attached property on the NavigationWindow to the WPF GoToPage command, you enable all pages that the NavigationWindow hosts to use this command in order to navigate to other pages and pass along objects as DataContext for the new page.</p>
<p>In the page, you would use the command like this:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:db8d323e-4d4a-4ac2-a3ef-81a183b4695d" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Button</span><span style="color:#ff0000;"> x</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Name</span><span style="color:#0000ff;">=&quot;EditButton&quot;</span> <br /> &#160;&#160;<span style="color:#ff0000;"> DataContext</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding</span><span style="color:#ff0000;"> ElementName</span><span style="color:#0000ff;">=ItemListView,</span><span style="color:#ff0000;"> Path</span><span style="color:#0000ff;">=SelectedItem}&quot;</span> <br /> &#160;&#160;<span style="color:#ff0000;"> Command</span><span style="color:#0000ff;">=&quot;GoToPage&quot;</span><span style="color:#ff0000;"> CommandParameter</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">Binding}</span><span style="color:#0000ff;">&quot;</span> <br /> &#160;&#160;<span style="color:#ff0000;"> n</span><span style="color:#0000ff;">:</span><span style="color:#ff0000;">Navigation.Uri</span><span style="color:#0000ff;">=&quot;DetailPage.xaml&quot;&gt;</span></div>
</p></div>
</p></div>
<p>This button uses the selected item of a ListView as its DataContext. If clicked, it invokes the GoToPage command (set to its Command property) The selected item is bound to the CommandParameter property, which means that it will be passed as parameter to the GoToPage command. Finally, the URL of the page that should be navigated to is configured through the Navigation.Uri attached property.</p>
<h4>How Does It Work?</h4>
<p>The Navigation.Command property is a sticky property: in its change handler, it attaches a CommandBinding with the code that calls the Navigation command to the element it is set on:</p>
<p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a96b92ec-4ee1-4cde-957e-556766a1ac1d" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">ReadOnly</span> CommandProperty <span style="color:#0000ff;">As</span> DependencyProperty = DependencyProperty.RegisterAttached(<span style="color:#a31515;">&quot;Command&quot;</span>, <span style="color:#0000ff;">GetType</span>(RoutedCommand), <span style="color:#0000ff;">GetType</span>(Navigation), <span style="color:#0000ff;">New</span> PropertyMetadata(<span style="color:#0000ff;">AddressOf</span> OnCommandChanged))<br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Function</span> GetCommand(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject) <span style="color:#0000ff;">As</span> RoutedCommand<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> d.GetValue(CommandProperty)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span><br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> SetCommand(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject, <span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> RoutedCommand)<br /> &#160;&#160;&#160;&#160;d.SetValue(CommandProperty, value)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> <span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> OnCommandChanged(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> DependencyPropertyChangedEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> e.OldValue <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Detach(d, e.OldValue)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> e.NewValue <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Attach(d, e.NewValue)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> <span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> OnUnloaded(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> RoutedEventArgs)<br /> &#160;&#160;&#160;&#160;SetCommand(sender, <span style="color:#0000ff;">Nothing</span>)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
</p>
<p>This code follows a pattern that is typical for Sticky Components; I want to introduce them in more detail later, but we are going to encounter their patterns continuously here, so I want to point it out:</p>
<p>A Sticky Component needs to be able to clean up after itself. So, there are two procedures, Attach and Detach. The Attach method connects the sticky component by setting up CommandBindings or event handlers, the Detach method removes all these references between the Sticky Component and its hosting element. So, the Detach procedure needs to be called in two cases: either if the Sticky Component is removed from the element, or if the element is unloaded. So, the common pattern for Sticky Components is to call Detach when a Sticky Component is replaced on an element, and to reset the attached property that controls the Sticky Component in the element’s Unloaded event.</p>
<h4>Navigation Flow Control</h4>
<p>This is the method that finally gets called when the GoToPage command is invoked:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f25819d4-3da2-46bc-aaf3-6d57b4e95f76" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Function</span> Navigate(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> target <span style="color:#0000ff;">As</span> Uri, <span style="color:#0000ff;">ByVal</span> data <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>) <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Boolean</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> result <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Boolean</span> = <span style="color:#0000ff;">False</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> service <span style="color:#0000ff;">As</span> NavigationService = GetNavigationService(sender)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> service <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">AddHandler</span> service.LoadCompleted, <span style="color:#0000ff;">AddressOf</span> SetDataContextHandler<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;result = service.Navigate(target, data)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> result<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span></div>
</p></div>
</p></div>
<p>It uses the NavigationService.Navigate(Uri,Object) overloaded method, which allows to pass additional data into the navigation process. This additional data is the object that the user selected, and that was passed to the GoToPage command as parameter. The NavigationService will hold on to this object while the pages are changed. When the new page is loaded, we want to set the pages DataContext to the object, so we register a handler for the NavigationService’s LoadCompleted event.</p>
<p>The handler looks like this:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0b1099f2-bd97-41e9-ad7a-963558c67017" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> SetDataContextHandler(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> System.Windows.Navigation.NavigationEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> service <span style="color:#0000ff;">As</span> NavigationService = GetNavigationService(e.Navigator)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> service <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">RemoveHandler</span> service.LoadCompleted, <span style="color:#0000ff;">AddressOf</span> SetDataContextHandler<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> data <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span> = e.ExtraData<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> data <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> <span style="color:#0000ff;">TypeOf</span> e.Content <span style="color:#0000ff;">Is</span> DependencyObject <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;SetDataContext(e.Content, data)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">AddHandler</span> service.Navigating, <span style="color:#0000ff;">AddressOf</span> SaveDataContextHandler<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>Notice that the first thing this procedure does is to unregister itself from the LoadCompleted event. This is because there is no guarantee that all navigation in the application will use our command. This handler makes sense only if the ExtraData of the NavigationEventArgs really contains an object which should be set to the DataContext of the new page. Thus, we register it specifically for this case, and unregister it immediately after use. I call this design pattern a “One Shot Event”.</p>
<p>Then, we set the DataContext of the new page. By the time the event occurs, this page can be found in the Content property of the NavigationEventArgs. However, we cannot set its DataContext directly: WPF is quite particular about when exactly during the lifetime of a page the DataContext is set; some validation features will not work properly if it is set too early, so we define a special attached behaviour that waits until the new page’s Loaded event occurs and then sets the DataContext:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c573e249-b01e-4c20-89c3-e47ba0ea7931" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">ReadOnly</span> DataContextProperty <span style="color:#0000ff;">As</span> DependencyProperty = _<br /> &#160;&#160;&#160;&#160;DependencyProperty.RegisterAttached(<span style="color:#a31515;">&quot;DataContext&quot;</span>, <span style="color:#0000ff;">GetType</span>(<span style="color:#0000ff;">Object</span>), _<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">GetType</span>(Navigation), <span style="color:#0000ff;">New</span> PropertyMetadata(<span style="color:#0000ff;">Nothing</span>, <span style="color:#0000ff;">AddressOf</span> OnDataContextChanged))<br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Function</span> GetDataContext(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject) <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Return</span> d.GetValue(DataContextProperty)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Function</span><br /> <span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> SetDataContext(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject, <span style="color:#0000ff;">ByVal</span> value <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>)<br /> &#160;&#160;&#160;&#160;d.SetValue(DataContextProperty, value)<br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> <span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> OnDataContextChanged(<span style="color:#0000ff;">ByVal</span> d <span style="color:#0000ff;">As</span> DependencyObject, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> DependencyPropertyChangedEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> e.NewValue <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> StickyComponentManager.GetIsLoaded(d) <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;d.Dispatcher.Invoke(System.Delegate.CreateDelegate(<span style="color:#0000ff;">GetType</span>(Navigation), <span style="color:#0000ff;">Nothing</span>, <span style="color:#a31515;">&quot;OnDataContextLoaded&quot;</span>), d, <span style="color:#0000ff;">Nothing</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.AttachEvent(d, FrameworkElement.LoadedEvent, <span style="color:#0000ff;">AddressOf</span> OnDataContextLoaded)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span><br /> <span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> OnDataContextLoaded(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> RoutedEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> d <span style="color:#0000ff;">As</span> DependencyObject = <span style="color:#0000ff;">TryCast</span>(sender, DependencyObject)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> d <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StickyComponentManager.DetachEvent(d, FrameworkElement.LoadedEvent, <span style="color:#0000ff;">AddressOf</span> OnDataContextLoaded)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> data <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span> = GetDataContext(d)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;d.SetValue(FrameworkElement.DataContextProperty, data)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;d.ClearValue(DataContextProperty)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>Notice that the handler for the Loaded event not only removes itself from the page, but also resets the attached property that held on to the DataContext so as to leave no references to this object in places where they are not expected.</p>
<p>We want to be able to return to the page and still see the same object as DataContext. So, we need to save the DataContext to the Journal when the page is about to be left. This is where it gets tricky (again). The method to add custom information to the Journal is to implement a class that inherits from CustomContentState and set it to the CustomContentState property of the NavigatingCancelEventArgs that are passed into the NavigationService.Navigating event when the user tries to navigate away from the current page. However, CustomContentState objects are not stored as object references, but in serialized format, being deserialized as they are needed. This means that our DataContext would be serialized as well, making it impossible to return to the same instance. In order to work around this, we save the DataContext to a shared Session object in the background, and retain only an integer index, which can be serialized easily, while allowing us to retrieve the object later:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:acdbccd6-8c55-4911-b152-2db15cac4aaf" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> SaveDataContextHandler(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> System.Windows.Navigation.NavigatingCancelEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> service <span style="color:#0000ff;">As</span> NavigationService = GetNavigationService(e.Navigator)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> service <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">RemoveHandler</span> service.Navigating, <span style="color:#0000ff;">AddressOf</span> SaveDataContextHandler<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> <span style="color:#0000ff;">Not</span> e.Cancel <span style="color:#0000ff;">AndAlso</span> <span style="color:#0000ff;">TypeOf</span> service.Content <span style="color:#0000ff;">Is</span> DependencyObject <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> content <span style="color:#0000ff;">As</span> DependencyObject = service.Content<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> data <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span> = content.GetValue(FrameworkElement.DataContextProperty)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> data <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> id <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Integer</span> = GetDataContextId(content)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;id = Session.StoreReference(id, data)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> state <span style="color:#0000ff;">As</span> NavigationContentState = <span style="color:#0000ff;">New</span> NavigationContentState(id, e.ContentStateToSave)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;e.ContentStateToSave = state<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<p>Since we don’t want to keep the DataContext object alive longer than its object model supposes it is alive, the Session object uses WeakReferences for storing the DataContext.</p>
<p>When the user navigates back to the page, the CustomContentState’s Replay method is called. In this method, the DataContext is retrieved from the Session object and put into the new page’s DataContext property, using the same method as before. Since we cannot use a CustomContentState more than once, we also have to set up the handling of the Navigating event again, so that the DataContext is saved again when the page is left.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4163fe89-8352-4311-8d46-29bc793faa78" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Public</span> <span style="color:#0000ff;">Overrides</span> <span style="color:#0000ff;">Sub</span> Replay(<span style="color:#0000ff;">ByVal</span> navigationService <span style="color:#0000ff;">As</span> System.Windows.Navigation.NavigationService, <span style="color:#0000ff;">ByVal</span> mode <span style="color:#0000ff;">As</span> System.Windows.Navigation.NavigationMode)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> _OriginalState <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;_OriginalState.Replay(navigationService, mode)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> _DataContextId &lt;&gt; -1 <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> content <span style="color:#0000ff;">As</span> DependencyObject = <span style="color:#0000ff;">TryCast</span>(navigationService.Content, DependencyObject)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> content <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> data <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span> = Session.RetrieveReference(_DataContextId)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> data <span style="color:#0000ff;">Is</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;SetIsExpired(content, <span style="color:#0000ff;">True</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;WPFGlue.Validation.Validation.SetSuppressErrorTemplate(content, <span style="color:#0000ff;">True</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">Else</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;SetDataContext(content, data)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;SetDataContextId(content, _DataContextId)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">AddHandler</span> navigationService.Navigating, <span style="color:#0000ff;">AddressOf</span> SaveDataContextHandler<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<h4>&#160;</h4>
<h4>Handling Expired Content</h4>
<p>But what if the object that was the DataContext has be freed since the user last visited the page?</p>
<p>Handling this case gracefully almost drove me crazy. What I <strong>wanted</strong> to do was to navigate backwards one step and to clear the forward navigation stack so that the user couldn’t navigate to the page again. But I found no way of doing this that would work with all cases I wanted to cover: the API of the Journal is just too narrow. So, what I <strong>ended up</strong> doing was simply disabling the page and displaying a big fat Adorner on top of it, telling the user to go away and not come back&#8230; The Adorner can be styled using a ControlTemplate, a little bit like the Validation.ErrorTemplate, so you can make it less obnoxious; if anyone can tell me how to achieve what I originally wanted to do, I’ll be forever grateful.</p>
<h4>Disabling the GoToPage Command</h4>
<p>In the example, it makes no sense to try to go to the details page if no object is selected in the list. In cases like this, it is possible to disable the GoToPage command by setting the Navigation.CanNavigate property on the element that invokes the command. This can be done through a trigger, like in the example:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2a69b63e-7166-4a20-ab5f-b51d7a8367ca" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Style</span><span style="color:#ff0000;"> TargetType</span><span style="color:#0000ff;">=&quot;Button&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Style.Triggers</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Trigger</span><span style="color:#ff0000;"> Property</span><span style="color:#0000ff;">=&quot;DataContext&quot;</span><span style="color:#ff0000;"> Value</span><span style="color:#0000ff;">=&quot;{</span><span style="color:#a31515;">x</span><span style="color:#0000ff;">:</span><span style="color:#a31515;">Null}</span><span style="color:#0000ff;">&quot;&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;</span><span style="color:#a31515;">Setter</span><span style="color:#ff0000;"> Property</span><span style="color:#0000ff;">=&quot;n:Navigation.CanNavigate&quot;</span><span style="color:#ff0000;"> Value</span><span style="color:#0000ff;">=&quot;False&quot;/&gt;</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Trigger</span><span style="color:#0000ff;">&gt;</span><br /> &#160;&#160;&#160;&#160;<span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Style.Triggers</span><span style="color:#0000ff;">&gt;</span><br /> <span style="color:#a31515;"></span><span style="color:#0000ff;">&lt;/</span><span style="color:#a31515;">Style</span><span style="color:#0000ff;">&gt;</span></div>
</p></div>
</p></div>
<p>Or it could be done by binding this property to a property in a ViewModel.</p>
<h4>Blocking Navigation Completely</h4>
<p>Sometimes, it might be necessary to block navigation completely. On the details page, there is a ValidationRule that demands that the Name property contains a value. By binding the Navigation.BlockNavigation property to Validation.HasError on the Page element, one can disable all navigation away from the page until this property is filled. In order to support this behaviour, the following event handler is attached to the NavigationService.Navigating event:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0f177db2-9c25-4c02-a9f9-1e73451c0b12" class="wlWriterEditableSmartContent">
<div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;">
<div style="background-color:#ffffff;overflow:auto;white-space:nowrap;padding:2px 5px;"><span style="color:#0000ff;">Private</span> <span style="color:#0000ff;">Shared</span> <span style="color:#0000ff;">Sub</span> BlockNavigationHandler(<span style="color:#0000ff;">ByVal</span> sender <span style="color:#0000ff;">As</span> <span style="color:#0000ff;">Object</span>, <span style="color:#0000ff;">ByVal</span> e <span style="color:#0000ff;">As</span> System.Windows.Navigation.NavigatingCancelEventArgs)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">Dim</span> service <span style="color:#0000ff;">As</span> NavigationService = GetNavigationService(sender)<br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> service <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> service.Content <span style="color:#0000ff;">IsNot</span> <span style="color:#0000ff;">Nothing</span> <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;e.Cancel = GetBlockNavigation(service.Content)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#008000;">&#39;Allow Fragment navigation</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">If</span> e.Cancel <span style="color:#0000ff;">And</span> Uri.Compare(service.CurrentSource, service.Source, UriComponents.PathAndQuery, UriFormat.UriEscaped, StringComparison.InvariantCulture) = 0 <span style="color:#0000ff;">Then</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;e.Cancel = <span style="color:#0000ff;">False</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> &#160;&#160;&#160;&#160;<span style="color:#0000ff;">End</span> <span style="color:#0000ff;">If</span><br /> <span style="color:#0000ff;">End</span> <span style="color:#0000ff;">Sub</span></div>
</p></div>
</p></div>
<p>&#160;</p>
<h4>Testing the Component</h4>
<p>You will find the example application NavigationExample in the WPFGluePublished solution on the <a title="Downloads" href="http://wpfglue.wordpress.com/downloads/">Downloads page</a>. In this example, each page contains a “GC” button which forces the .Net garbage collection. By running the example in the debugger and following the debug output, you can see the lifetime events of the pages, and by forcing the garbage collection you can verify that the page objects get finalized when they are no longer needed, thus proving that the Navigation.Command didn’t leave behind any dangling references and doesn’t cause any memory leaks.</p>
<p>By adding some customers, editing their details, removing them, and going back using the NavigationWindow’s Back button, you can test the behaviour for pages whose DataContext has expired.</p>
<h4>Conclusion</h4>
<p>This example shows how it is possible to pass objects from page to page using XAML only, and how one can handle forwards and backwards navigation using object references. However, there are still some limitations: I don’t really like displaying expired pages, and since the Session object uses weak references, it might not be suitable for partial trust scenarios where there is no permission to execute unmanaged code.</p>
<p>In posts to come, I want to explore the possibilities of defining a navigation topology as a central resource. However, for this I will need the complete Sticky Component Framework, about which I will write as soon as possible…</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/wpfglue.wordpress.com/87/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/wpfglue.wordpress.com/87/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/wpfglue.wordpress.com/87/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/wpfglue.wordpress.com/87/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/wpfglue.wordpress.com/87/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/wpfglue.wordpress.com/87/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/wpfglue.wordpress.com/87/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/wpfglue.wordpress.com/87/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/wpfglue.wordpress.com/87/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/wpfglue.wordpress.com/87/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/wpfglue.wordpress.com/87/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/wpfglue.wordpress.com/87/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/wpfglue.wordpress.com/87/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/wpfglue.wordpress.com/87/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=wpfglue.wordpress.com&amp;blog=10283374&amp;post=87&amp;subd=wpfglue&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://wpfglue.wordpress.com/2009/12/08/navigating-from-object-to-object/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/ef0b2a44dce8747a7e5449b44387034e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">hbarck</media:title>
		</media:content>
	</item>
	</channel>
</rss>
