<?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/"
	>

<channel>
	<title>zdima.net &#187; XAML</title>
	<atom:link href="http://zdima.net/blog/archives/tag/xaml/feed" rel="self" type="application/rss+xml" />
	<link>http://zdima.net/blog</link>
	<description></description>
	<lastBuildDate>Mon, 30 Jan 2012 11:42:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WPF: Accessing Resources From An External Project</title>
		<link>http://zdima.net/blog/archives/14958</link>
		<comments>http://zdima.net/blog/archives/14958#comments</comments>
		<pubDate>Mon, 19 Apr 2010 19:02:00 +0000</pubDate>
		<dc:creator>XTab</dc:creator>
				<category><![CDATA[Contributors]]></category>
		<category><![CDATA[MergedDictionaries]]></category>
		<category><![CDATA[ResourceDictionary]]></category>
		<category><![CDATA[Resources]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[Visual Basic]]></category>
		<category><![CDATA[Visual Basic WPF]]></category>
		<category><![CDATA[Visual Basic.NET]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=14958</guid>
		<description><![CDATA[A friend asked me recently if it was possible to access resources that were created and stored in a separate assembly. Although I was sure it could be done, I’d never tried it, so I was interested in experimenting with this idea.  It turns out that ...<p class="read-more"><a href="http://zdima.net/blog/archives/14958">> Read more</a></p>]]></description>
			<content:encoded><![CDATA[<p>A friend asked me recently if it was possible to access resources that were created and stored in a separate assembly. Although I was sure it could be done, I’d never tried it, so I was interested in experimenting with this idea.  It turns out that the Pack URL holds the key.  Here’s an example.</p>
<p><span style="text-decoration:underline">Access a single ResourceDictionary</span></p>
<p>In a ResourceDictionary file named Dictionary1.xaml inside a standard WPF Application project named ‘Resources’, I have the following markup:</p>
<p> </p>
<div style="font-family:courier new;background:white;color:black;font-size:9pt">
<p style="margin:0px"><span style="color:#2b91af">    1</span> <span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:red"> xmlns</span><span style="color:blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    2</span>    <span style="color:red">xmlns</span><span style="color:blue">:</span><span style="color:red">x</span><span style="color:blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    3</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">LinearGradientBrush</span><span style="color:red"> x</span><span style="color:blue">:</span><span style="color:red">Key</span><span style="color:blue">=&quot;MyBrush&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    4</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">GradientStop</span><span style="color:red"> Color</span><span style="color:blue">=&quot;Black&quot;</span><span style="color:red"> Offset</span><span style="color:blue">=&quot;0&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    5</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">GradientStop</span><span style="color:red"> Color</span><span style="color:blue">=&quot;Yellow&quot;</span><span style="color:red"> Offset</span><span style="color:blue">=&quot;1&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    6</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;/</span><span style="color:#a31515">LinearGradientBrush</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    7</span> </p>
<p style="margin:0px"><span style="color:#2b91af">    8</span> <span style="color:#a31515">  </span><span style="color:blue">&lt;</span><span style="color:#a31515">Style</span><span style="color:red"> x</span><span style="color:blue">:</span><span style="color:red">Key</span><span style="color:blue">=&quot;RedButton&quot;</span><span style="color:red"> TargetType</span><span style="color:blue">=&quot;{</span><span style="color:#a31515">x</span><span style="color:blue">:</span><span style="color:#a31515">Type</span><span style="color:red"> Button</span><span style="color:blue">}&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    9</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Setter</span><span style="color:red"> Property</span><span style="color:blue">=&quot;Background&quot;</span><span style="color:red"> Value</span><span style="color:blue">=&quot;Red&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   10</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Setter</span><span style="color:red"> Property</span><span style="color:blue">=&quot;Foreground&quot;</span><span style="color:red"> Value</span><span style="color:blue">=&quot;Yellow&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   11</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Setter</span><span style="color:red"> Property</span><span style="color:blue">=&quot;Margin&quot;</span><span style="color:red"> Value</span><span style="color:blue">=&quot;12,3&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   12</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Setter</span><span style="color:red"> Property</span><span style="color:blue">=&quot;Padding&quot;</span><span style="color:red"> Value</span><span style="color:blue">=&quot;3&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   13</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Setter</span><span style="color:red"> Property</span><span style="color:blue">=&quot;MinWidth&quot;</span><span style="color:red"> Value</span><span style="color:blue">=&quot;75&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   14</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Setter</span><span style="color:red"> Property</span><span style="color:blue">=&quot;MinHeight&quot;</span><span style="color:red"> Value</span><span style="color:blue">=&quot;34&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   15</span> <span style="color:#a31515">  </span><span style="color:blue">&lt;/</span><span style="color:#a31515">Style</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   16</span> <span style="color:blue">&lt;/</span><span style="color:#a31515">ResourceDictionary</span><span style="color:blue">&gt;</span></p>
</div>
<p> </p>
<p>Very basic resources, I know, but sufficient to demo the process. The next step is to create the ‘client’ project, the one that will use this resource.  You can either add a new project to the current solution or start a completely separate solution. In my first example, I added a WPF Application project to the solution and named it ‘ResourceUser’.</p>
<p>In either case, you need to add a reference to the ‘Resource’ project in the Reference section of the ResourceUser project. If you add a second project to the current solution, the project name will be available to you in the Projects tab of the Add reference dialog (as shown in the screenshot below).  If you use a separate solution, you’ll have to use the Browse tab and navigate your way to the required assembly.</p>
<p> </p>
<p><a href="http://vbcity.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xtab.metablogapi/8546.ResDictonaries001_5F00_1A88F004.png"><img height="466" width="468" src="http://vbcity.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xtab.metablogapi/1512.ResDictonaries001_5F00_thumb_5F00_6FB061C2.png" alt="ResDictonaries001" border="0" title="ResDictonaries001" style="display:inline;border-width:0px"></a> </p>
<p> </p>
<p>This enables you to point to the source file, i.e. the ResourceDictionary named Dictionary1.xaml in the Resource project.  The way you point to that resource is to create a ResourceDictionary in the Application.xaml file of the client project, the project that I named ResourceUser.  You set its Source property to the Dictionary1.xaml file.  As I said at the start, you use the pack URL syntax to do this. Here’s the syntax that does the job:</p>
<p> </p>
<div style="font-family:courier new;background:white;color:black;font-size:9pt">
<p style="margin:0px"><span style="color:#2b91af">    1</span> <span style="color:blue">&lt;</span><span style="color:#a31515">Application</span><span style="color:red"> x</span><span style="color:blue">:</span><span style="color:red">Class</span><span style="color:blue">=&quot;Application&quot;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    2</span>    <span style="color:red">xmlns</span><span style="color:blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    3</span>    <span style="color:red">xmlns</span><span style="color:blue">:</span><span style="color:red">x</span><span style="color:blue">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    4</span>    <span style="color:red">StartupUri</span><span style="color:blue">=&quot;Window1.xaml&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    5</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Application.Resources</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    6</span> </p>
<p style="margin:0px"><span style="color:#2b91af">    7</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:red"> Source</span><span style="color:blue">=&quot;pack://application:,,,/Resources;component/Dictionary1.xaml&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    8</span> </p>
<p style="margin:0px"><span style="color:#2b91af">    9</span> <span style="color:#a31515">  </span><span style="color:blue">&lt;/</span><span style="color:#a31515">Application.Resources</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   10</span> <span style="color:blue">&lt;/</span><span style="color:#a31515">Application</span><span style="color:blue">&gt;</span></p>
</div>
<p> </p>
<p>To avoid confusion, I probably should have named the first project something like ‘ResourceDictionarySource’, but anyway I’m sure you’ll understand that the word ‘Resources’ in that Source property refers to the name of the project.  You’ll also see that the Dictionary1.xaml file name is included as the final item.  The general syntax for the pack URL approach is:</p>
<blockquote>
<p><a href="pack://application:,,,/" class="autohyperlink" title="pack://application:,,,/" target="_blank" rel="nofollow">application:,,,/</a><span style="color:#800000">&lt;Name of project you are referencing&gt;</span>;component/<span style="color:#800000">&lt;Name of specific file you want to access&gt;</span></p>
</blockquote>
<p>Once you’ve rebuilt the project, you can use the referenced resources just as you would if they existed in the client project.  To use the gradient brush and the button styles from my example above, you can do something like this in the Window of the ResourceUser project:</p>
<p> </p>
<div style="font-family:courier new;background:white;color:black;font-size:9pt">
<p style="margin:0px"><span style="color:#2b91af">   12</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Button</span><span style="color:red"> Style</span><span style="color:blue">=&quot;{</span><span style="color:#a31515">StaticResource</span><span style="color:red"> RedButton</span><span style="color:blue">}&quot;</span><span style="color:red"> Content</span><span style="color:blue">=&quot;Demo&quot;</span><span style="color:red"> Margin</span><span style="color:blue">=&quot;52,21,127,0&quot;</span><span style="color:red"> Grid.Row</span><span style="color:blue">=&quot;1&quot;</span><span style="color:red"> Height</span><span style="color:blue">=&quot;22&quot;</span><span style="color:red"> VerticalAlignment</span><span style="color:blue">=&quot;Top&quot; /&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   13</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Rectangle</span><span style="color:red"> Margin</span><span style="color:blue">=&quot;52,28,127,17&quot;</span><span style="color:red"> Name</span><span style="color:blue">=&quot;Rectangle1&quot;</span><span style="color:red"> Stroke</span><span style="color:blue">=&quot;Black&quot;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   14</span>               <span style="color:red">Fill</span><span style="color:blue">=&quot;{</span><span style="color:#a31515">StaticResource</span><span style="color:red"> MyBrush</span><span style="color:blue">}&quot;/&gt;</span></p>
</div>
<p><span style="text-decoration:underline"></span></p>
<p><span style="text-decoration:underline">Access multiple ResourceDictionaries</span></p>
<p>If the project that has the resources contains more than one ResourceDictionary, then you can use a MergedDictionaries block in the Application.xaml file of the client project. The following example assumes that the Resources project now contains two separate ResourceDictionary files named Dictionary1.xaml and Dictionary2.xaml:</p>
<p> </p>
<div style="font-family:courier new;background:white;color:black;font-size:9pt">
<p style="margin:0px"><span style="color:#2b91af">    5</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Application.Resources</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    6</span> </p>
<p style="margin:0px"><span style="color:#2b91af">    7</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    8</span> <span style="color:#a31515">      </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary.MergedDictionaries</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    9</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:red"> Source</span><span style="color:blue">=&quot;pack://application:,,,/Resources;component/Dictionary1.xaml&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   10</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:red"> Source</span><span style="color:blue">=&quot;pack://application:,,,/Resources;component/Dictionary2.xaml&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   11</span> <span style="color:#a31515">      </span><span style="color:blue">&lt;/</span><span style="color:#a31515">ResourceDictionary.MergedDictionaries</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   12</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;/</span><span style="color:#a31515">ResourceDictionary</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   13</span> </p>
<p style="margin:0px"><span style="color:#2b91af">   14</span> <span style="color:#a31515">  </span><span style="color:blue">&lt;/</span><span style="color:#a31515">Application.Resources</span><span style="color:blue">&gt;</span></p>
</div>
<p> </p>
<p><span style="text-decoration:underline">What if you have ResourceDictionaries in the client project too?</span></p>
<p>This doesn’t present any kind of problem.  You simply add the ResourceDictionary to the MergedDictionaries collection in the usual way.  For example, if you have a ResourceDictionary named ResourceDictionary3.xaml in the ResourceUser project, you can use this syntax in Application.xaml:</p>
<p> </p>
<div style="font-family:courier new;background:white;color:black;font-size:9pt">
<p style="margin:0px"><span style="color:#2b91af">    7</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    8</span> <span style="color:#a31515">      </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary.MergedDictionaries</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    9</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:red"> Source</span><span style="color:blue">=&quot;pack://application:,,,/Resources;component/Dictionary1.xaml&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   10</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:red"> Source</span><span style="color:blue">=&quot;pack://application:,,,/Resources;component/Dictionary2.xaml&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   11</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">ResourceDictionary</span><span style="color:red"> Source</span><span style="color:blue">=&quot;Dictionary3.xaml&quot; /&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   12</span> <span style="color:#a31515">      </span><span style="color:blue">&lt;/</span><span style="color:#a31515">ResourceDictionary.MergedDictionaries</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   13</span> <span style="color:#a31515">    </span><span style="color:blue">&lt;/</span><span style="color:#a31515">ResourceDictionary</span><span style="color:blue">&gt;</span></p>
<p style="margin:0px"><span style="color:blue"> </span></p>
<p style="margin:0px"> </p>
</div>
<p><span style="text-decoration:underline">What about resources that use their own resources?</span></p>
<p>So what happens if for example you have a ControlTemplate that uses images that are stored as resources in the Resource project?  Well, this isn’t a problem at all because the whole Resource project is referenced, so if the template calls for a resource file in that project when it is used in the client project, that file is available.</p>
<p>If that explanation isn’t as clear as you’d like, here’s an example.  In the Dictionary2.xaml ResourceDictionary, you have a Control Template for a CheckBox that uses three images.  Here’s the first part of the markup for the CheckBox Control Template:</p>
<p> </p>
<div style="font-family:courier new;background:white;color:black;font-size:9pt">
<p style="margin:0px"><span style="color:#2b91af">    6</span> <span style="color:blue">&lt;</span><span style="color:#a31515">ControlTemplate</span><span style="color:red"> x</span><span style="color:blue">:</span><span style="color:red">Key</span><span style="color:blue">=&quot;ThumbCheckBox&quot;</span><span style="color:red"> TargetType</span><span style="color:blue">=&quot;{</span><span style="color:#a31515">x</span><span style="color:blue">:</span><span style="color:#a31515">Type</span><span style="color:red"> CheckBox</span><span style="color:blue">}&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    7</span> <span style="color:#a31515">        </span><span style="color:blue">&lt;</span><span style="color:#a31515">Border</span><span style="color:red"> Name</span><span style="color:blue">=&quot;OuterBorder&quot;</span> </p>
<p style="margin:0px"><span style="color:#2b91af">    8</span>               <span style="color:red">BorderBrush</span><span style="color:blue">=&quot;Black&quot;</span><span style="color:red"> BorderThickness</span><span style="color:blue">=&quot;1&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">    9</span> <span style="color:#a31515">            </span><span style="color:blue">&lt;</span><span style="color:#a31515">Canvas</span><span style="color:red"> Name</span><span style="color:blue">=&quot;MainCanvas&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   10</span> <span style="color:#a31515">                </span><span style="color:blue">&lt;</span><span style="color:#a31515">Border</span><span style="color:red"> Name</span><span style="color:blue">=&quot;ImagesBorder&quot;</span><span style="color:red"> BorderBrush</span><span style="color:blue">=&quot;DarkGray&quot;</span> <span style="color:red">BorderThickness</span><span style="color:blue">=&quot;1&quot;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   11</span>                       <span style="color:red">Width</span><span style="color:blue">=&quot;24&quot;</span><span style="color:red"> Height</span><span style="color:blue">=&quot;32&quot;</span><span style="color:red"> Margin</span><span style="color:blue">=&quot;1,1,0,0&quot; &gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   12</span> <span style="color:#a31515">                    </span><span style="color:blue">&lt;</span><span style="color:#a31515">Canvas</span><span style="color:red"> Name</span><span style="color:blue">=&quot;ImagesCanvas&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   13</span> <span style="color:#a31515">                        </span><span style="color:blue">&lt;</span><span style="color:#a31515">Image</span><span style="color:red"> Name</span><span style="color:blue">=&quot;ThumbDown&quot;</span><span style="color:red"> Source</span><span style="color:blue">=&quot;ThumbDownSmall.jpg&quot;</span><span style="color:red"> Width</span><span style="color:blue">=&quot;18&quot;</span><span style="color:red"> Height</span><span style="color:blue">=&quot;26&quot;</span> </p>
<p style="margin:0px"><span style="color:#2b91af">   14</span>                             <span style="color:red">Canvas.Left</span><span style="color:blue">=&quot;2&quot;</span><span style="color:red"> Canvas.Top</span><span style="color:blue">=&quot;2&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   15</span> <span style="color:#a31515">                        </span><span style="color:blue">&lt;</span><span style="color:#a31515">Image</span><span style="color:red"> Name</span><span style="color:blue">=&quot;ThumbUp&quot;</span><span style="color:red"> Source</span><span style="color:blue">=&quot;ThumbUpSmall.jpg&quot;</span><span style="color:red"> Width</span><span style="color:blue">=&quot;18&quot;</span><span style="color:red"> Height</span><span style="color:blue">=&quot;26&quot;</span> </p>
<p style="margin:0px"><span style="color:#2b91af">   16</span>                              <span style="color:red">Margin</span><span style="color:blue">=&quot;1&quot;</span>  <span style="color:red">Canvas.Left</span><span style="color:blue">=&quot;2&quot;</span><span style="color:red"> Canvas.Top</span><span style="color:blue">=&quot;2&quot;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   17</span>                              <span style="color:red">Visibility</span><span style="color:blue">=&quot;Hidden&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   18</span> <span style="color:#a31515">                        </span><span style="color:blue">&lt;</span><span style="color:#a31515">Image</span><span style="color:red"> Name</span><span style="color:blue">=&quot;Indeterminate&quot;</span><span style="color:red"> Source</span><span style="color:blue">=&quot;QuestionMark.jpg&quot;</span><span style="color:red"> Width</span><span style="color:blue">=&quot;18&quot;</span><span style="color:red"> Height</span><span style="color:blue">=&quot;26&quot;</span> </p>
<p style="margin:0px"><span style="color:#2b91af">   19</span>                              <span style="color:red">Margin</span><span style="color:blue">=&quot;1&quot;</span>  <span style="color:red">Canvas.Left</span><span style="color:blue">=&quot;2&quot;</span><span style="color:red"> Canvas.Top</span><span style="color:blue">=&quot;2&quot;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   20</span>                              <span style="color:red">Visibility</span><span style="color:blue">=&quot;Hidden&quot;/&gt;</span></p>
<p style="margin:0px"><span style="color:#2b91af">   21</span> <span style="color:#a31515">                    </span><span style="color:blue">&lt;/</span><span style="color:#a31515">Canvas</span><span style="color:blue">&gt;</span></p>
</div>
<p> </p>
<p>You can see that there are three jpgs involved in the creation of that template.</p>
<p>They are all stored in the project with a Build Action of Resource.  One of the images is named ThumbDownSmall.jpg  and you can see it shown in the Solution Explorer, together with its properties in the Properties pane:</p>
<p><a href="http://vbcity.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xtab.metablogapi/7271.ResDictonaries002_5F00_6079374E.png"><img height="666" width="376" src="http://vbcity.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xtab.metablogapi/6332.ResDictonaries002_5F00_thumb_5F00_40AA11EC.png" alt="ResDictonaries002" border="0" title="ResDictonaries002" style="display:inline;border-width:0px"></a> </p>
<p> </p>
<p>If you assign this ControlTemplate to a CheckBox instance in the Window of the client project, the required images will be pulled from the Resources project as and when they are needed.  The following XAML in the client project uses the template:</p>
<p> </p>
<div style="font-family:courier new;background:white;color:black;font-size:9pt">
<p style="margin:0px"><span style="color:#a31515">    </span><span style="color:blue">&lt;</span><span style="color:#a31515">CheckBox</span><span style="color:red"> Name</span><span style="color:blue">=&quot;chkApproval&quot;</span><span style="color:red"> Margin</span><span style="color:blue">=&quot;52,14,111,36&quot;</span><span style="color:red"> Grid.Row</span><span style="color:blue">=&quot;2&quot;</span></p>
<p style="margin:0px">         <span style="color:red">Template</span><span style="color:blue">=&quot;{</span><span style="color:#a31515">StaticResource</span><span style="color:red"> ThumbCheckBox</span><span style="color:blue">}&quot;</span></p>
<p style="margin:0px">         <span style="color:red">Content</span><span style="color:blue">=&quot;Not Approved&quot;</span></p>
<p style="margin:0px">         <span style="color:red">IsChecked</span><span style="color:blue">=&quot;{</span><span style="color:#a31515">x</span><span style="color:blue">:</span><span style="color:#a31515">Null</span><span style="color:blue">}&quot;</span> </p>
<p style="margin:0px">         <span style="color:red">IsThreeState</span><span style="color:blue">=&quot;True&quot;&gt;</span></p>
<p style="margin:0px"><span style="color:#a31515">    </span><span style="color:blue">&lt;/</span><span style="color:#a31515">CheckBox</span><span style="color:blue">&gt;</span></p>
</div>
<p> </p>
<p>And the result is the CheckBox you can see at the bottom of the Window:</p>
<p> </p>
<p><a href="http://vbcity.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xtab.metablogapi/8306.ResDictonaries003_5F00_613D636C.png"><img height="389" width="387" src="http://vbcity.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/xtab.metablogapi/1581.ResDictonaries003_5F00_thumb_5F00_3DC0BF07.png" alt="ResDictonaries003" border="0" title="ResDictonaries003" style="display:inline;border:0px"></a></p>
<p>You can download the sample solution I used for this blog post.  It&#39;s available as a blog attachment or can be downloaded <a href="http://www.xtabvbcity.plus.com/Blogs/Resources.zip">from here</a>.</p>
<div style="clear:both"></div>
<p><img src="http://vbcity.com/aggbug.aspx?PostID=691443" width="1" height="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/14958/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF:  Using a VirtualizingStackPanel to Improve ComboBox Performance</title>
		<link>http://zdima.net/blog/archives/10800</link>
		<comments>http://zdima.net/blog/archives/10800#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:18:00 +0000</pubDate>
		<dc:creator>XTab</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Contributors]]></category>
		<category><![CDATA[DataTemplate]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[VirtualizingStackPanel]]></category>
		<category><![CDATA[Visual Basic]]></category>
		<category><![CDATA[Visual Basic.NET]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=10800</guid>
		<description><![CDATA[
IntroductionIn this earlier blog, I looked at how to use a ComboBox to display a list of all the system fonts, displaying each font name in its own font style.

I mentioned there that fonts are something of a special case, in that this collection of f...<p class="read-more"><a href="http://zdima.net/blog/archives/10800">> Read more</a></p>]]></description>
			<content:encoded><![CDATA[<p><span ></span></p>
<p><span >Introduction</span><br />In <a href="http://vbcity.com/blogs/xtab/archive/2009/11/25/wpf-how-to-list-select-and-apply-fonts.aspx">this earlier blog</a><a></a>, I looked at how to use a ComboBox to display a list of all the system fonts, displaying each font name in its own font style.</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/Fonts/Fonts001.png" alt=""></p>
<p>I mentioned there that fonts are something of a special case, in that this collection of fonts is automatically cached for you after you first use it. The result is that when you run the application for the second and subsequent times there is minimal delay between the time the user clicks the ComboBox down arrow and the appearance of the list of fonts.</p>
<p>In this blog I want to look at the situation where you have a ComboBox that has a large number of other (possibly graphically complex) items to display. <br />Without the built-in caching that is available for fonts, you will often find that the display of large amounts of data in a ComboBox can be annoyingly slow. Furthermore, it will continue to be slow each time the ComboBox is recreated (although you can re-access the ComboBox and have shorter delays as long as you don&#39;t close the Window). However, if you close the Window that contains this ComboBox, then the whole display has to be rebuilt and the initial longer delay will reoccur. </p>
<p>The reason for the delay is that WPF creates the complete display for the ComboBox in advance,  regardless of the fact that it might only display a tiny proportion of the total number of items. It is this initial unnecessary creation of visual content that causes the problem. Let&#39;s create a sample project to demonstrate this.</p>
<p><span >Display of Large Amount of Text</span><br />First, I&#39;ll create some fairly uninspiring demo data in the code-behind: </p>
<div >
<p >    <span >Private</span> <span >Sub</span> Window2_Loaded(<span >ByVal</span> sender <span >As</span> <span >Object</span>, <span >ByVal</span> e <span >As</span> System.Windows.RoutedEventArgs) <span >Handles</span> <span >Me</span>.Loaded</p>
<p >        <span >Dim</span> DemoList <span >As</span> <span >New</span> List(<span >Of</span> <span >String</span>)</p>
<p >        <span >For</span> i <span >As</span> <span >Integer</span> = 0 <span >To</span> 10000</p>
<p >            DemoList.Add(<span >&quot;This is ItemCollection # &quot;</span> &amp; i.ToString)</p>
<p >        <span >Next</span></p>
<p >        <span >Me</span>.DataContext = DemoList</p>
<p >    <span >End</span> <span >Sub</span> </p>
</div>
<p>This simply creates 10,000 Strings, stores them in a List (Of String) and sets this List as the DataContext for the Window.</p>
<p>Next, in the markup for the Window, create a ComboBox that will use those Strings for its display of items: </p>
<div >
<p ><span >    </span><span >&lt;</span><span >ComboBox</span><span > Height</span><span >=&quot;23&quot;</span><span > Margin</span><span >=&quot;27,10,10,0&quot;</span><span > Name</span><span >=&quot;ComboBox1&quot;</span></p>
<p >             <span >VerticalAlignment</span><span >=&quot;Top&quot;</span></p>
<p >             <span >ItemsSource</span><span >=&quot;{</span><span >Binding</span><span >}&quot;&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ComboBox</span><span >&gt;</span><span > </span> </p>
</div>
<p>When you run this application, there will be noticeable delay before the list appears. As I mentioned above, when you click for a second and subsequent times, the delay is shorter but still exists. If you close this Window and then subsequently show it again, the long delay will reoccur.</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/VSP001.png" alt=""></p>
<p><span >Improving the Display Time</span><br />The quick fix for this issue is to insert a VirtualizingStackPanel into the template for the ComboBox. This panel has the ability to assess how many items can be displayed, based on the measurements of the ComboBox, and automatically creates the visuals for that limited number of items only. </p>
<p>An easy way to implement this is to create an ItemsPanelTemplate as a Resource and reference it in the ComboBox markup.  </p>
<div >
<p ><span >  </span><span >&lt;</span><span >Window.Resources</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >ItemsPanelTemplate</span><span > x</span><span >:</span><span >Key</span><span >=&quot;VSP&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >VirtualizingStackPanel</span><span >/&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ItemsPanelTemplate</span><span >&gt;</span></p>
<p ><span >  </span><span >&lt;/</span><span >Window.Resources</span><span >&gt;</span></p>
<p > </p>
<p > </p>
</div>
<div >
<p ><span >    </span><span >&lt;</span><span >ComboBox</span><span > Height</span><span >=&quot;23&quot;</span><span > Margin</span><span >=&quot;27,10,10,0&quot;</span><span > Name</span><span >=&quot;ComboBox1&quot;</span></p>
<p >             <span >VerticalAlignment</span><span >=&quot;Top&quot;</span> </p>
<p >             <span >ItemsSource</span><span >=&quot;{</span><span >Binding</span><span >}&quot;</span></p>
<p >             <span >ItemsPanel</span><span >=&quot;{</span><span >StaticResource</span><span > VSP</span><span >}&quot;&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ComboBox</span><span >&gt;</span><span > </span> </p>
</div>
<p>Specifically, the ItemsPanel property of the ComboBox is set to that ItemsPanelTemplate Resource.</p>
<p>If you prefer, you can include the VirtualizingStackPanel right in the ComboBox creation markup: </p>
<div >
<p ><span >   </span><span >&lt;</span><span >ComboBox</span><span > Height</span><span >=&quot;23&quot;</span><span > Margin</span><span >=&quot;27,10,10,0&quot;</span><span > Name</span><span >=&quot;ComboBox1&quot;</span></p>
<p >             <span >VerticalAlignment</span><span >=&quot;Top&quot;</span> </p>
<p >             <span >ItemsSource</span><span >=&quot;{</span><span >Binding</span><span >}&quot;</span></p>
<p >            <span >&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >ComboBox.ItemsPanel</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >ItemsPanelTemplate</span><span >&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >VirtualizingStackPanel</span><span > /&gt;</span></p>
<p ><span >        </span><span >&lt;/</span><span >ItemsPanelTemplate</span><span >&gt;</span></p>
<p ><span >      </span><span >&lt;/</span><span >ComboBox.ItemsPanel</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ComboBox</span><span >&gt;</span><span > </span> </p>
</div>
<p>Personally, I like to try and keep as much of these kind of things as Resources as I can. </p>
<p><span >More Complex Items</span></p>
<p>  If your display is more complex &#8211; maybe using a DataTemplate and including nested panels and some images in each item:</p>
<div >
<p ><span >    </span><span >&lt;</span><span >DataTemplate</span><span > x</span><span >:</span><span >Key</span><span >=&quot;ImgAndText&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >StackPanel</span><span > Orientation</span><span >=&quot;Horizontal&quot;&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >Image</span><span > Source</span><span >=&quot;Timer.jpg&quot;</span><span > Height</span><span >=&quot;89&quot;</span><span > Margin</span><span >=&quot;3&quot;&gt;&lt;/</span><span >Image</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >StackPanel</span><span >&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >Image</span><span > Source</span><span >=&quot;Stars.jpg&quot;</span><span > Width</span><span >=&quot;152&quot;</span><span > Height</span><span >=&quot;44&quot;</span><span > Stretch</span><span >=&quot;None&quot;&gt;&lt;/</span><span >Image</span><span >&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >TextBlock</span><span > Text</span><span >=&quot;{</span><span >Binding</span><span >}&quot;</span><span > Margin</span><span >=&quot;2,15,2,2&quot; &gt;&lt;/</span><span >TextBlock</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;/</span><span >StackPanel</span><span >&gt;</span></p>
<p ><span >       </span><span >&lt;/</span><span >StackPanel</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >DataTemplate</span><span >&gt;</span></p>
</div>
<p> </p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/VSP002.png" alt=""></p>
<p>then the delay can become very substantial indeed and you will certainly want to be sure to include a VirtualizingStackPanel in the markup for the ComboBox.</p>
<div ></div>
<p><img src="http://vbcity.com/aggbug.aspx?PostID=296" width="1" height="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/10800/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF: ProgressBar With Marquee Text Display and TemplateBinding</title>
		<link>http://zdima.net/blog/archives/10465</link>
		<comments>http://zdima.net/blog/archives/10465#comments</comments>
		<pubDate>Fri, 11 Dec 2009 13:11:00 +0000</pubDate>
		<dc:creator>XTab</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Contributors]]></category>
		<category><![CDATA[ControlTemplate]]></category>
		<category><![CDATA[ProgressBar]]></category>
		<category><![CDATA[TemplateBinding]]></category>
		<category><![CDATA[TextBox]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[Visual Basic]]></category>
		<category><![CDATA[Visual Basic WPF]]></category>
		<category><![CDATA[Visual Basic.NET]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=10465</guid>
		<description><![CDATA[
 IntroductionIn this blog I want to demonstrate several things. The first is how to reveal a text message in a ProgressBar. This is easy to do and you can get reasonably close to the moving marquee effect that you can see on some digital displays. A ...<p class="read-more"><a href="http://zdima.net/blog/archives/10465">> Read more</a></p>]]></description>
			<content:encoded><![CDATA[<p><span ></span></p>
<p> <span >Introduction</span><br />In this blog I want to demonstrate several things. The first is how to reveal a text message in a ProgressBar. This is easy to do and you can get reasonably close to the moving marquee effect that you can see on some digital displays. <br />A more important topic that I&#39;ll cover is TemplateBinding in ControlTemplates. This makes it easy to use a core template, but allow individual instances of the control type that use the template to tweak selected properties. In this case I&#39;ll use the FontSize property.<br />Finally, you sometimes come across a situation where the control (in this case the ProgressBar) doesn&#39;t have a property that maps directly to a property that exists in the ControlTemplate. Although this might seem improbable, it actually happens quite often. We&#39;ll look at how we can work round this limitation and in the example I will show you can set a Content property on a ProgressBar control, even though the ProgressBar doesn&#39;t actually possess such a property. </p>
<p>If you&#39;ve read my last three or four blogs you may be thinking that I&#39;m a bit obsessed with ProgressBars! That&#39;s not the case and it&#39;s simply that they represent a good case study for ControlTemplates, they require named parts and I think they make a nice change from the demos that mostly seem to use Buttons. </p>
<p><span >The ControlTemplate</span><br />In the previous blogs on ProgressBars, you will have seen that I have stored the ControlTemplates in the Window.Resources collection. This time, the ControlTemplate is going to be stored in the Application.Resources collection. The thinking behind this is that this template is designed to be reused in several Windows across the application, with different values being placed on some properties in some instances. So having it in a central location clearly makes it available application-wide and makes sense. </p>
<p>Here is the markup for the initial version of the ControlTemplate: </p>
<div >
<p ><span >    </span><span >&lt;</span><span >ControlTemplate</span><span > x</span><span >:</span><span >Key</span><span >=&quot;PBWordReveal&quot;</span><span > TargetType</span><span >=&quot;{</span><span >x</span><span >:</span><span >Type</span><span > ProgressBar</span><span >}&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >Grid</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >Border</span><span > Name</span><span >=&quot;PART_Track&quot;</span>  </p>
<p >          <span >BorderThickness</span><span >=&quot;2&quot;</span> <span >CornerRadius</span><span >=&quot;5&quot;</span></p>
<p >          <span >Background</span><span >=&quot;LightSkyBlue&quot;</span><span > BorderBrush</span><span >=&quot;Navy&quot;</span>  <span >/&gt;</span></p>
<p > </p>
<p ><span >        </span><span >&lt;</span><span >ContentControl</span><span > Name</span><span >=&quot;PART_Indicator&quot;</span> </p>
<p >           <span >Content</span><span >=&quot;  Loading   . . . .   Loading   . . . . .   Loading&quot;</span></p>
<p >           <span >Margin</span><span >=&quot;4,0&quot;</span><span > FontSize</span><span >=&quot;14&quot;</span> </p>
<p >           <span >Foreground</span><span >=&quot;Black&quot;</span><span > Background</span><span >=&quot;LightSkyBlue&quot;</span></p>
<p >           <span >VerticalAlignment</span><span >=&quot;Center&quot;</span></p>
<p >           <span >HorizontalAlignment</span><span >=&quot;Left&quot;/&gt;</span></p>
<p ><span >      </span><span >&lt;/</span><span >Grid</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ControlTemplate</span><span >&gt;</span> </p>
</div>
<p>If you are not familiar with the concept of named parts &#8211; specifically the PART_Track and PART_Indicator shown above &#8211; you get an explanation in my previous ProgressBar blogs. </p>
<p>The outer track is a Border element, while the Indicator uses a ContentControl. The key property is probably the Content property, which as you can see contains the text that will be displayed. The HorizontalAlignment property is also quite important to the look of the final effect. </p>
<p><span >ProgressBar Instance</span> <br />To use this template, I will create a ProgressBar instance in a Window. </p>
<div >
<p ><span >    </span><span >&lt;</span><span >ProgressBar</span><span > Name</span><span >=&quot;PBReveal&quot;</span></p>
<p >     <span >Template</span><span >=&quot;{</span><span >StaticResource</span><span > PBWordReveal</span><span >}&quot;</span></p>
<p >            <span >Width</span><span >=&quot;200&quot;</span><span > Height</span><span >=&quot;40&quot;</span>    <span >/&gt;</span> </p>
</div>
<p>To animate the ProgressBar in the code-behind of the Window (in this example, a Window named &#39;WordReveal&#39;: </p>
<div >
<p ><span >Imports</span> System.Windows.Media.Animation</p>
<p > </p>
<p ><span >Partial</span> <span >Public</span> <span >Class</span> WordReveal</p>
<p > </p>
<p >    <span >Private</span> <span >Sub</span> WordReveal_Loaded(<span >ByVal</span> sender <span >As</span> <span >Object</span>, <span >ByVal</span> e <span >As</span> System.Windows.RoutedEventArgs) <span >Handles</span> <span >Me</span>.Loaded</p>
<p >         <span >Dim</span> a <span >As</span> <span >New</span> DoubleAnimation</p>
<p >        a.From = 0</p>
<p >        a.To = 100</p>
<p >        a.Duration = <span >New</span> TimeSpan(0, 0, 6)</p>
<p > </p>
<p >        PBReveal.BeginAnimation(ProgressBar.ValueProperty, a)</p>
<p >    <span >End</span> <span >Sub</span></p>
<p ><span >End</span> <span >Class</span> </p>
</div>
<p>When you run this project, the text content in the ProgressBar will be revealed from left to right. The screenshot shows the bar with the animation approx 60% complete: </p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs026.png" alt=""></p>
<p>And this is the display when the animation has ended:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs025.png" alt=""></p>
<p>Effectively all that is happening is that the ContentControl, the PART_Indicator element of the template, is revealed over the period of the animation &#8211; the revelation commencing from left to right. </p>
<p>If you want more of a marquee type effect, you can change the HorizontalAlignment : </p>
<div >
<p > <span > HorizontalAlignment</span><span >=&quot;Right&quot;</span> </p>
</div>
<p>This will make the text scroll from right to left:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs027.png" alt=""></p>
<p>Setting the HorizontalAlignment to either Center or Stretch will produce a different result again. </p>
<p><span >TemplateBinding</span><br />TemplateBinding allows you to hand back control of selected properties to the instance of the ProgressBar that is using this ControlTemplate. It is simple to implement and in this example only requires the change shown below to the PART_Indicator named part of the template:  </p>
<div >
<p ><span >       </span><span >&lt;</span><span >ContentControl</span><span > Name</span><span >=&quot;PART_Indicator&quot;</span> </p>
<p >           <span >Content</span><span >=&quot;  Loading   . . . .   Loading   . . . . .   Loading&quot;</span></p>
<p >           <span >Margin</span><span >=&quot;4,0&quot;</span> </p>
<p >              <span >FontSize</span><span >=&quot;{</span><span >TemplateBinding</span><span > FontSize</span><span >}&quot;</span> </p>
<p >           <span >Foreground</span><span >=&quot;Black&quot;</span><span > Background</span><span >=&quot;LightSkyBlue&quot;</span></p>
<p >           <span >VerticalAlignment</span><span >=&quot;Center&quot;</span></p>
<p >           <span >HorizontalAlignment</span><span >=&quot;Right&quot;</span></p>
<p >          <span >/&gt;</span> </p>
</div>
<p>The TemplateBinding points to a specific property &#8211; FontSize. This can now be set in an instance of the control that uses the template:  </p>
<div >
<p ><span >    </span><span >&lt;</span><span >ProgressBar</span><span > Name</span><span >=&quot;PBReveal&quot;</span></p>
<p >     <span >Template</span><span >=&quot;{</span><span >StaticResource</span><span > PBWordReveal</span><span >}&quot;</span></p>
<p >     <span >Width</span><span >=&quot;200&quot;</span><span > Height</span><span >=&quot;40&quot;</span> </p>
<p >        <span >FontSize</span><span >=&quot;22&quot;/&gt;</span> </p>
</div>
<p>Note that if you choose not to set a value on the FontSize property in the ProgressBar instance, the default value for that property will be used (12).</p>
<p><span >Mapping Between Properties </span><br />As you can see from the markup, the PART_Indicator uses a ContentPresenter. The ContentPresenter has a Content property and this is what is used to set the value of the text to be displayed. The basic ProgressBar however doesn&#39;t have such a property. So if you want to include TemplateBinding to allow different text to be used in different instances that use this template, you need to map the ContentPresenter property to some other property of the ProgressBar. </p>
<p>In most cases, if you have only one property that needs this kind of mapping, the solution is simple. You can use the Tag property: </p>
<div >
<p ><span >        </span><span >&lt;</span><span >ContentControl</span><span > Name</span><span >=&quot;PART_Indicator&quot;</span> </p>
<p >             <span >Content</span><span >=&quot;{</span><span >TemplateBinding</span><span > Tag</span><span >}&quot;</span></p>
<p >           <span >Margin</span><span >=&quot;4,0&quot;</span> </p>
<p >           <span >FontSize</span><span >=&quot;{</span><span >TemplateBinding</span><span > FontSize</span><span >}&quot;</span> </p>
<p >           <span >Foreground</span><span >=&quot;Black&quot;</span><span > Background</span><span >=&quot;LightSkyBlue&quot;</span></p>
<p >           <span >VerticalAlignment</span><span >=&quot;Center&quot;</span></p>
<p >           <span >HorizontalAlignment</span><span >=&quot;Right&quot;</span></p>
<p >          <span >/&gt;</span> </p>
</div>
<p>And you insert the required text in the markup for the ProgressBar instance : </p>
<div >
<p ><span >    </span><span >&lt;</span><span >ProgressBar</span><span > Name</span><span >=&quot;PBReveal&quot;</span></p>
<p >     <span >Template</span><span >=&quot;{</span><span >StaticResource</span><span > PBWordReveal</span><span >}&quot;</span></p>
<p >     <span >Width</span><span >=&quot;200&quot;</span><span > Height</span><span >=&quot;40&quot;</span> </p>
<p >     <span >FontSize</span><span >=&quot;22&quot;</span></p>
<p >       <span >Tag</span><span >=&quot;  Please Wait . . . . . . . . . .&quot;/&gt;</span> </p>
</div>
<p>These two templated changes result in the following display:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs028.png" alt=""></p>
<p>As you can see, both the FontSize and the Content have changed. </p>
<p>If you need to include more than one of these kind of cross property mappings, there is nothing (apart from common sense and experience) stopping you from hijacking other ProgressBar properties. You can identify a property that you absolutely, categorically know won&#39;t be used (and there&#39;s the start of the slippery slope right there) you can use this to map to. </p>
<p>The more professional alternative, of course, is to create a custom control of your own which contains all the properties you desire. I&#39;ll be looking at the steps involved in creating a custom control in a future blog. </p>
<div ></div>
<p><img src="http://vbcity.com/aggbug.aspx?PostID=290" width="1" height="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/10465/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF: How to Create a Reversing ProgressBar</title>
		<link>http://zdima.net/blog/archives/10016</link>
		<comments>http://zdima.net/blog/archives/10016#comments</comments>
		<pubDate>Sat, 05 Dec 2009 11:57:00 +0000</pubDate>
		<dc:creator>XTab</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Contributors]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[ControlTemplate]]></category>
		<category><![CDATA[LinearGradientBrush]]></category>
		<category><![CDATA[ProgressBar]]></category>
		<category><![CDATA[RotateTransform]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[Visual Basic]]></category>
		<category><![CDATA[Visual Basic WPF]]></category>
		<category><![CDATA[Visual Basic.NET]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=10016</guid>
		<description><![CDATA[
 
 
In some of my earlier blogs - here, here and here, I looked at some rather colorful, non-rectangular versions of the ProgressBar. Although you probably wouldn&#39;t want to use some of those versions outside of a game environment, I hope it did ...<p class="read-more"><a href="http://zdima.net/blog/archives/10016">> Read more</a></p>]]></description>
			<content:encoded><![CDATA[<p><span ></span></p>
<p> </p>
<p> </p>
<p>In some of my earlier blogs &#8211; <a href="http://cs.vbcity.com/blogs/xtab/archive/2009/11/24/wpf-controltemplates-creating-a-non-rectangular-progressbar.aspx">here</a>, <a href="http://cs.vbcity.com/blogs/xtab/archive/2009/11/30/wpf-changing-progressbar-appearance-as-values-change.aspx">here</a> and <a href="http://cs.vbcity.com/blogs/xtab/archive/2009/12/02/wpf-how-to-create-a-quot-loading-quot-progressbar.aspx">here</a>, I looked at some rather colorful, non-rectangular versions of the ProgressBar. Although you probably wouldn&#39;t want to use some of those versions outside of a game environment, I hope it did show you how you can create and tweak non-rectangular versions. In this blog, I want to examine a less bizarre variation and along the way hopefully show you some more useful WPF basics. </p>
<p><span >Reversing the Default ProgressBar</span><br />The default ProgressBar is rectangular, has slightly rounded corners, a Gray Background, Linear Gradient Green Foreground and, most importantly, it traverses from left to right. I was wondering about how to change this and have a ProgressBar that traversed from right to left &#8211; a kind of a countdown effect instead of the usual fill-increasing effect. Because I was in ControlTemplate mode, I confess that I initially overlooked the obvious solution &#8211; total simplicity in WPF &#8211; and created a whole new template that did the job. I&#39;ll show you the obvious WPF solution shortly, but first let&#39;s just look at how this can be done as a ControlTemplate task. </p>
<p><span >ControlTemplate</span><br />I set about this by using a combination of Expression Blend and Visual Studio. I know I could have done it all in Blend using the Edit Template tools, but I came up this WPF route the hard way, from back in the early days when there were no tools and you had to become a XAML-head to get anywhere with this new-fangled thing called WPF. So I find that I still prefer to create my ControlTemplates in XAML in Visual Studio and use Blend when I want to do anything fancy with graphics or animation. </p>
<p>If you find it easier to do it all in Blend, I have no problem with that, but here&#39;s my way. First create a ControlTemplate, Key it as &#39;ReverseBasicPB&#39; and set its TargetType to ProgressBar. The visual elements of the template will all be held inside a Grid. </p>
<div >
<p ><span >    </span><span >&lt;</span><span >ControlTemplate</span><span > x</span><span >:</span><span >Key</span><span >=&quot;ReverseBasicPB&quot;</span><span > TargetType</span><span >=&quot;{</span><span >x</span><span >:</span><span >Type</span><span > ProgressBar</span><span >}&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >Grid</span><span >&gt;</span></p>
<p > </p>
<p ><span >      </span><span >&lt;/</span><span >Grid</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ControlTemplate</span><span >&gt;</span> </p>
</div>
<p>As you will know from the earlier blogs, the ProgressBar requires two named parts &#8211; PART_Track and PART_Indicator. In this version, PART_Track will consist of a Rectangle inside a Border and PART_Indicator will be a Rectangle with a reasonable copy of the Green Linear Brush. <br />(As a side note, it is possible to dig into the WPF namespaces and get hold of the ProgressBarGlassyHighlight and ProgressBarTopHighlight Brushes, but I was content to go with my approximation.) </p>
<p>Here is the markup for the PART_Track: </p>
<div >
<p ><span >       </span><span >&lt;</span><span >Border</span><span > Name</span><span >=&quot;PART_Track&quot;</span> <span >BorderBrush</span><span >=&quot;DarkGray&quot;</span> </p>
<p >               <span >BorderThickness</span><span >=&quot;2&quot;</span> <span >CornerRadius</span><span >=&quot;3&quot; &gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >Rectangle</span><span > Fill</span><span >=&quot;LightGray&quot;</span> </p>
<p >               <span >RadiusX</span><span >=&quot;3&quot;</span><span > RadiusY</span><span >=&quot;3&quot;/&gt;</span></p>
<p ><span >        </span><span >&lt;/</span><span >Border</span><span >&gt;</span> </p>
</div>
<p>Note that to achieve the rounded corner effect, Border uses CornerRadius and Rectangle uses RadiusX and RadiusY. </p>
<p>The markup for the Indicator is just as simple: </p>
<div >
<p ><span >          </span><span >&lt;</span><span >Rectangle</span><span > Name</span><span >=&quot;PART_Indicator&quot;</span><span > HorizontalAlignment</span><span >=&quot;Right&quot;</span> </p>
<p >                    <span >RadiusX</span><span >=&quot;3&quot;</span><span > RadiusY</span><span >=&quot;3&quot;</span>  </p>
<p >                    <span >Margin</span><span >=&quot;2,2,2,2&quot;&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >Rectangle.Fill</span><span >&gt;</span></p>
<p ><span >            </span><span >&lt;</span><span >LinearGradientBrush</span><span > EndPoint</span><span >=&quot;0.5,0&quot;</span><span > StartPoint</span><span >=&quot;0.5,1&quot;&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FF5FBB23&quot;</span><span > Offset</span><span >=&quot;0.525&quot;/&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;White&quot;/&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FF63BC28&quot;/&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FF95EDA5&quot;</span><span > Offset</span><span >=&quot;0.542&quot;/&gt;</span></p>
<p ><span >            </span><span >&lt;/</span><span >LinearGradientBrush</span><span >&gt;</span></p>
<p ><span >          </span><span >&lt;/</span><span >Rectangle.Fill</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;/</span><span >Rectangle</span><span >&gt;</span> </p>
</div>
<p>The key property here is the HorizontalAlignment. By setting it to Right we ensure that the ProgressBar Indicator will start at the right hand side and stretch out towards the left. </p>
<p><span >Demo</span><br />The following markup in a Window will create two ProgressBars, one default style and the other using this ControlTemplate: </p>
<div >
<p ><span >    </span><span >&lt;</span><span >Grid</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >Grid.RowDefinitions</span><span >&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >RowDefinition</span><span > Height</span><span >=&quot;87*&quot; /&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >RowDefinition</span><span > Height</span><span >=&quot;175*&quot; /&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >Grid.RowDefinitions</span><span >&gt;</span></p>
<p > </p>
<p ><span >    </span><span >&lt;</span><span >ProgressBar</span> <span >x</span><span >:</span><span >Name</span><span >=&quot;PBDefault&quot;</span><span > Width</span><span >=&quot;150&quot;</span><span > Height</span><span >=&quot;33&quot;&gt;</span></p>
<p > </p>
<p ><span >    </span><span >&lt;/</span><span >ProgressBar</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >ProgressBar</span><span > Name</span><span >=&quot;MyPB&quot;</span><span > Width</span><span >=&quot;150&quot;</span><span > Height</span><span >=&quot;33&quot;</span></p>
<p >          <span >Template</span><span >=&quot;{</span><span >StaticResource</span><span > ReverseBasicPB</span><span >}&quot;</span><span > Margin</span><span >=&quot;22&quot;</span> </p>
<p >          <span >Grid.Row</span><span >=&quot;1&quot;</span> </p>
<p >          <span >VerticalAlignment</span><span >=&quot;Top&quot; /&gt;</span></p>
<p ><span >  </span><span >&lt;/</span><span >Grid</span><span >&gt;</span> </p>
</div>
<p>Add in the animation code-behind used in previous examples: </p>
<div >
<p >    <span >Private</span> <span >Sub</span> ReverseBasic_Loaded(<span >ByVal</span> sender <span >As</span> <span >Object</span>, <span >ByVal</span> e <span >As</span> System.Windows.RoutedEventArgs) <span >Handles</span> <span >Me</span>.Loaded</p>
<p >        <span >Dim</span> a <span >As</span> <span >New</span> DoubleAnimation</p>
<p >        a.From = 0</p>
<p >        a.To = 100</p>
<p >        a.Duration = <span >New</span> TimeSpan(0, 0, 6)</p>
<p > </p>
<p >        MyPB.BeginAnimation(ProgressBar.ValueProperty, a)</p>
<p > </p>
<p >        a.From = 0</p>
<p >        a.To = 100</p>
<p >        a.Duration = <span >New</span> Duration(TimeSpan.Parse(<span >&quot;0:0:6&quot;</span>))</p>
<p > </p>
<p >        PBDefault.BeginAnimation(ProgressBar.ValueProperty, a)</p>
<p >    <span >End</span> <span >Sub</span> </p>
</div>
<p>When you run this, completed ProgressBars are reasonably close in looks, the only major difference being that the templated one at the bottom runs right to left.</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs022.png" alt=""></p>
<p> </p>
<p>Although the creation of the ControlTemplate was only a few minutes work and opens the way for further visual changes (which I&#39;ll probably blog about later), if you just want the default ProgressBar reversed, the simple way is as follows:</p>
<p>Add a new ProgressBar to the Window, but this time include a LayoutTransform to rotate it 180 degrees. </p>
<div >
<p ><span >    </span><span >&lt;</span><span >ProgressBar</span> <span >x</span><span >:</span><span >Name</span><span >=&quot;PBDefaultReversed&quot;</span> </p>
<p >                 <span >Width</span><span >=&quot;150&quot;</span><span > Height</span><span >=&quot;33&quot;</span></p>
<p >                 <span >Grid.Row</span><span >=&quot;2&quot; &gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >ProgressBar.LayoutTransform</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >RotateTransform</span><span > Angle</span><span >=&quot;180&quot;</span> <span >/&gt;</span></p>
<p ><span >      </span><span >&lt;/</span><span >ProgressBar.LayoutTransform</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ProgressBar</span><span >&gt;</span> </p>
</div>
<p>(You&#39;ll also need to add the extra row to the Grid if you are following along and creating this sample yourself:) </p>
<div >
<p ><span >    </span><span >&lt;</span><span >Grid.RowDefinitions</span><span >&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >RowDefinition</span><span > Height</span><span >=&quot;87*&quot; /&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >RowDefinition</span><span > Height</span><span >=&quot;85*&quot; /&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >RowDefinition</span><span > Height</span><span >=&quot;90*&quot; /&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >Grid.RowDefinitions</span><span >&gt;</span> </p>
</div>
<p>And don&#39;t forget to animate it in the code-behind.</p>
<p>The final result, with the default ProgressBar at the top, the templated one in the middle and the transformed one at the bottom, looks like this:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs024.png" alt=""></p>
<p>I chose not to use a gradient for the background Gray, but of course you can implement this if you prefer.</p>
<div ></div>
<p><img src="http://cs.vbcity.com/aggbug.aspx?PostID=286" width="1" height="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/10016/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF: Changing ProgressBar Appearance As Values Change</title>
		<link>http://zdima.net/blog/archives/9623</link>
		<comments>http://zdima.net/blog/archives/9623#comments</comments>
		<pubDate>Mon, 30 Nov 2009 07:22:00 +0000</pubDate>
		<dc:creator>XTab</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Contributors]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Brushes]]></category>
		<category><![CDATA[ControlTemplate]]></category>
		<category><![CDATA[DataTrigger]]></category>
		<category><![CDATA[FindName]]></category>
		<category><![CDATA[FindResource]]></category>
		<category><![CDATA[Gradient]]></category>
		<category><![CDATA[LinearGradientBrush]]></category>
		<category><![CDATA[ProgressBar]]></category>
		<category><![CDATA[ProgressBarBrushConverter]]></category>
		<category><![CDATA[Resources]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[Visual Basic WPF]]></category>
		<category><![CDATA[Visual Basic.NET]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=9623</guid>
		<description><![CDATA[
 

IntroductionIn this earlier blog, I looked at how to create a non-rectangular ProgressBar. As the next step, I want to look at how you can change properties dynamically as the current Value of the ProgressBar changes. 
I&#39;ll start with the eas...<p class="read-more"><a href="http://zdima.net/blog/archives/9623">> Read more</a></p>]]></description>
			<content:encoded><![CDATA[<p><span ></span></p>
<p> </p>
</p>
<p><span >Introduction</span><br />In <a href="http://cs.vbcity.com/blogs/xtab/archive/2009/11/24/wpf-controltemplates-creating-a-non-rectangular-progressbar.aspx">this earlier blog</a>, I looked at how to create a non-rectangular ProgressBar. As the next step, I want to look at how you can change properties dynamically as the current Value of the ProgressBar changes. </p>
<p>I&#39;ll start with the easy (and fairly realistic) scenario where you want to tone down the ProgressBar once it has reached its maximum value.</p>
<p>Currently the ProgressBar coloring looks like this:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs004.png" alt=""></p>
<p>If you want to apply changes to the look of the ProgressBar as it is running, you can use a DataTrigger in XAML or you can simply use the ValueChanged event of the ProgressBar in the code-behind. I say &quot;simply&quot;, but you do in fact have to understand how to dig into the ControlTemplate and drill down in order to make the code-behind approach work. </p>
<p>There&#39;s a trade-off between these two approaches &#8211; DataTrigger or code-behind. DataTrigger offers a slightly more concise syntax, but only as long as your requirements are very basic. Once you step beyond the absolute basics, the XAML becomes quite complex. And as you are no doubt more familiar with VB, what&#39;s the point in struggling just to prove the point that it <i>can</i> be created in XAML? Sometimes, common sense has to win over technical ego. </p>
<p>Overall, in most cases, code-behind is the easiest answer. But just to be sure you know what a DataTrigger is and how it works, let&#39;s run through it. </p>
<p><span >DataTrigger</span><br />A DataTrigger is fired (and as a result some predefined change happens) when a value is reached. In the scenario we are looking at here, a DataTrigger could be set to fire when the Value property of a ProgressBar reaches its maximum. So in the case of the ProgressBar defined below that would of course be when it reaches 100.  </p>
<div >
<p ><span >    </span><span >&lt;</span><span >ProgressBar</span><span > x</span><span >:</span><span >Name</span><span >=&quot;CurvyPB&quot;</span><span > Width</span><span >=&quot;300&quot;</span><span > Height</span><span >=&quot;60&quot;</span></p>
<p >       <span >Template</span><span >=&quot;{</span><span >StaticResource</span><span > PBCurvy</span><span >}&quot;</span></p>
<p >       <span >Foreground</span><span >=&quot;{</span><span >StaticResource</span><span > BlueGreenRed</span><span >}&quot;</span> </p>
<p >       <span >Minimum</span><span >=&quot;0&quot;</span><span > Maximum</span><span >=&quot;100&quot; /&gt;</span> </p>
</div>
<p>The &#39;predefined change&#39; might be to alter the color of the outside edge of the control and also to dim its Opacity, so that it can be more easily ignored now that its work is done.</p>
<p>The DataTrigger sits in a Triggers collection in the ControlTemplate for the ProgressBar. The syntax is as follows: </p>
<div >
<p ><span >      </span><span >&lt;</span><span >ControlTemplate.Triggers</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >DataTrigger</span><span > Binding</span><span >=&quot;{</span><span >Binding</span><span > RelativeSource</span><span >={</span><span >RelativeSource</span><span > Self</span><span >},</span><span > Path</span><span >=Value}&quot;</span> </p>
<p >                    <span >Value</span><span >=&quot;100&quot;&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >Setter</span><span > TargetName</span><span >=&quot;PART_Track&quot;</span><span > Property</span><span >=&quot;Stroke&quot;</span><span > Value</span><span >=&quot;DarkGray&quot; /&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >Setter</span><span > TargetName</span><span >=&quot;PART_Track&quot;</span><span > Property</span><span >=&quot;Opacity&quot;</span><span > Value</span><span >=&quot;0.3&quot; /&gt;</span></p>
<p ><span >        </span><span >&lt;/</span><span >DataTrigger</span><span >&gt;</span></p>
<p ><span >      </span><span >&lt;/</span><span >ControlTemplate.Triggers</span><span >&gt;</span> </p>
</div>
<p>(Note that this is only one section of the complete ControlTemplate.) </p>
<p>The DataTrigger Binding looks awkward and is one of those rather peculiar constructs that makes XAML hard to decipher (and create) sometimes. Essentially it translates to : <br />&quot;Keep checking the Value property of the ProgressBar instance that is using this ControlTemplate. If and when it reaches a Value of 100, fire the trigger.&quot;</p>
<p>The Setters both target the Path named &#39;PART_Track&#39;. The first changes the Stroke to DarkGray and the second one turns down the Opacity of that Path (which effectively reduces the Opacity of the templated ProgressBar).</p>
<p>Here is the full XAML for the Window which contains the ControlTemplate and the ProgressBar instance: </p>
<div >
<p ><span >&lt;</span><span >Window</span><span > x</span><span >:</span><span >Class</span><span >=&quot;CurvyWithTriggers&quot;</span></p>
<p >   <span >xmlns</span><span >=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></p>
<p >   <span >xmlns</span><span >:</span><span >x</span><span >=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></p>
<p >   <span >xmlns</span><span >:</span><span >converter</span><span >=&quot;clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna&quot;</span>   </p>
<p >   <span >Title</span><span >=&quot;Curved ProgressBar&quot;</span><span > Height</span><span >=&quot;200&quot;</span><span > Width</span><span >=&quot;400&quot;&gt;</span></p>
<p ><span >  </span><span >&lt;</span><span >Window.Resources</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >ControlTemplate</span><span > x</span><span >:</span><span >Key</span><span >=&quot;PBCurvy&quot;</span><span > TargetType</span><span >=&quot;{</span><span >x</span><span >:</span><span >Type</span><span > ProgressBar</span><span >}&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >Grid</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >Path</span><span > x</span><span >:</span><span >Name</span><span >=&quot;PART_Track&quot;</span> </p>
<p >             <span >Stroke</span><span >=&quot;{</span><span >StaticResource</span><span > BlueGreenRed</span><span >}&quot;</span> </p>
<p >             <span >StrokeThickness</span><span >=&quot;5&quot;</span> </p>
<p >             <span >Data</span><span >=&quot;F1 M46.802502,0.50000018 C59.803562,0.50000006 71.553123,3.7052743 79.942001,</span></p>
<p ><span >              8.9014616 C88.330879,3.7052746 100.08044,0.5 113.0815,0.50000018 C125.92575,</span></p>
<p ><span >              0.5 137.54851,3.6284194 145.9305,8.6908474 C154.3125,3.6284194 165.93524,</span></p>
<p ><span >              0.50000006 178.7795,0.50000018 C204.35167,0.5 225.082,12.900593 225.082,</span></p>
<p ><span >              28.1975 C225.082,43.494408 204.35167,55.895 178.7795,55.895 C165.93524,</span></p>
<p ><span >              55.895 154.3125,52.766582 145.9305,47.704151 C137.54851,52.766582 125.92575,</span></p>
<p ><span >              55.895 113.0815,55.895 C100.08044,55.895 88.330879,52.689728 79.942001,</span></p>
<p ><span >              47.493538 C71.553123,52.689728 59.803562,55.895 46.802502,55.895 21.230335,</span></p>
<p ><span >              55.895 0.5,43.494408 0.5,28.1975 0.5,12.900593 21.230335,0.5 46.802502,</span></p>
<p ><span >              0.50000018 z&quot;</span></p>
<p >             <span >Stretch</span><span >=&quot;Fill&quot;&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >Path.Fill</span><span >&gt;</span></p>
<p ><span >            </span><span >&lt;</span><span >MultiBinding</span><span >&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >MultiBinding.Converter</span><span >&gt;</span></p>
<p ><span >                </span><span >&lt;</span><span >converter</span><span >:</span><span >ProgressBarBrushConverter</span><span > /&gt;</span></p>
<p > </p>
<p ><span >              </span><span >&lt;/</span><span >MultiBinding.Converter</span><span >&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >Binding</span><span > Path</span><span >=&quot;Foreground&quot;</span><span > RelativeSource</span><span >=&quot;{</span><span >RelativeSource</span><span > TemplatedParent</span><span >}&quot; /&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >Binding</span><span > Path</span><span >=&quot;IsIndeterminate&quot;</span><span > RelativeSource</span><span >=&quot;{</span><span >RelativeSource</span><span > TemplatedParent</span><span >}&quot; /&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >Binding</span><span > Path</span><span >=&quot;ActualWidth&quot;</span><span > ElementName</span><span >=&quot;PART_Indicator&quot; /&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >Binding</span><span > Path</span><span >=&quot;ActualHeight&quot;</span><span > ElementName</span><span >=&quot;PART_Indicator&quot; /&gt;</span></p>
<p ><span >              </span><span >&lt;</span><span >Binding</span><span > Path</span><span >=&quot;ActualWidth&quot;</span><span > ElementName</span><span >=&quot;PART_Track&quot; /&gt;</span></p>
<p > </p>
<p ><span >            </span><span >&lt;/</span><span >MultiBinding</span><span >&gt;</span></p>
<p ><span >          </span><span >&lt;/</span><span >Path.Fill</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;/</span><span >Path</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >Decorator</span><span > x</span><span >:</span><span >Name</span><span >=&quot;PART_Indicator&quot; /&gt;</span></p>
<p ><span >       </span><span >&lt;/</span><span >Grid</span><span >&gt;</span></p>
<p > </p>
<p ><span >      </span><span >&lt;</span><span >ControlTemplate.Triggers</span><span >&gt;</span></p>
<p ><span >        </span><span >&lt;</span><span >DataTrigger</span><span > Binding</span><span >=&quot;{</span><span >Binding</span><span > RelativeSource</span><span >={</span><span >RelativeSource</span><span > Self</span><span >},</span><span > Path</span><span >=Value}&quot;</span> </p>
<p >                    <span >Value</span><span >=&quot;100&quot;&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >Setter</span><span > TargetName</span><span >=&quot;PART_Track&quot;</span><span > Property</span><span >=&quot;Stroke&quot;</span><span > Value</span><span >=&quot;DarkGray&quot; /&gt;</span></p>
<p ><span >          </span><span >&lt;</span><span >Setter</span><span > TargetName</span><span >=&quot;PART_Track&quot;</span><span > Property</span><span >=&quot;Opacity&quot;</span><span > Value</span><span >=&quot;0.3&quot; /&gt;</span></p>
<p ><span >        </span><span >&lt;/</span><span >DataTrigger</span><span >&gt;</span></p>
<p ><span >      </span><span >&lt;/</span><span >ControlTemplate.Triggers</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ControlTemplate</span><span >&gt;</span></p>
<p > </p>
<p ><span >  </span><span >&lt;/</span><span >Window.Resources</span><span >&gt;</span></p>
<p ><span >  </span><span >&lt;</span><span >Grid</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >ProgressBar</span><span > x</span><span >:</span><span >Name</span><span >=&quot;CurvyPB&quot;</span><span > Width</span><span >=&quot;300&quot;</span><span > Height</span><span >=&quot;60&quot;</span></p>
<p >       <span >Template</span><span >=&quot;{</span><span >StaticResource</span><span > PBCurvy</span><span >}&quot;</span></p>
<p >       <span >Foreground</span><span >=&quot;{</span><span >StaticResource</span><span > BlueGreenRed</span><span >}&quot;</span> </p>
<p >       <span >Minimum</span><span >=&quot;0&quot;</span><span > Maximum</span><span >=&quot;100&quot; /&gt;</span></p>
<p > </p>
<p ><span >  </span><span >&lt;/</span><span >Grid</span><span >&gt;</span></p>
<p ><span >&lt;/</span><span >Window</span><span >&gt;</span> </p>
</div>
<p>This markup in the Application.xaml file creates the LinearGradientBrush: </p>
<div >
<p ><span >    </span><span >&lt;</span><span >Application.Resources</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >LinearGradientBrush</span><span > x</span><span >:</span><span >Key</span><span >=&quot;BlueGreenRed&quot;</span> </p>
<p >       <span >EndPoint</span><span >=&quot;1,0.5&quot;</span><span > StartPoint</span><span >=&quot;0,0.5&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FF2D3ADD&quot;</span><span > Offset</span><span >=&quot;0&quot;/&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FFF13E14&quot;</span><span > Offset</span><span >=&quot;1&quot;/&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FF9775D8&quot;</span><span > Offset</span><span >=&quot;0.192&quot;/&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FF3F893B&quot;</span><span > Offset</span><span >=&quot;0.481&quot;/&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FF2B9518&quot;</span><span > Offset</span><span >=&quot;0.625&quot;/&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >GradientStop</span><span > Color</span><span >=&quot;#FECC7638&quot;</span><span > Offset</span><span >=&quot;0.812&quot;/&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >LinearGradientBrush</span><span >&gt;</span></p>
<p ><span >  </span><span >&lt;/</span><span >Application.Resources</span><span >&gt;</span> </p>
</div>
<p>The code-behind to animate the ProgressBar: </p>
<div >
<p ><span >Imports</span> System.Windows.Media.Animation</p>
<p > </p>
<p ><span >Partial</span> <span >Public</span> <span >Class</span> CurvyWithTriggers</p>
<p > </p>
<p >    <span >Private</span> <span >Sub</span> CurvyWithTriggers_Loaded(<span >ByVal</span> sender <span >As</span> <span >Object</span>, <span >ByVal</span> e <span >As</span> System.Windows.RoutedEventArgs) <span >Handles</span> <span >Me</span>.Loaded</p>
<p >        <span >Dim</span> a <span >As</span> <span >New</span> DoubleAnimation</p>
<p >        a.From = 0</p>
<p >        a.To = 100</p>
<p >        a.Duration = <span >New</span> TimeSpan(0, 0, <img src='http://zdima.net/blog/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> </p>
<p > </p>
<p >        CurvyPB.BeginAnimation(ProgressBar.ValueProperty, a)</p>
<p >    <span >End</span> <span >Sub</span></p>
<p ><span >End</span> <span >Class</span> </p>
</div>
<p>Apologies if you already have all that code and markup from the previous blog. Personally I hate it when someone says &quot;I&#39;ve used the same code as in my earlier blog&quot;, which means I then have to go and find that blog, dig through it and find the missing bits before I can test out what I&#39;m working on now. So I much prefer to repeat it and make life easier for you, at the expense of a slightly longer blog entry.</p>
<p>After the ProgressBar completes its mission, it hits that Value of 100 and the look changes to this:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs005.png" alt=""></p>
<p>So if you&#39;re sat there saying to yourself that there&#39;s nothing there that you couldn&#39;t have easily done in code-behind, I almost agree with you. Certainly the Opacity change would be easy: </p>
<div >
<p >        <span >If</span> progressBar1.Value = 100 <span >Then</span></p>
<p >            progressBar1.Opacity = 0.3</p>
<p >        <span >End</span> <span >If</span> </p>
</div>
<p>But what about changing the value of the Stroke property though? The ProgressBar doesn&#39;t have a Stroke property. That&#39;s tucked away inside the ControlTemplate and is a property of the Path named PART_Track. To get to that, we will need a way to access the ControlTemplate and then drill down into the Path.</p>
<p>Before we look at the code-behind approach, I just want to mention a problem with DataTriggers, especially as they relate to ProgressBars. The only arithmetic operator available to you in the DataTrigger in XAML is the equals operator. For fairly obvious reasons, the less-than and greater-then operator symbols have the potential to cause problems in a language that uses them as element delimiters. </p>
<p>The reason that this is a particular problem with the ProgressBar is that the algorithm that breaks the ProgressBar movement into its time chunks will rarely, if ever, space them across whole numbers. That is to say if the Minimum Value is 0 and the Maximum Value is 100 and the duration is 10 seconds, you might reasonably suppose that each new block will appear at intervals of 0, 10, 20, 30, etc. However it doesn&#39;t work that way and the values are more likely to be something like : <br />0 <br />0.252538 <br />0.299015 <br />0.613981 <br />: etc <br />: ending with <br />99.769844 <br />99.890324 <br />100 </p>
<p>This makes it impossible for you to set a DataTrigger on a value that you can be certain will be matched exactly, except for the starting and ending values of 0 and 100. In theory, you could tweak the size settings of the PART_Track and PART_Indicator to ensure whole number partitions (these being the key factors in the breakdown), but none of my experimenting with this approach worked. An alternative approach, which I haven&#39;t tried, would be to create a ValueConverter which would then allow you to set value parameters, such as &lt; 20 or &gt; 40 and so on. However, I didn&#39;t really see any gain in going that route, as I can use the ValueChanged event of the ProgressBar directly, together with a bit of WPF delving, as we will now see. </p>
<p><span >FindResource and FindName</span><br />When you need to get at a ControlTemplate (or other Resource, for that matter), you can use the FindResource method of the FrameworkElement class. Before, I get into that, I am going to make two changes to the markup in the Window. <br />The first change is to add a Name property to the Window, placing this inside the opening tag of the Window class markup:  </p>
<div >
<p ><span > x</span><span >:</span><span >Name</span><span >=&quot;CurvyValueChangedWindow&quot;</span> </p>
</div>
<p>This is necessary in order for the Window to be accessed from the code-behind.</p>
<p>The second change is purely decorative &#8211; changing the Stroke property of the PART_Track path from the LinearGradientBrush to plain Yellow.  </p>
<div >
<p ><span >        </span><span >&lt;</span><span >Path</span><span > x</span><span >:</span><span >Name</span><span >=&quot;PART_Track&quot;</span> </p>
<p >             <span >Stroke</span><span >=&quot;Yellow&quot;</span> </p>
</div>
<p> The ProgressBar now looks like this at startup:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs006.png" alt=""></p>
<p>To locate that ControlTemplate, I use the following code, which I have placed in the ValueChanged event of the ProgressBar: </p>
<div >
<p >        <span >Dim</span> ct <span >As</span> <span >New</span> ControlTemplate()</p>
<p >        <span >Try</span></p>
<p >            ct = <span >CType</span>(CurvyValueChangedWindow.FindResource(<span >&quot;PBCurvy&quot;</span>), ControlTemplate)</p>
<p > </p>
<p >        <span >Catch</span> Ex <span >As</span> ResourceReferenceKeyNotFoundException</p>
<p >            <span >&#39;  Design time message</span></p>
<p >            Console.WriteLine(<span >&quot;CT Not found&quot;</span>)</p>
<p >            <span >&#39;  Quit gracefully if not found</span></p>
<p >            <span >Exit</span> <span >Sub</span></p>
<p >        <span >End</span> <span >Try</span> </p>
</div>
<p>The third line does all the work and you will see now why I added a name to the WPF Window. This Name is used to identify the container in which the Resource named PBCurvy (i.e. the ControlTemplate) should be found. <br />Note also that if due to a typo or other error the Resource can&#39;t be found, then no further action will be taken. At this stage, the Catch is superfluous. It is however important to avoid the application crashing as we move on to the next step.</p>
<p><span >FindName</span><br />So now we have got ourselves a reference to the ControlTemplate, but we still need to drill down into the Path named PART_Track which is a sub-element of that template. To do this, you can use the following code, placing it immediately below the code used to find the ControlTemplate resource:  </p>
<div >
<p >        <span >Dim</span> p <span >As</span> <span >New</span> Path</p>
<p >        p = <span >CType</span>(ct.FindName(<span >&quot;PART_Track&quot;</span>, PBCurvy), Path)</p>
<p > </p>
<p >        <span >If</span> IsNothing(p) <span >Then</span></p>
<p >            Console.WriteLine(<span >&quot;Path Not found&quot;</span>)</p>
<p >            <span >Exit</span> <span >Sub</span></p>
<p >        <span >End</span> <span >If</span> </p>
</div>
<p>This time the FindName function searches through that ControlTemplate (now referenced as &#39;ct&#39;) in order to find the named Path. <br />Once again, the test for IsNothing isn&#39;t necessary at this stage, because we have not yet tried to do anything with the Path variable &#39;p&#39;. As before though, when we add further code, this checkpoint &#8211; and the Exit Sub if the Path isn&#39;t found &#8211; are important. </p>
<p><span >Changing The values</span><br />We&#39;ve now reached the point where we can manipulate values of that Path according to the current values of the ProgressBar. This code placed immediately below the previous snippet will change the color and thickness of the Stroke: </p>
<div >
<p >        <span >Select</span> <span >Case</span> PBCurvy.Value</p>
<p >            <span >Case</span> <span >Is</span> &lt; 25</p>
<p >                p.Stroke = <span >New</span> SolidColorBrush(Colors.Yellow)</p>
<p >                p.StrokeThickness = 5</p>
<p >            <span >Case</span> 25 <span >To</span> 49</p>
<p >                p.Stroke = <span >New</span> SolidColorBrush(Colors.Green)</p>
<p >                p.StrokeThickness = 7</p>
<p >            <span >Case</span> 50 <span >To</span> 75</p>
<p >                p.Stroke = <span >New</span> SolidColorBrush(Colors.Orange)</p>
<p >                p.StrokeThickness = 9</p>
<p >            <span >Case</span> 76 <span >To</span> 99</p>
<p >                p.Stroke = <span >New</span> SolidColorBrush(Colors.Red)</p>
<p >                p.StrokeThickness = 11</p>
<p >            <span >Case</span> <span >Else</span></p>
<p >                p.Stroke = <span >New</span> SolidColorBrush(Colors.DarkGray)</p>
<p >        <span >End</span> <span >Select</span> </p>
</div>
<p>When you run the application, the colors will change as things progress:   </p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs007.png" alt=""> </p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs008.png" alt=""></p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs009.png" alt=""></p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/ProgressBars/PBs010.png" alt=""></p>
<p> I have chosen to make those particular changes for demo purposes, but you are of course not limited to those. The key take away points in this blog are the availability of the DataTrigger and the use of the very helpful FindResource and FindName methods when you want to trigger a change via the code-behind.</p>
<div ></div>
<p><img src="http://cs.vbcity.com/aggbug.aspx?PostID=284" width="1" height="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/9623/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF: Displaying a Master-Detail Collection of In-Memory Objects In a TreeView</title>
		<link>http://zdima.net/blog/archives/9701</link>
		<comments>http://zdima.net/blog/archives/9701#comments</comments>
		<pubDate>Tue, 17 Nov 2009 22:32:00 +0000</pubDate>
		<dc:creator>XTab</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Contributors]]></category>
		<category><![CDATA[DataBinding]]></category>
		<category><![CDATA[DataTemplate]]></category>
		<category><![CDATA[HierarchicalDataTemplate]]></category>
		<category><![CDATA[TreeView]]></category>
		<category><![CDATA[VB.NET]]></category>
		<category><![CDATA[Visual Basic]]></category>
		<category><![CDATA[Visual Basic DataBinding]]></category>
		<category><![CDATA[Visual Basic WPF]]></category>
		<category><![CDATA[Visual Basic.NET]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=9701</guid>
		<description><![CDATA[
 IntroductionIn this earlier blog I used an XML file containing nested data items as the data source of a TreeView. In this version I will use a collection of objects as the data source. The details of the data are much the same as I used in the prev...<p class="read-more"><a href="http://zdima.net/blog/archives/9701">> Read more</a></p>]]></description>
			<content:encoded><![CDATA[<p><span ></span></p>
<p> <span >Introduction</span><br />In <a href="http://cs.vbcity.com/blogs/xtab/archive/2009/11/15/wpf-hierarchicaldatatemplates-and-master-detail-data-display.aspx">this earlier blog </a>I used an XML file containing nested data items as the data source of a TreeView. In this version I will use a collection of objects as the data source. <br />The details of the data are much the same as I used in the previous blog, with a couple of tiny changes to avoid any possible confusion caused by the use of Visual Basic keywords as field names: </p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/HDTs/HDTChart2.png" alt=""></p>
<p>These classes are saved in a VB file named SalesData.vb. Because it is fairly lengthy, filling about three screen display lengths, I&#39;ve made it available from <a href="http://www.xtabvbcity.plus.com/Blogs/HDTs/SalesDataClass.htm">this link</a>. (To a large extent, how the the data is created isn&#39;t really the topic of this blog &#8211; I&#39;m more concerned with the Binding to a source and the templates used for displaying the data.) </p>
<p><span >Mapping to the local Assembly </span><br />In order to be able to access those SalesPerson, SalesOrder, etc classes and objects in the XAML file, it is necessary to create a mapping. The syntax for this is as follows:  </p>
<div >
<p >  <span >xmlns</span><span >:</span><span >local</span><span >=&quot;clr-namespace:HierarchicalDataTemplate&quot;</span> </p>
</div>
<p>It isn&#39;t mandatory to use &#39;local&#39; as the mapping alias, but it&#39;s a fairly traditional approach. In this case, of course &#39;HierarchicalDataTemplate&#39; is the name of the project I am working on. </p>
<p>With the namespace mapping in place, any of the classes that currently exist in the code-behind files of the project become visible to the XAML file. If you view the code listing for the SalesData.vb file, you will see that the class which creates the demo data is called &#39;SalesPersonList&#39;. It&#39;s now possible to create a new instance of that class in the XAML file : </p>
<div >
<p ><span >    </span><span >&lt;</span><span >local</span><span >:</span><span >SalesPersonList</span><span > x</span><span >:</span><span >Key</span><span >=&quot;SalesPersonList&quot;/&gt;</span> </p>
</div>
<p>I generally place this in the Window.Resources collection.</p>
<p><span >Creating a TreeView and Binding its Data Source</span> <br />In the markup for the Window itself, I&#39;ll create a TreeView which contains a single TreeViewItem.  </p>
<div >
<p ><span >    </span><span >&lt;</span><span >TreeView</span><span >&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >TreeViewItem</span><span > ItemsSource</span><span >=&quot;{</span><span >Binding</span><span > Source</span><span >={</span><span >StaticResource</span><span > SalesPersonList</span><span >}}&quot;</span></p>
<p >          <span >Header</span><span >=&quot;Sales Figures&quot; /&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >TreeView</span><span >&gt;</span> </p>
</div>
<p>The ItemsSource is the crucial property here. It identifies exactly where the TreeView should look for its data. In this case it looks into the SalesPersonList instance that I created a few moments ago. For the avoidance of doubt, the exact &#39;SalesPersonList&#39; that is used is the StaticResource created earlier and identified by the Key. (I possibly should have used a different name for the Key and the underlying Class to avoid any confusion). </p>
<p>Because of the use of the Binding and the HierarchicalDataTemplates, it is only necessary to create this single TreeViewItem. The Binding engine will trawl through all the data and create as many TreeViewItem nodes as it needs to in order to display everything correctly. </p>
<p><span >HierarchicalDataTemplates</span><br />This example uses three HierarchicalDataTemplates, plus a standard DataTemplate for the SalesItems. Here is the first one (which again I&#39;ve placed in the Window.Resources collection):  </p>
<div >
<p ><span >    </span><span >&lt;</span><span >HierarchicalDataTemplate</span><span > DataType</span><span >=&quot;{</span><span >x</span><span >:</span><span >Type</span><span > local</span><span >:</span><span >SalesPerson</span><span >}&quot;</span></p>
<p >          <span >ItemsSource</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=Periods}&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >TextBlock</span><span > Text</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=Name}&quot;/&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >HierarchicalDataTemplate</span><span >&gt;</span> </p>
</div>
<p>The DataType property identifies which type of object will be dealt with by this template. In the case of this first template, this will be the SalesPerson type. In other words, when the Binding that I placed on the TreeViewItem finds any instance of a SalesPerson inside that SalesPersonList, it will look at this template to discover how it should display SalesPerson details. <br />In this case, the Name property of the current SalesPerson will be shown in a TextBlock. <br />The ItemsSource property also uses a Binding, but it is only interested in knowing what needs to be shown as the child data of SalesPersons. As we know from the diagram above, this will be the Periods data. </p>
<p>If you are finding the DataType and the Bindings&#39; Paths a bit tricky to grasp, it may help if you run the project as it currently stands. Here&#39;s the markup for the Window so far: </p>
<div >
<p ><span >&lt;</span><span >Window</span><span > x</span><span >:</span><span >Class</span><span >=&quot;OrdersListsDisplay&quot;</span></p>
<p >   <span >xmlns</span><span >=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></p>
<p >   <span >xmlns</span><span >:</span><span >x</span><span >=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></p>
<p >   <span >xmlns</span><span >:</span><span >local</span><span >=&quot;clr-namespace:HierarchicalDataTemplate&quot;</span></p>
<p >   <span >Title</span><span >=&quot;Sales List Display&quot;</span><span > Height</span><span >=&quot;300&quot;</span><span > Width</span><span >=&quot;300&quot;&gt;</span></p>
<p ><span >  </span><span >&lt;</span><span >Window.Resources</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >local</span><span >:</span><span >SalesPersonList</span><span > x</span><span >:</span><span >Key</span><span >=&quot;SalesPersonList&quot;/&gt;</span></p>
<p > </p>
<p ><span >    </span><span >&lt;!&#8211;  Data Templates &#8211;&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >HierarchicalDataTemplate</span><span > DataType</span><span >=&quot;{</span><span >x</span><span >:</span><span >Type</span><span > local</span><span >:</span><span >SalesPerson</span><span >}&quot;</span></p>
<p >          <span >ItemsSource</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=Periods}&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >TextBlock</span><span > Text</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=Name}&quot;/&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >HierarchicalDataTemplate</span><span >&gt;</span></p>
<p > </p>
<p ><span >  </span><span >&lt;/</span><span >Window.Resources</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >Grid</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >TreeView</span><span >&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >TreeViewItem</span><span > ItemsSource</span><span >=&quot;{</span><span >Binding</span><span > Source</span><span >={</span><span >StaticResource</span><span > SalesPersonList</span><span >}}&quot;</span></p>
<p >          <span >Header</span><span >=&quot;Sales Figures&quot; /&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >TreeView</span><span >&gt;</span></p>
<p ><span >  </span><span >&lt;/</span><span >Grid</span><span >&gt;</span></p>
<p ><span >&lt;/</span><span >Window</span><span >&gt;</span> </p>
</div>
<p>When you run this, you will first see:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/HDTs/HDT003.png" alt=""></p>
<p>Then, when you expand the first node, you will have:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/HDTs/HDT004.png" alt=""></p>
<p>Finally, clicking on either or both the SalesPerson nodes, you will see that the application has tried to display the children of the SalesPersons for you. In the absence of any instruction about formatting the Periods, it simply reverts to displaying the default ToString rendering of the class. </p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/HDTs/HDT005.png" alt=""></p>
<p>Hopefully though you can now see why the template points to SalesPerson as its DataType, but identifies the next level down the tree as the ItemsSource. (You may have noticed that this wasn&#39;t necessary with the XML data example in the earlier blog, where simply assigning a Binding without a Path will work.) </p>
<p><span >Displaying Periods and SalesOrders</span><br />Exactly the same approach is used for the next two templates: </p>
<div >
<p ><span >    </span><span >&lt;</span><span >HierarchicalDataTemplate</span><span > DataType</span><span >=&quot;{</span><span >x</span><span >:</span><span >Type</span><span > local</span><span >:</span><span >Period</span><span >}&quot;</span></p>
<p >          <span >ItemsSource</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=SalesOrders}&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >TextBlock</span><span > Text</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=Name}&quot;/&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >HierarchicalDataTemplate</span><span >&gt;</span></p>
<p > </p>
<p ><span >    </span><span >&lt;</span><span >HierarchicalDataTemplate</span><span > DataType</span><span >=&quot;{</span><span >x</span><span >:</span><span >Type</span><span > local</span><span >:</span><span >SalesOrder</span><span >}&quot;</span></p>
<p >         <span >ItemsSource</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=SalesItems}&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >TextBlock</span><span > Text</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=Name}&quot;/&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >HierarchicalDataTemplate</span><span >&gt;</span> </p>
</div>
<p>The three HierarchicalDataTemplates in place so far will produce this result:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/HDTs/HDT006.png" alt=""></p>
<p>which should come as no surprise, based on what I explained earlier. </p>
<p><span >ItemDetail DataTemplate</span><br />So that just leaves the template for the SalesItems and ItemDetail data. This time a standard DataTemplate will do, because we know there is no further data below ItemDetail.  </p>
<div >
<p ><span >    </span><span >&lt;</span><span >DataTemplate</span><span > DataType</span><span >=&quot;{</span><span >x</span><span >:</span><span >Type</span><span > local</span><span >:</span><span >SalesItem</span><span >}&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >TextBlock</span><span > Text</span><span >=&quot;{</span><span >Binding</span><span > Path</span><span >=ItemDetail}&quot;/&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >DataTemplate</span><span >&gt;</span> </p>
</div>
<p>Just for the record, a HierarchicalDataTemplate would work but isn&#39;t necessary. With the final DataTemplate added, every level of the Master-Detail data can be accessed:</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/HDTs/HDT007.png" alt=""></p>
<p><span >Formatting</span><br />You have many options for formatting the final presentation of the data. In this example, you can change the color, font size and weight, indentation, etc via the individual TextBlock properties. If you wanted to insert additional graphical detail (such as an icon), you simply wrap the TextBlock in a StackPanel with its Orientation set to Horizontal. You can then insert the icon image as an additional child of this StackPanel. </p>
<p>You can build on this basic example shown here to create a much more complex display.</p>
<div ></div>
<p><img src="http://cs.vbcity.com/aggbug.aspx?PostID=287" width="1" height="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/9701/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Create and Use a Custom Command in WPF</title>
		<link>http://zdima.net/blog/archives/9005</link>
		<comments>http://zdima.net/blog/archives/9005#comments</comments>
		<pubDate>Mon, 02 Nov 2009 04:45:00 +0000</pubDate>
		<dc:creator>XTab</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Contributors]]></category>
		<category><![CDATA[Commands]]></category>
		<category><![CDATA[Custom Command]]></category>
		<category><![CDATA[Visual Basic]]></category>
		<category><![CDATA[Visual Basic WPF]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://zdima.net/blog/?p=9005</guid>
		<description><![CDATA[
  I&#39;ve got to be honest and admit up front that initially I wasn&#39;t completely sold on the idea that WPF Commands are the great leap forward that they are sometimes billed as. OK, so I get that they can reduce the repetition of event handling...<p class="read-more"><a href="http://zdima.net/blog/archives/9005">> Read more</a></p>]]></description>
			<content:encoded><![CDATA[<p><span ></span></p>
<p>  I&#39;ve got to be honest and admit up front that initially I wasn&#39;t completely sold on the idea that WPF Commands are the great leap forward that they are sometimes billed as. OK, so I get that they can reduce the repetition of event handling code, but even their most ardent supporters aren&#39;t going to be able to claim that the required code is particularly intuitive. I will agree though that the availability of CanExecute is useful sometimes when multiple controls are bound to a Command. As a WinForms developer moving to WPF, I still find that in many cases I&#39;m happy to use event handlers and, where necessary, a utility method or two. </p>
<p>So, having got that caveat out of the way, let&#39;s look at a basic situation where we want a range of different user actions to trigger the same task. </p>
<p>I&#39;ve decided to use the scenario that I covered in <a href="http://cs.vbcity.com/blogs/xtab/archive/2009/10/27/wpf-how-to-move-elements-at-runtime.aspx">this blog</a>. It&#39;s maybe not the most realistic scenario, but it does give an opportunity to use a wide range of user inputs and gestures to move the image across the screen. It also allows the use of the CanExecute event. </p>
<p>In the earlier blog, the user had to click on an image to make it move from left to right across a Canvas. This can soon become tiresome, so by means of a Command we&#39;ll give her several other options. In order to make the use of CanExecute realistic, we will say that once the image reaches the far right edge of the Canvas, it must stay there. So the image move will be allowed to happen (i.e. CanExecute) as long as it hasn&#39;t reached the right hand edge of the canvas. </p>
<p><span >Creating the User Interface</span><br />The following XAML will create an updated version of the Canvas-and-Image UI used previously. This version includes various controls that will be bound to the Command. </p>
<div >
<p ><span >&lt;</span><span >Window</span><span > x</span><span >:</span><span >Class</span><span >=&quot;Window3&quot;</span></p>
<p >   <span >xmlns</span><span >=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></p>
<p >   <span >xmlns</span><span >:</span><span >x</span><span >=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></p>
<p > </p>
<p >   <span >Title</span><span >=&quot;Using A Command&quot;</span><span > Height</span><span >=&quot;300&quot;</span><span > Width</span><span >=&quot;300&quot;&gt;</span></p>
<p > </p>
<p > </p>
<p ><span >    </span><span >&lt;</span><span >Grid</span><span > x</span><span >:</span><span >Name</span><span >=&quot;MainGrid&quot;&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >Grid.RowDefinitions</span><span >&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >RowDefinition</span><span > Height</span><span >=&quot;Auto&quot; /&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >RowDefinition</span><span > Height</span><span >=&quot;218*&quot; /&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >RowDefinition</span><span > Height</span><span >=&quot;Auto&quot; /&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >Grid.RowDefinitions</span><span >&gt;</span></p>
<p > </p>
<p > </p>
<p ><span >      </span><span >&lt;!&#8211;  Canvas in the main middle section &#8211;&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >Canvas</span><span > x</span><span >:</span><span >Name</span><span >=&quot;MainCanvas&quot;</span><span > Grid.Row</span><span >=&quot;1&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >Image</span><span > x</span><span >:</span><span >Name</span><span >=&quot;MoveableImage&quot;</span><span > Width</span><span >=&quot;55&quot;</span><span > Source</span><span >=&quot;questionmark2.jpg&quot;</span></p>
<p > </p>
<p >        <span >Canvas.Left</span><span >=&quot;0&quot;</span><span > Canvas.Top</span><span >=&quot;0&quot; /&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >Canvas</span><span >&gt;</span></p>
<p > </p>
<p ><span >    </span><span >&lt;!&#8211; Menu at the top &#8211;&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >Menu</span><span > Grid.Row</span><span >=&quot;0&quot;</span><span > Margin</span><span >=&quot;3&quot;&gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >MenuItem</span><span > Header</span><span >=&quot;Move It&quot;</span><span > Margin</span><span >=&quot;5&quot;</span></p>
<p > </p>
<p >               <span >&gt;&lt;/</span><span >MenuItem</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >Menu</span><span >&gt;</span></p>
<p > </p>
<p ><span >    </span><span >&lt;</span><span >ToolBar</span><span > Grid.Row</span><span >=&quot;2&quot; &gt;</span></p>
<p ><span >      </span><span >&lt;</span><span >Button</span><span > Content</span><span >=&quot;Move It&quot;</span> </p>
<p >              <span >/&gt;</span></p>
<p ><span >    </span><span >&lt;/</span><span >ToolBar</span><span >&gt;</span></p>
<p > </p>
<p ><span >      </span><span >&lt;</span><span >Button</span><span > Grid.Row</span><span >=&quot;1&quot;</span><span > VerticalAlignment</span><span >=&quot;Bottom&quot;</span></p>
<p >             <span >HorizontalAlignment</span><span >=&quot;Right&quot;</span> <span >Width</span><span >=&quot;100&quot;</span></p>
<p >             <span >Height</span><span >=&quot;33&quot;</span><span > Content</span><span >=&quot;Move It&quot;</span><span > Margin</span><span >=&quot;0,0,4,2&quot;</span></p>
<p >              <span >/&gt;</span></p>
<p ><span >  </span><span >&lt;/</span><span >Grid</span><span >&gt;</span></p>
<p ><span >&lt;/</span><span >Window</span><span >&gt;</span></p>
</div>
<p> (If you&#39;ve looked at the markup closely and think that the order of elements is haphazard, you would be wrong.   Try moving the MenuItem to what seems a more logical position above the Canvas and you will get an Error when the code is completed.  As you will see, the code behind for the MenuItem will eventually have a link to the Image.   So therefore the Image must be created first in the top down XAML file, before the MenuItem can know about it .  I often think that it&#39;s these little potential Gotchas that make the WinForms-to-WPF learning curve so difficult.)</p>
<p>This is what it should look like:</p>
<p>  <img src="http://www.xtabvbcity.plus.com/Blogs/Blog%20-%20Command01.png" alt=""></p>
<p><span >Creating the Command</span><br />Let&#39;s start by creating a new Command Class called MoveItCommand. It will have a single property named MoveIt, a backing field named _move it and a parameterless constructor. The property and field are of type RoutedUICommand, but apart from that are standard and really don&#39;t need any additional explanation: </p>
<div >
<p >    <span >Private</span> <span >Shared</span> _moveit <span >As</span> RoutedUICommand</p>
<p >    <span >Public</span> <span >Shared</span> <span >ReadOnly</span> <span >Property</span> MoveIt() <span >As</span> RoutedUICommand</p>
<p >        <span >Get</span></p>
<p >            <span >Return</span> _moveit</p>
<p >        <span >End</span> <span >Get</span></p>
<p >    <span >End</span> <span >Property</span></p>
</div>
<p> The constructor is used to create the various keyboard and mouse gestures that can be used to move the image. For the purposes of demonstration, I&#39;ve gone totally overboard on these and have included four variations in the final version. But for clarity, I am only showing one in the code snippet below:</p>
<p>     <span >Shared</span> <span >Sub</span> <span >New</span>()</p>
<div >
<p >        <span >&#39;  Add keyboard and mouse gestures</span></p>
<p >        <span >Dim</span> UserInputs <span >As</span> <span >New</span> InputGestureCollection()</p>
<p >        UserInputs.Add(<span >New</span> KeyGesture(Key.M, ModifierKeys.Alt))</p>
<p > </p>
<p >         <span >&#39;  Assign these gestures to the _moveit field (and thereby to the MoveIt property)</span></p>
<p >        _moveit = <span >New</span> RoutedUICommand(<span >&quot;Move Element&quot;</span>, <span >&quot;Move&quot;</span>, <span >GetType</span>(MoveItCommand), UserInputs)</p>
<p > </p>
<p >    <span >End</span> <span >Sub</span> </p>
</div>
<ul>
<li>The constructor begins by creating a new empty collection of mouse gestures. </li>
<li>The second line creates and stores a gesture which takes the Alt and M keys as the combination to be used to fire this command. Notice the order of the keys used as arguments &#8211; effectively it is &quot;M &amp; Alt&quot; which isn&#39;t the way we usually think of the combination. If you switch the order and place the Modifier key first, you will get a runtime error. Trust me, I&#39;ve been there, done that! </li>
<li>Finally, a new RoutedCommand is created, containing descriptive text, its name, owner type (which is this custom command class &#8211; MoveItCommand), and the collection of Gestures that will work with this command. </li>
</ul>
<p> Note that all the members of this class are Shared, ensuring that only instance of the Command will be in use in the application when it runs.</p>
<p><span >Additional Gestures</span> <br />If you are happy with how the Class and its Constructor works, I&#39;ll now add in those other gestures I mentioned. These include F12 on its own, a mouse click on its own and finally a combination of mouse click and key press. Here&#39;s the revised code:  </p>
<div >
<p >    <span >Shared</span> <span >Sub</span> <span >New</span>()</p>
<p >        <span >&#39;  Add keyboard and mouse gestures</span></p>
<p >        <span >Dim</span> UserInputs <span >As</span> <span >New</span> InputGestureCollection()</p>
<p >        UserInputs.Add(<span >New</span> KeyGesture(Key.M, ModifierKeys.Alt))</p>
<p >        UserInputs.Add(<span >New</span> KeyGesture(Key.F12, ModifierKeys.None))</p>
<p >        UserInputs.Add(<span >New</span> MouseGesture(MouseAction.RightClick, ModifierKeys.None))</p>
<p >        UserInputs.Add(<span >New</span> MouseGesture(MouseAction.LeftClick, ModifierKeys.Shift))</p>
<p >         <span >&#39;  Assign these gestures to the _moveit field (and thereby to the MoveIt property)</span></p>
<p >        _moveit = <span >New</span> RoutedUICommand(<span >&quot;Move Element&quot;</span>, <span >&quot;Move&quot;</span>, <span >GetType</span>(MoveItCommand), UserInputs)</p>
<p >    <span >End</span> <span >Sub</span></p>
</div>
<p> </p>
<ul>
<li>The first gesture is Alt and M, which I&#39;ve already covered. </li>
<li>The second gesture is the F12 key on its own. Note that you must include Modifiers.None. if you don&#39;t, you will get a runtime error. </li>
<li>The third gesture will fire the command when the mouse is right clicked anywhere in the Window. Because of the way that WPF and RoutedCommands work, this effectively means that you can still click on the Image to make it move. If you wanted to limit the mouse click to the Image only, you could harness the power of Bubbling and Tunneling events to trap the mouse button press at the Image level. I haven&#39;t done that in this example. </li>
<li>The final gesture takes a combination of both the mouse left button click together with holding down the Shift key. Quite awkward to use and only included to demonstrate the range of available gestures. </li>
</ul>
<p> </p>
<p><span >Command Bindings</span><br />Having created the custom Command Class, if we want to use it in the XAML &#8211; and we do &#8211; then it is necessary to create an XML namespace mapping. Without this link, the XAML markup would have no idea about the existence of the class and its property. The syntax is fairly simple: </p>
<div >
<p >   <span >xmlns</span><span >:</span><span >local</span><span >=&quot;clr-namespace:GetValue&quot;</span> </p>
</div>
<p>The alias of &#39;local&#39; is used as the key which is mapped to the namespace in which the MoveItCommand class resides. The namespace is the same as the name of the project and in this case the project is named &#39;GetValue&#39;. </p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/Blog%20-%20Command02.png" alt=""></p>
<p>Given this namespace mapping, we can now set up the CommandBinding in the XAML pane:</p>
<p> </p>
<div >
<p ><span >  </span><span >&lt;</span><span ><a href="http://Window.Com" class="autohyperlink" title="http://Window.Com" target="_blank" rel="nofollow">Window.Com</a>mandBindings</span><span >&gt;</span></p>
<p ><span >    </span><span >&lt;</span><span >CommandBinding</span><span > Command</span><span >=&quot;local:MoveItCommand.MoveIt&quot;</span></p>
<p >                   <span >Executed</span><span >=&quot;CommandBinding_Executed&quot;</span> </p>
<p >                   <span >CanExecute</span><span >=&quot;CommandBinding_CanExecute&quot;/&gt;</span></p>
<p ><span >  </span><span >&lt;/</span><span ><a href="http://Window.Com" class="autohyperlink" title="http://Window.Com" target="_blank" rel="nofollow">Window.Com</a>mandBindings</span><span >&gt;</span></p>
</div>
<p> </p>
<p>As you see from the snippet above, you create a new CommandBinding inside a CommandBindings collection. The Command property of the CommandBinding points to that MoveIt property created in the MoveItCommand class. </p>
<p>The Executed and CanExecute properties point to two methods which we will create next in the code-behind. </p>
<p><span >Executing The CommandBinding</span> The task of the CommandBinding_Executed method is to carry out whatever tasks we want to have actioned when the command is invoked. In this demonstration project, this task is simply to shunt the image a few units to the right. So the code is as follows:  </p>
<div >
<p >    <span >Private</span> <span >Sub</span> CommandBinding_Executed(<span >ByVal</span> sender <span >As</span> System.Object, <span >ByVal</span> e <span >As</span> System.Windows.Input.ExecutedRoutedEventArgs)</p>
<p >        <span >&#39;  Move the image 5 units to the right</span></p>
<p >        <span >Dim</span> LeftPos <span >As</span> <span >Double</span> = MoveableImage.GetValue(Canvas.LeftProperty)</p>
<p >        MoveableImage.SetValue(Canvas.LeftProperty, LeftPos + 5)</p>
<p > </p>
<p >    <span >End</span> <span >Sub</span> </p>
</div>
<p>(If you are not sure about how the GetValue and SetValue functions work, you can read up on it in my blog <a href="http://cs.vbcity.com/blogs/xtab/archive/2009/10/27/wpf-how-to-move-elements-at-runtime.aspx">here</a>). </p>
<p><span >CanExecute</span><br />CanExecute is an optional feature which can be quite useful. In this demonstration, we will only allow the Command to work (and therefore only allow the Image to continue moving to the right) if it hasn&#39;t reached the right hand edge of the Canvas. More subtly, if CanExecute becomes set to False, any controls that are bound to the Command will automatically be disabled. I will add Command Bindings to the buttons, etc shortly.</p>
<p>First, here is the code for the CanExecute method: </p>
<div >
<p >    <span >Private</span> <span >Sub</span> CommandBinding_CanExecute(<span >ByVal</span> sender <span >As</span> System.Object, <span >ByVal</span> e <span >As</span> System.Windows.Input.CanExecuteRoutedEventArgs)</p>
<p >        <span >&#39;  Only allow execution of the command if the image</span></p>
<p >        <span >&#39;  has not yet reached the right hand edge.</span></p>
<p >        e.CanExecute = MoveableImage.GetValue(Canvas.LeftProperty) &lt; (MainCanvas.ActualWidth &#8211; MoveableImage.Width)</p>
<p > </p>
<p >    <span >End</span> <span >Sub</span> </p>
</div>
<p>It tests the current position of the Image to see if it has reached the right hand edge of the Canvas. CanExecute will be set to True if there is still space to the right side of the Image, otherwise it will be set to False.</p>
<p>The complete code behind for the Window and the Custom Command class together now looks like this: </p>
<div >
<p ><span >Partial</span> <span >Public</span> <span >Class</span> Window3</p>
<p > </p>
<p >    <span >Private</span> <span >Sub</span> CommandBinding_Executed(<span >ByVal</span> sender <span >As</span> System.Object, <span >ByVal</span> e <span >As</span> System.Windows.Input.ExecutedRoutedEventArgs)</p>
<p >        <span >&#39;  Move the image 5 units to the right</span></p>
<p >        <span >Dim</span> LeftPos <span >As</span> <span >Double</span> = MoveableImage.GetValue(Canvas.LeftProperty)</p>
<p >        MoveableImage.SetValue(Canvas.LeftProperty, LeftPos + 5)</p>
<p > </p>
<p >    <span >End</span> <span >Sub</span></p>
<p > </p>
<p >    <span >Private</span> <span >Sub</span> CommandBinding_CanExecute(<span >ByVal</span> sender <span >As</span> System.Object, <span >ByVal</span> e <span >As</span> System.Windows.Input.CanExecuteRoutedEventArgs)</p>
<p >        <span >&#39;  Only allow execution of the command if the image</span></p>
<p >        <span >&#39;  has not yet reached the right hand edge.</span></p>
<p >        e.CanExecute = MoveableImage.GetValue(Canvas.LeftProperty) &lt; (MainCanvas.ActualWidth &#8211; MoveableImage.Width)</p>
<p > </p>
<p >    <span >End</span> <span >Sub</span></p>
<p ><span >End</span> <span >Class</span></p>
<p > </p>
<p ><span >Public</span> <span >Class</span> MoveItCommand</p>
<p > </p>
<p >    <span >Private</span> <span >Shared</span> _moveit <span >As</span> RoutedUICommand</p>
<p >    <span >Public</span> <span >Shared</span> <span >ReadOnly</span> <span >Property</span> MoveIt() <span >As</span> RoutedUICommand</p>
<p >        <span >Get</span></p>
<p >            <span >Return</span> _moveit</p>
<p >        <span >End</span> <span >Get</span></p>
<p >    <span >End</span> <span >Property</span></p>
<p > </p>
<p >    <span >Shared</span> <span >Sub</span> <span >New</span>()</p>
<p >        <span >&#39;  Add keyboard and mouse gestures</span></p>
<p >        <span >Dim</span> UserInputs <span >As</span> <span >New</span> InputGestureCollection()</p>
<p >        UserInputs.Add(<span >New</span> KeyGesture(Key.M, ModifierKeys.Alt))</p>
<p >        UserInputs.Add(<span >New</span> KeyGesture(Key.F12, ModifierKeys.None))</p>
<p >        UserInputs.Add(<span >New</span> MouseGesture(MouseAction.RightClick, ModifierKeys.None))</p>
<p >        UserInputs.Add(<span >New</span> MouseGesture(MouseAction.LeftClick, ModifierKeys.Shift))</p>
<p >         <span >&#39;  Assign these gestures to the _moveit field (and thereby to the MoveIt property)</span></p>
<p >        _moveit = <span >New</span> RoutedUICommand(<span >&quot;Move Element&quot;</span>, <span >&quot;Move&quot;</span>, <span >GetType</span>(MoveItCommand), UserInputs)</p>
<p >    <span >End</span> <span >Sub</span></p>
<p > </p>
<p ><span >End</span> <span >Class</span> </p>
</div>
<p>At this point, you can run the project and use any of those four gestures to move the Image. Once the Image hits the right hand edge, it will stop moving. The menu item, the two buttons don&#39;t play any part in the action yet &#8211; that is, clicking them will have no effect and they won&#39;t become disabled when the Image reaches the right hand limit. </p>
<p><span >Binding the Command to the Controls</span><br />All that remains to do is to bind this custom command to the menu item and the two buttons. Now things really do become simple and you can begin to see the potential benefit of using a Command. The following piece of markup is added to the MenuItem, the Button in the Toolbar and the Button in the Canvas:  </p>
<div >
<p >        <span >Command</span><span >=&quot;local:MoveItCommand.MoveIt&quot;</span> </p>
</div>
<p>With those bindings in place, you can move the Image by any of the seven methods included &#8211; the four input gestures and by clicking on any of the three controls. Note now that once the Image hits the right hand edge, those three controls all become disabled.</p>
<p><img src="http://www.xtabvbcity.plus.com/Blogs/Blog%20-%20Command03.png" alt=""></p>
<p>So, there is a fairly simple example of using your own Command. You can see the final version of the XAML markup <a href="http://www.xtabvbcity.plus.com/Blogs/XAML.docx">here</a>, and also the code behind <a href="http://www.xtabvbcity.plus.com/Blogs/CodeBehind.docx">here</a>.</p>
<div ></div>
<p><img src="http://cs.vbcity.com/aggbug.aspx?PostID=264" width="1" height="1"></p>
]]></content:encoded>
			<wfw:commentRss>http://zdima.net/blog/archives/9005/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

