<?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>Colin Eberhardt&#039;s Adventures in .NET &#187; attached behaviour</title>
	<atom:link href="http://www.scottlogic.co.uk/blog/colin/tag/attached-behaviour/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.scottlogic.co.uk/blog/colin</link>
	<description>Colin Eberhardt&#039;s Adventures in .NET</description>
	<lastBuildDate>Thu, 09 Feb 2012 10:21:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Automatically Showing ToolTips on a Trimmed TextBlock (Silverlight)</title>
		<link>http://www.scottlogic.co.uk/blog/colin/2011/01/showing-tooltips-on-trimmed-textblock-silverlight/</link>
		<comments>http://www.scottlogic.co.uk/blog/colin/2011/01/showing-tooltips-on-trimmed-textblock-silverlight/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 08:18:54 +0000</pubDate>
		<dc:creator>Colin Eberhardt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[attached behaviour]]></category>
		<category><![CDATA[ellipsis]]></category>
		<category><![CDATA[textblock]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/colin/?p=1073</guid>
		<description><![CDATA[Silverlight 4 added TextTrimming=&#8221;WordEllipsis&#8221;, which trims the text that a TextBlock displays based on the available width. This blog post describes a simple method for automatically showing the full text as a tooltip whenever the text is trimmed. This is presented as an attached behaviour. UPDATE: I have updated this solution to support both WPF [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fcolin%252F2011%252F01%252Fshowing-tooltips-on-trimmed-textblock-silverlight%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Automatically%20Showing%20ToolTips%20on%20a%20Trimmed%20TextBlock%20%28Silverlight%29%20%23%22%20%7D);"></div>
<p><em>Silverlight 4 added TextTrimming=&#8221;WordEllipsis&#8221;, which trims the text that a TextBlock displays based on the available width. This blog post describes a simple method for automatically showing the full text  as a tooltip whenever the text is trimmed. This is presented as an attached behaviour.</em></p>
<p><b>UPDATE:</b> I have updated this solution to support both WPF and Silverlight, see my <a href="http://www.scottlogic.co.uk/blog/colin/2011/01/automatically-showing-tooltips-on-a-trimmed-textblock-silverlight-wpf/">recent blog post</a>.</p>
<p>The TextTrimming feature of SL4 allows us to worry a little less about the layout of our applications, giving the option to use fixed widths when rendering text. This can be particularly useful if you have to localize your application. However, arbitrarily trimming the text without providing the user with a mechanism to see the full text is not great for the user. A simple solution is to use a tooltip to present the full text. </p>
<p>Detecting whether the a TextBlock&#8217;s text is being trimmed is not something that is available from the TextBlock&#8217;s API, there is no IsTrimmed property! A quick search of the Silverlight forums <a href="http://forums.silverlight.net/forums/p/200034/466651.aspx">drew a dead end</a>. I did find a <a href="http://tranxcoder.wordpress.com/2008/10/12/customizing-lookful-wpf-controls-take-2/">decent WPF solution</a>, however this uses various parts of the WPF API that are not present in Silverlight.</p>
<p>Eventually I found that there is a very simple solution &#8230; quoting from the MSDN page on <a href="http://msdn.microsoft.com/en-us/library/cc189010%28VS.95%29.aspx">Text and Fonts</a>:</p>
<blockquote><p>You can detect clipped text programmatically because ActualWidth for a TextBlock always reports the expanded size of the text, even if it does not fit in the layout container. If you know where to read the Width for the layout container that is doing the clipping, you can compare these two values.</p></blockquote>
<p>Therefore, if a TextBlock is trimming the text, the reported ActualWidth of the TextBlock will be the width that the TextBlock requires to render the text in its entirety, not the <em>actual</em> width of the rendered text!</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2011/01/TextTrimming.png" alt="" title="TextTrimming" width="568" height="257" class="aligncenter size-full wp-image-1076" /></p>
<p>In the example above, the Width of the TextBlock is set explicity, however it is more common that the width of TextBlock is determined by its parent container, a Grid for example.</p>
<p>To wrap this functionality up into something re-useable, I have created a AutoToolTip attached behaviour. The code for this is shown below:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> TextBlockUtils
<span style="color: #008000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Gets the value of the AutoTooltipProperty dependency property</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">bool</span> GetAutoTooltip<span style="color: #008000;">&#40;</span>DependencyObject obj<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">bool</span><span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>AutoTooltipProperty<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Sets the value of the AutoTooltipProperty dependency property</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> SetAutoTooltip<span style="color: #008000;">&#40;</span>DependencyObject obj, <span style="color: #6666cc; font-weight: bold;">bool</span> value<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    obj<span style="color: #008000;">.</span><span style="color: #0000FF;">SetValue</span><span style="color: #008000;">&#40;</span>AutoTooltipProperty, value<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Identified the attached AutoTooltip property. When true, this will set the</span>
  <span style="color: #008080; font-style: italic;">/// TextBlock TextTrimming property to WordEllipsis, and display a tooltip with</span>
  <span style="color: #008080; font-style: italic;">/// the full text whenever the text is trimmed.</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> DependencyProperty AutoTooltipProperty <span style="color: #008000;">=</span>  
           DependencyProperty<span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterAttached</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;AutoTooltip&quot;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">bool</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>TextBlockUtils<span style="color: #008000;">&#41;</span>,
            <span style="color: #008000;">new</span> PropertyMetadata<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">false</span>, OnAutoTooltipPropertyChanged<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnAutoTooltipPropertyChanged<span style="color: #008000;">&#40;</span>DependencyObject d,
                                     DependencyPropertyChangedEventArgs e<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    TextBlock textBlock <span style="color: #008000;">=</span> d <span style="color: #0600FF; font-weight: bold;">as</span> TextBlock<span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>textBlock <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
      <span style="color: #0600FF; font-weight: bold;">return</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>e<span style="color: #008000;">.</span><span style="color: #0000FF;">NewValue</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Equals</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      textBlock<span style="color: #008000;">.</span><span style="color: #0000FF;">TextTrimming</span> <span style="color: #008000;">=</span> TextTrimming<span style="color: #008000;">.</span><span style="color: #0000FF;">WordEllipsis</span><span style="color: #008000;">;</span>
      ComputeAutoTooltip<span style="color: #008000;">&#40;</span>textBlock<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      textBlock<span style="color: #008000;">.</span><span style="color: #0000FF;">SizeChanged</span> <span style="color: #008000;">+=</span> TextBlock_SizeChanged<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">else</span>
    <span style="color: #008000;">&#123;</span>
      textBlock<span style="color: #008000;">.</span><span style="color: #0000FF;">SizeChanged</span> <span style="color: #008000;">-=</span> TextBlock_SizeChanged<span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> TextBlock_SizeChanged<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, SizeChangedEventArgs e<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    TextBlock textBlock <span style="color: #008000;">=</span> sender <span style="color: #0600FF; font-weight: bold;">as</span> TextBlock<span style="color: #008000;">;</span>
    ComputeAutoTooltip<span style="color: #008000;">&#40;</span>textBlock<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Assigns the ToolTip for the given TextBlock based on whether the text is trimmed</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> ComputeAutoTooltip<span style="color: #008000;">&#40;</span>TextBlock textBlock<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    FrameworkElement parentElement <span style="color: #008000;">=</span> VisualTreeHelper<span style="color: #008000;">.</span><span style="color: #0000FF;">GetParent</span><span style="color: #008000;">&#40;</span>textBlock<span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>parentElement <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>textBlock<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualWidth</span> <span style="color: #008000;">&gt;</span> parentElement<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualWidth</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        ToolTipService<span style="color: #008000;">.</span><span style="color: #0000FF;">SetToolTip</span><span style="color: #008000;">&#40;</span>textBlock, textBlock<span style="color: #008000;">.</span><span style="color: #0000FF;">Text</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #008000;">&#125;</span>
      <span style="color: #0600FF; font-weight: bold;">else</span>
      <span style="color: #008000;">&#123;</span>
        ToolTipService<span style="color: #008000;">.</span><span style="color: #0000FF;">SetToolTip</span><span style="color: #008000;">&#40;</span>textBlock, <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Most of this is boiler-plate attached behaviour code. The most interesting method is <code>ComputeAutoTooltip</code> which determines whether a tooltip is required. This simply looks at the ActualWidth of the parent and compares it to the ActualWidth of the TextBlock.</p>
<p>To use this code, ensure that your TextBlock is placed within its own Grid, then set the attached property to true. You can see this in action below:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">util:GridUtils.ColumnDefinitions</span>=<span style="color: #ff0000;">&quot;2*,&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">util:GridUtils.RowDefinitions</span>=<span style="color: #ff0000;">&quot;,&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;sdk:GridSplitter</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">Grid.RowSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span></span>
<span style="color: #009900;">                    <span style="color: #000066;">ShowsPreview</span>=<span style="color: #ff0000;">&quot;True&quot;</span></span>
<span style="color: #009900;">                    <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;LightGray&quot;</span></span>
<span style="color: #009900;">                    <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;10&quot;</span></span>
<span style="color: #009900;">                    <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Right&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;0&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;0,0,10,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;The rain in Spain stays mainly in the plain&quot;</span>   </span>
<span style="color: #009900;">                <span style="color: #000066;">util:TextBlockUtils.AutoTooltip</span>=<span style="color: #ff0000;">&quot;True&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;In Hertford, Hereford, and Hampshire, hurricanes hardly ever happen&quot;</span></span>
<span style="color: #009900;">                <span style="color: #000066;">util:TextBlockUtils.AutoTooltip</span>=<span style="color: #ff0000;">&quot;True&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;0,0,10,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Peter Piper picked a peck of pickled peppers&quot;</span></span>
<span style="color: #009900;">                <span style="color: #000066;">util:TextBlockUtils.AutoTooltip</span>=<span style="color: #ff0000;">&quot;True&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;She sells sea-shells on the sea-shore&quot;</span></span>
<span style="color: #009900;">                <span style="color: #000066;">util:TextBlockUtils.AutoTooltip</span>=<span style="color: #ff0000;">&quot;True&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Note the use of the <a href="http://www.scottlogic.co.uk/blog/colin/2010/12/a-simplified-grid-markup-for-silverlight-and-wpf/">simplified grid syntax which I blogged about earlier</a>. You can see this code in action below. Move the grid splitter to see the tooltips automatically enabled when an ellipsis is displayed:</p>
<div style="text-align: center;"><object width="400" height="80" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2011/01/AutoTooltipTextBlock.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<p>You can download the full sourcecode here: <a href='http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2011/01/AutoTooltipTextBlock.zip'>AutoTooltipTextBlock.zip</a></p>
<p>Regards, Colin E.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/colin/2011/01/showing-tooltips-on-trimmed-textblock-silverlight/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>A Simplified Grid Markup for Silverlight and WPF</title>
		<link>http://www.scottlogic.co.uk/blog/colin/2010/12/a-simplified-grid-markup-for-silverlight-and-wpf/</link>
		<comments>http://www.scottlogic.co.uk/blog/colin/2010/12/a-simplified-grid-markup-for-silverlight-and-wpf/#comments</comments>
		<pubDate>Tue, 21 Dec 2010 12:58:47 +0000</pubDate>
		<dc:creator>Colin Eberhardt</dc:creator>
				<category><![CDATA[codeproject]]></category>
		<category><![CDATA[attached behaviour]]></category>
		<category><![CDATA[grid]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/colin/?p=1050</guid>
		<description><![CDATA[The WPF / Silverlight syntax is long and cumbersome. This blog post describe a simple attached property that allows you to specify row and column widths / heights as a simple comma separated list, e.g. RowDefinitions=&#8221;Auto,,3*,,,,2*&#8221; The Grid is probably one of the most useful and versatile layouts that Silverlight and WPF offers. However, if [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fcolin%252F2010%252F12%252Fa-simplified-grid-markup-for-silverlight-and-wpf%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22A%20Simplified%20Grid%20Markup%20for%20Silverlight%20and%20WPF%20%23%22%20%7D);"></div>
<p><em>The WPF / Silverlight syntax is long and cumbersome. This blog post describe a simple attached property that allows you to specify row and column widths / heights as a simple comma separated list, e.g. RowDefinitions=&#8221;Auto,,3*,,,,2*&#8221;</em></p>
<p>The Grid is probably one of the most useful and versatile layouts that Silverlight and WPF offers. However, if you hand craft your XAML, as I do, you will probably start to find the Grid markup for defining rows and columns to be verbose and cumbersome. If we look at the following example, which uses a mixture of Auto, Star and Pixel widths / heights:</p>
<p><img class="aligncenter size-full wp-image-1051" title="gridExample" src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/12/gridExample.png" alt="" width="290" height="241" /></p>
<p>Despite this being a simple example, the required row and column definitions are highly verbose:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;Auto&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;2*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;100&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;User Details&quot;</span> <span style="color: #000066;">FontSize</span>=<span style="color: #ff0000;">&quot;20&quot;</span></span>
<span style="color: #009900;">          <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span></span>
<span style="color: #009900;">          <span style="color: #000066;">Grid.ColumnSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Forename:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Jeremy&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Surname:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;James&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Age:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;3&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;24&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;3&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Phone:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;+44 191 555467&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Notes:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;5&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;A multi-line block of text ...&quot;</span> </span>
<span style="color: #009900;">            <span style="color: #000066;">TextWrapping</span>=<span style="color: #ff0000;">&quot;Wrap&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;6&quot;</span> <span style="color: #000066;">Grid.ColumnSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>To provide a simpler alternative, I have created attached properties, one for the column definitions, and the other for the rows. These attached properties allow you to specify the columns / rows as a comma separated list of heights and widths.</p>
<p>Using this technique, the above example becomes:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">local:GridUtils.ColumnDefinitions</span>=<span style="color: #ff0000;">&quot;100,&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">local:GridUtils.RowDefinitions</span>=<span style="color: #ff0000;">&quot;Auto,,,,,,2*&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;User Details&quot;</span> <span style="color: #000066;">FontSize</span>=<span style="color: #ff0000;">&quot;20&quot;</span></span>
<span style="color: #009900;">          <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span></span>
<span style="color: #009900;">          <span style="color: #000066;">Grid.ColumnSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Forename:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Jeremy&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Surname:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;James&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Age:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;3&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;24&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;3&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Phone:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;+44 191 555467&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Notes:&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;5&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;A multi-line block of text ...&quot;</span> </span>
<span style="color: #009900;">            <span style="color: #000066;">TextWrapping</span>=<span style="color: #ff0000;">&quot;Wrap&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;6&quot;</span> <span style="color: #000066;">Grid.ColumnSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The comma separated list defines the widths / heights of each column / row. The number of items in this list defined the number of rows / column that are generated. This notation supports pixel, star and auto widths / heights. Also, if you want a row or column with the default size, just leave the value blank, i.e. a row definition of “,,,” will create four rows of default height.</p>
<p>The code to achieve this is pretty simple, involving a couple of attached properties and string parsing in their changed event handlers. The complete code for the GridUtils class is given below, feel free to copy and paste it into your project:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Windows</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Windows.Controls</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">namespace</span> SimplifiedGrid
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> GridUtils
  <span style="color: #008000;">&#123;</span>
    <span style="color: #008080;">#region RowDefinitions attached property</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Identified the RowDefinitions attached property</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> DependencyProperty RowDefinitionsProperty <span style="color: #008000;">=</span>
        DependencyProperty<span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterAttached</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;RowDefinitions&quot;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>GridUtils<span style="color: #008000;">&#41;</span>,
            <span style="color: #008000;">new</span> PropertyMetadata<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;&quot;</span>, <span style="color: #008000;">new</span> PropertyChangedCallback<span style="color: #008000;">&#40;</span>OnRowDefinitionsPropertyChanged<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Gets the value of the RowDefinitions property</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">string</span> GetRowDefinitions<span style="color: #008000;">&#40;</span>DependencyObject d<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#41;</span>d<span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>RowDefinitionsProperty<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Sets the value of the RowDefinitions property</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> SetRowDefinitions<span style="color: #008000;">&#40;</span>DependencyObject d, <span style="color: #6666cc; font-weight: bold;">string</span> value<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      d<span style="color: #008000;">.</span><span style="color: #0000FF;">SetValue</span><span style="color: #008000;">&#40;</span>RowDefinitionsProperty, value<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Handles property changed event for the RowDefinitions property, constructing</span>
    <span style="color: #008080; font-style: italic;">/// the required RowDefinitions elements on the grid which this property is attached to.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnRowDefinitionsPropertyChanged<span style="color: #008000;">&#40;</span>DependencyObject d, DependencyPropertyChangedEventArgs e<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      Grid targetGrid <span style="color: #008000;">=</span> d <span style="color: #0600FF; font-weight: bold;">as</span> Grid<span style="color: #008000;">;</span>
&nbsp;
      <span style="color: #008080; font-style: italic;">// construct the required row definitions</span>
      targetGrid<span style="color: #008000;">.</span><span style="color: #0000FF;">RowDefinitions</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Clear</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #6666cc; font-weight: bold;">string</span> rowDefs <span style="color: #008000;">=</span> e<span style="color: #008000;">.</span><span style="color: #0000FF;">NewValue</span> <span style="color: #0600FF; font-weight: bold;">as</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">;</span>
      var rowDefArray <span style="color: #008000;">=</span> rowDefs<span style="color: #008000;">.</span><span style="color: #0000FF;">Split</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">','</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> rowDefinition <span style="color: #0600FF; font-weight: bold;">in</span> rowDefArray<span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>rowDefinition<span style="color: #008000;">.</span><span style="color: #0000FF;">Trim</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #666666;">&quot;&quot;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
          targetGrid<span style="color: #008000;">.</span><span style="color: #0000FF;">RowDefinitions</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> RowDefinition<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">else</span>
        <span style="color: #008000;">&#123;</span>
          targetGrid<span style="color: #008000;">.</span><span style="color: #0000FF;">RowDefinitions</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> RowDefinition<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
          <span style="color: #008000;">&#123;</span>
            Height <span style="color: #008000;">=</span> ParseLength<span style="color: #008000;">&#40;</span>rowDefinition<span style="color: #008000;">&#41;</span>
          <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
      <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080;">#endregion</span>
&nbsp;
&nbsp;
    <span style="color: #008080;">#region ColumnDefinitions attached property</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Identifies the ColumnDefinitions attached property</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> DependencyProperty ColumnDefinitionsProperty <span style="color: #008000;">=</span>
        DependencyProperty<span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterAttached</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ColumnDefinitions&quot;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>GridUtils<span style="color: #008000;">&#41;</span>,
            <span style="color: #008000;">new</span> PropertyMetadata<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;&quot;</span>, <span style="color: #008000;">new</span> PropertyChangedCallback<span style="color: #008000;">&#40;</span>OnColumnDefinitionsPropertyChanged<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Gets the value of the ColumnDefinitions property</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">string</span> GetColumnDefinitions<span style="color: #008000;">&#40;</span>DependencyObject d<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#41;</span>d<span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>ColumnDefinitionsProperty<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Sets the value of the ColumnDefinitions property</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> SetColumnDefinitions<span style="color: #008000;">&#40;</span>DependencyObject d, <span style="color: #6666cc; font-weight: bold;">string</span> value<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      d<span style="color: #008000;">.</span><span style="color: #0000FF;">SetValue</span><span style="color: #008000;">&#40;</span>ColumnDefinitionsProperty, value<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Handles property changed event for the ColumnDefinitions property, constructing</span>
    <span style="color: #008080; font-style: italic;">/// the required ColumnDefinitions elements on the grid which this property is attached to.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnColumnDefinitionsPropertyChanged<span style="color: #008000;">&#40;</span>DependencyObject d, DependencyPropertyChangedEventArgs e<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      Grid targetGrid <span style="color: #008000;">=</span> d <span style="color: #0600FF; font-weight: bold;">as</span> Grid<span style="color: #008000;">;</span>
&nbsp;
      <span style="color: #008080; font-style: italic;">// construct the required column definitions</span>
      targetGrid<span style="color: #008000;">.</span><span style="color: #0000FF;">ColumnDefinitions</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Clear</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #6666cc; font-weight: bold;">string</span> columnDefs <span style="color: #008000;">=</span> e<span style="color: #008000;">.</span><span style="color: #0000FF;">NewValue</span> <span style="color: #0600FF; font-weight: bold;">as</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">;</span>
      var columnDefArray <span style="color: #008000;">=</span> columnDefs<span style="color: #008000;">.</span><span style="color: #0000FF;">Split</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">','</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> columnDefinition <span style="color: #0600FF; font-weight: bold;">in</span> columnDefArray<span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>columnDefinition<span style="color: #008000;">.</span><span style="color: #0000FF;">Trim</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #666666;">&quot;&quot;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
          targetGrid<span style="color: #008000;">.</span><span style="color: #0000FF;">ColumnDefinitions</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> ColumnDefinition<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">else</span>
        <span style="color: #008000;">&#123;</span>
          targetGrid<span style="color: #008000;">.</span><span style="color: #0000FF;">ColumnDefinitions</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> ColumnDefinition<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
          <span style="color: #008000;">&#123;</span>
            Width <span style="color: #008000;">=</span> ParseLength<span style="color: #008000;">&#40;</span>columnDefinition<span style="color: #008000;">&#41;</span>
          <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
      <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080;">#endregion</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Parses a string to create a GridLength</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> GridLength ParseLength<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> length<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      length <span style="color: #008000;">=</span> length<span style="color: #008000;">.</span><span style="color: #0000FF;">Trim</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
      <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>length<span style="color: #008000;">.</span><span style="color: #0000FF;">ToLowerInvariant</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Equals</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;auto&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> GridLength<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0</span>, GridUnitType<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">Auto</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #008000;">&#125;</span>
      <span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>length<span style="color: #008000;">.</span><span style="color: #0000FF;">Contains</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;*&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        length <span style="color: #008000;">=</span> length<span style="color: #008000;">.</span><span style="color: #0000FF;">Replace</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;*&quot;</span>,<span style="color: #666666;">&quot;&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsNullOrEmpty</span><span style="color: #008000;">&#40;</span>length<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> length <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;1&quot;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> GridLength<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Parse</span><span style="color: #008000;">&#40;</span>length<span style="color: #008000;">&#41;</span>, GridUnitType<span style="color: #008000;">.</span><span style="color: #0000FF;">Star</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #008000;">&#125;</span>
&nbsp;
      <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> GridLength<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Parse</span><span style="color: #008000;">&#40;</span>length<span style="color: #008000;">&#41;</span>, GridUnitType<span style="color: #008000;">.</span><span style="color: #0000FF;">Pixel</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The code which parses the row and column strings is also executed by the Visual Studio designer, so you can see your new rows / columns immediately. It also works just fine in WPF and Silverlight.</p>
<p>You can download example projects in both technologies: <a href='http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/12/SimplifiedGrid.zip'>SimplfiedGrid.zip</a></p>
<p>readers might also be interested in <a href="http://whydoidoit.com/2010/10/06/automatic-grid-layout-for-silverlight/">Mike Talbot&#8217;s AutoGrid</a> which dynamically adds rows / columns based as children are added to the grid. A very neat idea!</p>
<p>(Thanks to Rob Newsome for coming up with this idea in the first place!)</p>
<p>Regards, Colin E.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/colin/2010/12/a-simplified-grid-markup-for-silverlight-and-wpf/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Developing a Lookless Silverlight Gauge Control (part 2)</title>
		<link>http://www.scottlogic.co.uk/blog/colin/2010/10/developing-a-lookless-silverlight-gauge-control-part-2/</link>
		<comments>http://www.scottlogic.co.uk/blog/colin/2010/10/developing-a-lookless-silverlight-gauge-control-part-2/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 20:38:29 +0000</pubDate>
		<dc:creator>Colin Eberhardt</dc:creator>
				<category><![CDATA[codeproject]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[attached behaviour]]></category>
		<category><![CDATA[attached view model]]></category>
		<category><![CDATA[bullet graph]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/colin/?p=867</guid>
		<description><![CDATA[In a previous blog post I described the process of creating a lookless gauge control. I introduced the concept of an attached view model which separates view specific concepts from the control. In this post I demonstrate how this allows for great flexibility when re-templating the control. In my previous post I described the development [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fcolin%252F2010%252F10%252Fdeveloping-a-lookless-silverlight-gauge-control-part-2%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Developing%20a%20Lookless%20Silverlight%20Gauge%20Control%20%28part%202%29%20%23%22%20%7D);"></div>
<p><em>In a previous blog post I described the process of creating a lookless gauge control. I introduced the concept of an attached view model which separates view specific concepts from the control. In this post I demonstrate how this allows for great flexibility when re-templating the control.</em></p>
<p>In <a href="http://www.scottlogic.co.uk/blog/colin/2010/08/developing-a-very-lookless-silverlight-radial-gauge-control/">my previous post</a> I described the development of a radial gauge control where I removed any view-specific logic and properties from the control by introducing an attached view model into the control’s template. My reasons for doing this were to create a completely lookless control in the order that this would permit greater flexibility when re-templating or themeing. The control I created was a gauge control, which in my previous blog post I rendered as a radial gauge. The ‘radial concepts’ of angle, and other derived properties are contained within the attached view model, with the Gauge control itself only containing concepts that are common across all gauges (radial or otherwise). The control is shown below:</p>
<div style="text-align: center; "><object width="300" height="240" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/GaugeControlTwo.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<p>In this post I will create two different templates for this control. The first is a small variation on the radial gauge which is rendered as a semi-circle. The second is very different, a bullet graph, where the gauge is rendered as a linear indicator. With each, an attached view model is introduced into the controls template in order to compute properties that aid in the rendering of the control.</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/BulletAndSemiGauge.jpg" alt="" title="BulletAndSemiGauge" width="400" height="126" class="aligncenter size-full wp-image-869" /></p>
<h2>A Semi-circular Gauge</h2>
<p>The original attached view model I created was hard-coded to create a radial control where the needle has a sweep angle of 300 degrees. To support a semi-circular gauge we need to be able to configure this parameter. I achieved this by simply making SweepAngle a public property of the attached view model. This property is used wherever the view model needs to convert a gauge value to a radial location (i.e. when computing the tick mark rotation angles):</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> RadialGaugeControlViewModel <span style="color: #008000;">:</span> AttachedViewModelBase
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> RadialGaugeControlViewModel<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    SweepAngle <span style="color: #008000;">=</span> <span style="color: #FF0000;">300</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Gets / sets the sweep angle of the radial gauge</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">double</span> SweepAngle
  <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">double</span> ValueToAngle<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span> value<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #6666cc; font-weight: bold;">double</span> minAngle <span style="color: #008000;">=</span> <span style="color: #008000;">-</span>SweepAngle <span style="color: #008000;">/</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span>
    <span style="color: #6666cc; font-weight: bold;">double</span> maxAngle <span style="color: #008000;">=</span> SweepAngle <span style="color: #008000;">/</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span>
    <span style="color: #6666cc; font-weight: bold;">double</span> angularRange <span style="color: #008000;">=</span> maxAngle <span style="color: #008000;">-</span> minAngle<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span>value <span style="color: #008000;">-</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">/</span> <span style="color: #008000;">&#40;</span>Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Maximum</span> <span style="color: #008000;">-</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">*</span>
        angularRange <span style="color: #008000;">+</span> minAngle<span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008000;">...</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>This allows it to be set in the control template of our re-templated gauge control where the view model is instantiated and attached:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Style</span> <span style="color: #000066;">TargetType</span>=<span style="color: #ff0000;">&quot;local:GaugeControl&quot;</span> <span style="color: #000066;">x:Key</span>=<span style="color: #ff0000;">&quot;themedGauge&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;FontSize&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;8&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Template&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter.Value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ControlTemplate</span> <span style="color: #000066;">TargetType</span>=<span style="color: #ff0000;">&quot;local:GaugeControl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;LayoutRoot&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- attach the view model --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:RadialGaugeControlViewModel.Attach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:RadialGaugeControlViewModel</span></span>
<span style="color: #009900;">                     <span style="color: #000066;">SweepAngle</span>=<span style="color: #ff0000;">&quot;180&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:RadialGaugeControlViewModel.Attach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- gauge template goes here! --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ControlTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Setter.Value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Setter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>This means that the various properties of the attached view model that the view binds to in order to render the various control parts, such as the needle, are now computed with a 180 degree sweep.</p>
<p>For the semi-circular gauge, I used a similar technique to the original radial gauge for creating the required layout, where a grid with various rows / columns with star widths / heights create a proportional layout within which elements such as the needle are placed:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #808080; font-style: italic;">&lt;!-- attach the view model --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:RadialGaugeControlViewModel.Attach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:RadialGaugeControlViewModel</span> <span style="color: #000066;">SweepAngle</span>=<span style="color: #ff0000;">&quot;180&quot;</span> <span style="color: #000066;">Clip</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:RadialGaugeControlViewModel.Attach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #808080; font-style: italic;">&lt;!-- the gauge outline --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path</span> <span style="color: #000066;">Stroke</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">StrokeThickness</span>=<span style="color: #ff0000;">&quot;3&quot;</span> <span style="color: #000066;">StrokeLineJoin</span>=<span style="color: #ff0000;">&quot;Round&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">Stretch</span>=<span style="color: #ff0000;">&quot;Uniform&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path.Data<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;PathGeometry<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;PathGeometry.Figures<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;PathFigure</span> <span style="color: #000066;">IsClosed</span>=<span style="color: #ff0000;">&quot;True&quot;</span> </span>
<span style="color: #009900;">                    <span style="color: #000066;">StartPoint</span>=<span style="color: #ff0000;">&quot;0.5,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;PathFigure.Segments<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ArcSegment</span> <span style="color: #000066;">Size</span>=<span style="color: #ff0000;">&quot;0.5,0.5&quot;</span> <span style="color: #000066;">RotationAngle</span>=<span style="color: #ff0000;">&quot;45&quot;</span> <span style="color: #000066;">IsLargeArc</span>=<span style="color: #ff0000;">&quot;False&quot;</span></span>
<span style="color: #009900;">                      <span style="color: #000066;">SweepDirection</span>=<span style="color: #ff0000;">&quot;Clockwise&quot;</span></span>
<span style="color: #009900;">                      <span style="color: #000066;">Point</span>=<span style="color: #ff0000;">&quot;1,0.5&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;LineSegment</span> <span style="color: #000066;">Point</span>=<span style="color: #ff0000;">&quot;1,0.55&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;LineSegment</span> <span style="color: #000066;">Point</span>=<span style="color: #ff0000;">&quot;0,0.55&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;LineSegment</span> <span style="color: #000066;">Point</span>=<span style="color: #ff0000;">&quot;0,0.5&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ArcSegment</span> <span style="color: #000066;">Size</span>=<span style="color: #ff0000;">&quot;0.5,0.5&quot;</span> <span style="color: #000066;">RotationAngle</span>=<span style="color: #ff0000;">&quot;45&quot;</span> <span style="color: #000066;">IsLargeArc</span>=<span style="color: #ff0000;">&quot;False&quot;</span></span>
<span style="color: #009900;">                            <span style="color: #000066;">SweepDirection</span>=<span style="color: #ff0000;">&quot;Clockwise&quot;</span></span>
<span style="color: #009900;">                            <span style="color: #000066;">Point</span>=<span style="color: #ff0000;">&quot;0.5,0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/PathFigure.Segments<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/PathFigure</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/PathGeometry.Figures<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/PathGeometry<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path.Data<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">ShowGridLines</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;3.5*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;4*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;.6*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;.6*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;8.0*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;.7*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;.7*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;8.0*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #808080; font-style: italic;">&lt;!-- needle --&gt;</span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path</span> <span style="color: #000066;">Stretch</span>=<span style="color: #ff0000;">&quot;Uniform&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">Grid.ColumnSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000066;">Grid.RowSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;Black&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">Stroke</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">StrokeThickness</span>=<span style="color: #ff0000;">&quot;0.5&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">Data</span>=<span style="color: #ff0000;">&quot;M 0,0 l 5,60 l -10, 0&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">RenderTransformOrigin</span>=<span style="color: #ff0000;">&quot;0.5,1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RotateTransform</span> <span style="color: #000066;">Angle</span>=<span style="color: #ff0000;">&quot;{Binding Path=ValueAngle}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #808080; font-style: italic;">&lt;!-- needle cover --&gt;</span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;White&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Stroke</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">StrokeThickness</span>=<span style="color: #ff0000;">&quot;2&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;13&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;13&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span> <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Bottom&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Grid.RowSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000066;">Grid.ColumnSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>You can see the various gridlines below:</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/semicircle.jpg" alt="" title="semicircle" width="251" height="123" class="aligncenter size-full wp-image-870" /></p>
<p>The code for creating the major / minor ticks and qualitative ranges are much the same as before. However, for a bit of variation I did not want the labels on this gauge to be rotated. In order to achieve this I used the same technique as before where each label is initially constructed at the same location, then a translate / rotate transform is used to move it to the correct location on the dial. In this control, the text label is rotated a second time in the opposite direction in order to bring it back to its original orientation:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;50&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;20&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TranslateTransform</span> <span style="color: #000066;">X</span>=<span style="color: #ff0000;">&quot;-25&quot;</span> <span style="color: #000066;">Y</span>=<span style="color: #ff0000;">&quot;-10&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TranslateTransform</span> <span style="color: #000066;">Y</span>=<span style="color: #ff0000;">&quot;{Binding Path=Parent.GridHeight,</span>
<span style="color: #009900;">              Converter={StaticResource ScaleFactorConverter}, ConverterParameter=-0.69}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RotateTransform</span> <span style="color: #000066;">Angle</span>=<span style="color: #ff0000;">&quot;{Binding Path=Angle}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;{Binding Path=Value}&quot;</span> </span>
<span style="color: #009900;">            <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">RenderTransformOrigin</span>=<span style="color: #ff0000;">&quot;0.5, 0.5&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- rotate the labels by '-Angle' to return to their original orientation --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RotateTransform</span> <span style="color: #000066;">Angle</span>=<span style="color: #ff0000;">&quot;{Binding Path=Angle,</span>
<span style="color: #009900;">                Converter={StaticResource ScaleFactorConverter}, ConverterParameter=-1}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TextBlock.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TextBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The finished semi-circular gauge can be seen here next to my original radial gauge control:</p>
<div style="text-align: center; "><object width="400" height="240" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/GaugeAndSemiGauge.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<p>So, the original control has proven to be pretty versatile in that it can be re-templated to look quite different. To allow this, the attached view model was modified to expose a few view-centric properties that could be set when it is created and attached within the template.</p>
<p>However, the example above is still a radial gauge. A much bigger challenge would be to re-template the control to look completely different. That was my next challenge!</p>
<h2>A Bullet Graph Template</h2>
<p>Radial gauge controls look very pretty; however they eat up a lot of screen real-estate, and are not the best way of visualising a one-dimensional metric. A much clearer visualisation can be achieved by using a linear gauge, a <a href="http://en.wikipedia.org/wiki/Bullet_graph">bullet-graph</a> for example. This section describes how a new attached view model can be applied to the gauge control, to support a template which produces a bullet graph.</p>
<p>Using the same process as in the above example, the basic structure of the control is defined using a Grid:</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/bulletLayout.png" alt="" title="bulletLayout" width="235" height="99" class="aligncenter size-full wp-image-872" /></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Style</span> <span style="color: #000066;">TargetType</span>=<span style="color: #ff0000;">&quot;local:GaugeControl&quot;</span> <span style="color: #000066;">x:Key</span>=<span style="color: #ff0000;">&quot;bulletGraphGauge&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;FontSize&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;8&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Template&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter.Value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ControlTemplate</span> <span style="color: #000066;">TargetType</span>=<span style="color: #ff0000;">&quot;local:GaugeControl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;LayoutRoot&quot;</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;LightBlue&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">ShowGridLines</span>=<span style="color: #ff0000;">&quot;True&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- attach the view model --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:RadialGaugeControlViewModel.Attach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BulletGraphGaugeViewModel</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:RadialGaugeControlViewModel.Attach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!--the grid layout --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;3*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;2*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;3*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>                
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- featured measure indicator --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Rectangle</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;Black&quot;</span></span>
<span style="color: #009900;">                        <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span></span>
<span style="color: #009900;">                        <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Left&quot;</span></span>
<span style="color: #009900;">                        <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;{Binding Path=FeaturedMeasureLength}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ControlTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Setter.Value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Setter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The ‘featured measure’, which is a thermometer-like bar which indicates the current value of the gauge has its Width property bound to the view model which is attached at the top of the template. To simplify the code, I refactored the attached view model concept to extract a base class which is shared by both the radial and bullet-graph subclasses. This base class takes care of attaching to its parents DataContext, adapting the control’s properties, exposing the actual width / height of the control and the other bits and pieces I described in my previous blog post. The bullet graph view model is then much simpler as a result. In the code below you can see how the FeaturedMeasureLength is computed in the view model:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> BulletGraphGaugeViewModel <span style="color: #008000;">:</span> AttachedViewModelBase
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> BulletGraphGaugeViewModel<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">private</span> GaugeControl Gauge
  <span style="color: #008000;">&#123;</span>
    <span style="color: #008080; font-style: italic;">// the view model’s DataContext is bound to the Gauge</span>
    get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> DataContext <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span> <span style="color: #008000;">?</span> <span style="color: #008000;">&#40;</span>GaugeControl<span style="color: #008000;">&#41;</span>DataContext <span style="color: #008000;">:</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">double</span> FeaturedMeasureLength
  <span style="color: #008000;">&#123;</span>
    get
    <span style="color: #008000;">&#123;</span>
      <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>Gauge <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
&nbsp;
      <span style="color: #0600FF; font-weight: bold;">return</span> ValueToWidth<span style="color: #008000;">&#40;</span>Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Value</span> <span style="color: #008000;">-</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Converts the given value (which should be between Gauge.Maximum / Gauge.Minimum)</span>
  <span style="color: #008080; font-style: italic;">/// into suitable width for rendering within the view.</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">double</span> ValueToWidth<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span> value<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #6666cc; font-weight: bold;">double</span> range <span style="color: #008000;">=</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Maximum</span> <span style="color: #008000;">-</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span>value<span style="color: #008000;">&#41;</span> <span style="color: #008000;">/</span> range <span style="color: #008000;">*</span> ElementWidth<span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Next we’ll add the ‘qualitative range’ scale:</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/bulletRanges.png" alt="" title="bulletRanges" width="229" height="98" class="aligncenter size-full wp-image-874" /></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- Qualitative ranges --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl</span> <span style="color: #000066;">ItemsSource</span>=<span style="color: #ff0000;">&quot;{Binding Path=Ranges}&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.RowSpan</span>=<span style="color: #ff0000;">&quot;3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl.ItemsPanel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsPanelTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;StackPanel</span> <span style="color: #000066;">Orientation</span>=<span style="color: #ff0000;">&quot;Horizontal&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsPanelTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl.ItemsPanel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Rectangle</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;{Binding Path=Width}&quot;</span></span>
<span style="color: #009900;">                  <span style="color: #000066;">Stroke</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">StrokeThickness</span>=<span style="color: #ff0000;">&quot;0.2&quot;</span></span>
<span style="color: #009900;">                  <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;{Binding Path=Color, Converter={StaticResource ColorToBrushConverter}}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Border</span> <span style="color: #000066;">BorderBrush</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">BorderThickness</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.RowSpan</span>=<span style="color: #ff0000;">&quot;3&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;-1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>Once again, the attached view model is used to adapt the properties exposed by the control in order to provide properties which are easier to bind to in order to create the required UI. Here the Gauge controls QualitativeRange is adapted to expose a Range property, which the ItemsControl in the XAML above binds to, this property is an enumeration of RangeItems which each have the correct width and colour for our UI:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> IEnumerable<span style="color: #008000;">&lt;</span>RangeItem<span style="color: #008000;">&gt;</span> Ranges
<span style="color: #008000;">&#123;</span>
  get
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>Gauge <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
      <span style="color: #0600FF; font-weight: bold;">yield</span> <span style="color: #0600FF; font-weight: bold;">break</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">QualitativeRange</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      var range <span style="color: #008000;">=</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">QualitativeRange</span><span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
      <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>i <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">// first RangeItem, width is determined from the first range value</span>
        <span style="color: #0600FF; font-weight: bold;">yield</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> RangeItem<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
          Color <span style="color: #008000;">=</span> range<span style="color: #008000;">.</span><span style="color: #0000FF;">Color</span>,
          Width <span style="color: #008000;">=</span> ValueToWidth<span style="color: #008000;">&#40;</span>range<span style="color: #008000;">.</span><span style="color: #0000FF;">Maximum</span> <span style="color: #008000;">-</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
      <span style="color: #008000;">&#125;</span>
      <span style="color: #0600FF; font-weight: bold;">else</span>
      <span style="color: #008000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">// subsequent items, width computed as the difference between the</span>
        <span style="color: #008080; font-style: italic;">// current value and its predecessor</span>
        var previousRange <span style="color: #008000;">=</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">QualitativeRange</span><span style="color: #008000;">&#91;</span>i <span style="color: #008000;">-</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">yield</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> RangeItem<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
          Color <span style="color: #008000;">=</span> range<span style="color: #008000;">.</span><span style="color: #0000FF;">Color</span>,
          Width <span style="color: #008000;">=</span> ValueToWidth<span style="color: #008000;">&#40;</span>range<span style="color: #008000;">.</span><span style="color: #0000FF;">Maximum</span> <span style="color: #008000;">-</span> previousRange<span style="color: #008000;">.</span><span style="color: #0000FF;">Maximum</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
      <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #008000;">...</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> RangeItem
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">double</span> Width <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> Color Color <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Finally, the scales are added:</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/bulletscale.png" alt="" title="bulletscale" width="237" height="99" class="aligncenter size-full wp-image-875" /></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- upper scale --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl</span> <span style="color: #000066;">ItemsSource</span>=<span style="color: #ff0000;">&quot;{Binding Path=MajorTicks}&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;0&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">ItemsPanel</span>=<span style="color: #ff0000;">&quot;{StaticResource CanvasTemplate}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;50&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;20&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- centre the labels --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TranslateTransform</span> <span style="color: #000066;">X</span>=<span style="color: #ff0000;">&quot;-25&quot;</span> <span style="color: #000066;">Y</span>=<span style="color: #ff0000;">&quot;-10&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TranslateTransform</span> <span style="color: #000066;">X</span>=<span style="color: #ff0000;">&quot;{Binding Path=Position}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;{Binding Path=Label}&quot;</span></span>
<span style="color: #009900;">                    <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span></span>
<span style="color: #009900;">                    <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #808080; font-style: italic;">&lt;!-- major ticks --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl</span> <span style="color: #000066;">ItemsSource</span>=<span style="color: #ff0000;">&quot;{Binding Path=MajorTicks}&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Bottom&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;0&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">ItemsPanel</span>=<span style="color: #ff0000;">&quot;{StaticResource CanvasTemplate}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Line</span> <span style="color: #000066;">X1</span>=<span style="color: #ff0000;">&quot;{Binding Path=Position}&quot;</span> <span style="color: #000066;">Y1</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">X2</span>=<span style="color: #ff0000;">&quot;{Binding Path=Position}&quot;</span> <span style="color: #000066;">Y2</span>=<span style="color: #ff0000;">&quot;-5&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Stroke</span>=<span style="color: #ff0000;">&quot;Black&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #808080; font-style: italic;">&lt;!-- minor ticks --&gt;</span>          
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl</span> <span style="color: #000066;">ItemsSource</span>=<span style="color: #ff0000;">&quot;{Binding Path=MinorTicks}&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Bottom&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;0&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">ItemsPanel</span>=<span style="color: #ff0000;">&quot;{StaticResource CanvasTemplate}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Line</span> <span style="color: #000066;">X1</span>=<span style="color: #ff0000;">&quot;{Binding}&quot;</span> <span style="color: #000066;">Y1</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">X2</span>=<span style="color: #ff0000;">&quot;{Binding}&quot;</span> <span style="color: #000066;">Y2</span>=<span style="color: #ff0000;">&quot;-3&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">Stroke</span>=<span style="color: #ff0000;">&quot;Black&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Again, exactly the same pattern is employed, with the MajorTicks and MinorTicks properties exposed by the attached view model, each providing an enumeration of simple value objects with a Position and Label properties, which are bound to the three ItemsControls above to create the required UI.</p>
<p>The complete bullet graph template is shown below next to the original radial gauge:</p>
<div style="text-align: center; "><object width="400" height="240" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/GaugeAndBullet.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<p>In conclusion, the use of an attached view model provides a mechanism for exposing view-specific properties to the view logic within the XAML template. This enables the construction of a control which really is entirely lookless.</p>
<p>You can download the sourcecode for this project:  <a href='http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/10/GaugeControl.zip'>GaugeControl.zip</a></p>
<p>Regards, Colin E.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/colin/2010/10/developing-a-lookless-silverlight-gauge-control-part-2/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Developing a (very) Lookless Silverlight Radial Gauge Control</title>
		<link>http://www.scottlogic.co.uk/blog/colin/2010/08/developing-a-very-lookless-silverlight-radial-gauge-control/</link>
		<comments>http://www.scottlogic.co.uk/blog/colin/2010/08/developing-a-very-lookless-silverlight-radial-gauge-control/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 11:13:20 +0000</pubDate>
		<dc:creator>Colin Eberhardt</dc:creator>
				<category><![CDATA[codeproject]]></category>
		<category><![CDATA[attached behaviour]]></category>
		<category><![CDATA[attached view model]]></category>
		<category><![CDATA[multibinding]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/colin/?p=764</guid>
		<description><![CDATA[This blog post describes the development of a lookless radial gauge control. In this post I will explore the use of an attached view model in order to move view specific properties and logic out of the control code in order to give a truly lookless control. Today I had to get up far too [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fcolin%252F2010%252F08%252Fdeveloping-a-very-lookless-silverlight-radial-gauge-control%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Developing%20a%20%28very%29%20Lookless%20Silverlight%20Radial%20Gauge%20Control%20%23%22%20%7D);"></div>
<p><em>This blog post describes the development of a lookless radial gauge control. In this post I will explore the use of an attached view model in order to move view specific properties and logic out of the control code in order to give a truly lookless control.</em></p>
<p>Today I had to get up far too early in order to catch an early morning flight to Copenhagen with a connection in Amsterdam. What to do for the six hours I would be travelling? Armed with a netbook and Visual Studio 2010 Express I thought it would be fun to have a go at developing a Silverlight gauge control. I know that there are already one or two free ones out there, with <a href="http://www.codeproject.com/KB/silverlight/circulargaugecontrol.aspx">a decent looking one available on codeproject</a>, however, it still felt like a good way to pass the time!</p>
<p>In order to make things a little more challenging I wanted to create a control that was truly lookless. So, what do I mean by this? Firstly a gauge control in its simplest sense displays the location of some indicator between a maximum and minimum value. There is nothing inherently circular about a gauge, thermometers are a good example of a linear gauge. So, I don’t want any ‘circular’ logic in the control itself. Secondly, custom controls often have certain expectations about the presence of named elements within their template. By this I mean that the template must contain, for example, a Path element called ‘needle’ which the control code will manipulate (The gauge published in the codeproject article above requires the presence of four named elements in the template). This forces certain constraints regarding how the control can be templated, this isn&#8217;t really lookless is it?</p>
<p>The following example shows the gauge control which I created, and the rest of this post describes the implementation:</p>
<div><object width="300" height="300" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/08/GaugeControlOne.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:GaugeControl</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;65&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;200&quot;</span>  </span>
<span style="color: #009900;">                    <span style="color: #000066;">Maximum</span>=<span style="color: #ff0000;">&quot;100&quot;</span> <span style="color: #000066;">Minimum</span>=<span style="color: #ff0000;">&quot;50&quot;</span></span>
<span style="color: #009900;">                    <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;gauge&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:GaugeControl.QualitativeRange<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:QualitativeRanges<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:QualitativeRange</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;Yellow&quot;</span> <span style="color: #000066;">Maximum</span>=<span style="color: #ff0000;">&quot;75&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:QualitativeRange</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;Orange&quot;</span> <span style="color: #000066;">Maximum</span>=<span style="color: #ff0000;">&quot;90&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:QualitativeRange</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;Red&quot;</span> <span style="color: #000066;">Maximum</span>=<span style="color: #ff0000;">&quot;100&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:QualitativeRanges<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:GaugeControl.QualitativeRange<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:GaugeControl<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<h2>The Starting Point</h2>
<p>The first step was to create a Gauge custom control with Value, Maximum and Minimum dependency properties. The only logic defined within the control itself is to set the DataContext of the root visual element to the control instance itself. This is quite a common approach to control design, allowing elements within the template to bind to the control properties:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnApplyTemplate<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">.</span><span style="color: #0000FF;">OnApplyTemplate</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  Grid root <span style="color: #008000;">=</span> GetTemplateChild<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;LayoutRoot&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">as</span> Grid<span style="color: #008000;">;</span>
  root<span style="color: #008000;">.</span><span style="color: #0000FF;">DataContext</span> <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The first thing I added to the control template was the ‘face’ of the radial gauge. This is simply an Ellipse with a pretty gradient fill and stroke:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- dial background and outer border --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse</span> <span style="color: #000066;">Stretch</span>=<span style="color: #ff0000;">&quot;Fill&quot;</span> <span style="color: #000066;">StrokeThickness</span>=<span style="color: #ff0000;">&quot;8&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse.Fill<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RadialGradientBrush</span> <span style="color: #000066;">Center</span>=<span style="color: #ff0000;">&quot;0.5,0.5&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;#EEF&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;#99B&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;0.9&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;#335&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/RadialGradientBrush<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Ellipse.Fill<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse.Stroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;LinearGradientBrush</span> <span style="color: #000066;">StartPoint</span>=<span style="color: #ff0000;">&quot;0,0&quot;</span> <span style="color: #000066;">EndPoint</span>=<span style="color: #ff0000;">&quot;0,1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;#BBD&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;#003&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/LinearGradientBrush<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Ellipse.Stroke<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Ellipse<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/08/face.jpg" alt="" title="face" width="222" height="207" class="aligncenter size-full wp-image-765" /></p>
<h2>Adding the Needle</h2>
<p>The next thing I added to the control was a needle. This is rendered using a simple Path with a LinearGradient in order to give it some sense of depth. I want the needle to have a length of approximately 70% of the gauge’s radius, a simple way to achieve this is to construct it within a Grid that uses ‘star’ widths / heights to provide a proportional layout and configure the Path to stretch to fill the cell it occupies:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- the needle path --&gt;</span>              
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;3*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;7*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;10*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path</span> <span style="color: #000066;">Stretch</span>=<span style="color: #ff0000;">&quot;Uniform&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.ColumnSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">Stroke</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">StrokeThickness</span>=<span style="color: #ff0000;">&quot;0.5&quot;</span></span>
<span style="color: #009900;">      <span style="color: #000066;">Data</span>=<span style="color: #ff0000;">&quot;M 0,0 l 10,60 l -10, 40 l -10 -40&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path.Fill<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;LinearGradientBrush</span> <span style="color: #000066;">StartPoint</span>=<span style="color: #ff0000;">&quot;0,0&quot;</span> <span style="color: #000066;">EndPoint</span>=<span style="color: #ff0000;">&quot;1,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;DarkRed&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;DarkRed&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;0.45&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;Red&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;0.55&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;Red&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/LinearGradientBrush<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path.Fill<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Here you can see how the needle is scaled by its parent Grid:</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/08/needle.jpg" alt="" title="needle" width="237" height="232" class="aligncenter size-full wp-image-768" /></p>
<p>Rotating the needle to reflect the current Gauge Value is achieved quite simply via RotateTransform. However, this needs to be converted into a rotation angle which depends on the Gauge Maximum /Minimum values together with the overall angle of sweep on the gauge. I initially approach this problem by applying bindings via value converters and <a href="http://www.scottlogic.co.uk/blog/colin/2010/08/silverlight-multibinding-updated-adding-support-for-elementname-and-twoway-binding/">multibindings</a>, however I found myself repeating the same conversion logic in numerous places within the template in order to render the ticks etc&#8230; Ideally the angle of rotation would be something that the template could bind to. The template DataContext is bound to the Gauge control itself, however as stated earlier I do not want ‘circular’ concepts to leak into the control.</p>
<h2>An attached View Model</h2>
<p>The solution I came up with for this problem was to create a view model that lives entirely within the control template that acts as an adapter for the Gauge, supplementing its properties with the needed ‘circular’ concepts. In keeping with my aims I could not instantiate this view model within the Gauge control itself, so instead it is created via an attached behaviour within the control template:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Style</span> <span style="color: #000066;">TargetType</span>=<span style="color: #ff0000;">&quot;local:GaugeControl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;FontSize&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;10&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Template&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter.Value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ControlTemplate</span> <span style="color: #000066;">TargetType</span>=<span style="color: #ff0000;">&quot;local:GaugeControl&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;LayoutRoot&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- attached the view model --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:RadialGaugeControlViewModel.Attach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
              <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:RadialGaugeControlViewModel</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:RadialGaugeControlViewModel.Attach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- ... control template goes here ...  --&gt;</span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ControlTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Setter.Value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Setter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The view model defines the Attach property and in its change handler performs the logic required to bind to the DatatContext of the parent (which is the Gauge control itself), and set itself as the DataContext of the Grid to which it is being attached. This allows the rest of the template to bind to properties of the RadialGaugeControlViewModel.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> RadialGaugeControlViewModel <span style="color: #008000;">:</span> FrameworkElement, INotifyPropertyChanged
<span style="color: #008000;">&#123;</span>
  <span style="color: #008080;">#region Attach attached property</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> DependencyProperty AttachProperty <span style="color: #008000;">=</span>
      DependencyProperty<span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterAttached</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Attach&quot;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>RadialGaugeControlViewModel<span style="color: #008000;">&#41;</span>,
          <span style="color: #008000;">new</span> PropertyMetadata<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">null</span>, <span style="color: #008000;">new</span> PropertyChangedCallback<span style="color: #008000;">&#40;</span>OnAttachChanged<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> RadialGaugeControlViewModel GetAttach<span style="color: #008000;">&#40;</span>DependencyObject d<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span>RadialGaugeControlViewModel<span style="color: #008000;">&#41;</span>d<span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>AttachProperty<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> SetAttach<span style="color: #008000;">&#40;</span>DependencyObject d, RadialGaugeControlViewModel value<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    d<span style="color: #008000;">.</span><span style="color: #0000FF;">SetValue</span><span style="color: #008000;">&#40;</span>AttachProperty, value<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Change handler for the Attach property</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnAttachChanged<span style="color: #008000;">&#40;</span>DependencyObject d, DependencyPropertyChangedEventArgs e<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    Grid targetElement <span style="color: #008000;">=</span> d <span style="color: #0600FF; font-weight: bold;">as</span> Grid<span style="color: #008000;">;</span>
    RadialGaugeControlViewModel viewModel <span style="color: #008000;">=</span> e<span style="color: #008000;">.</span><span style="color: #0000FF;">NewValue</span> <span style="color: #0600FF; font-weight: bold;">as</span> RadialGaugeControlViewModel<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// handle the loaded event</span>
    targetElement<span style="color: #008000;">.</span><span style="color: #0000FF;">Loaded</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">new</span> RoutedEventHandler<span style="color: #008000;">&#40;</span>Grid_Loaded<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Handle the Loaded event of the Grid to enable the attached</span>
  <span style="color: #008080; font-style: italic;">/// view model to bind to properties of the Grid Parent element</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> Grid_Loaded<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, RoutedEventArgs e<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    FrameworkElement targetElement <span style="color: #008000;">=</span> sender <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">;</span>
    FrameworkElement parent <span style="color: #008000;">=</span> targetElement<span style="color: #008000;">.</span><span style="color: #0000FF;">Parent</span> <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// use the attached view model as the DataContext of the element it is attached to</span>
    RadialGaugeControlViewModel attachedModel <span style="color: #008000;">=</span> GetAttach<span style="color: #008000;">&#40;</span>targetElement<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    targetElement<span style="color: #008000;">.</span><span style="color: #0000FF;">DataContext</span> <span style="color: #008000;">=</span> attachedModel<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// bind the DataContext of the view model to the DataContext of the parent.</span>
    attachedModel<span style="color: #008000;">.</span><span style="color: #0000FF;">SetBinding</span><span style="color: #008000;">&#40;</span>RadialGaugeControlViewModel<span style="color: #008000;">.</span><span style="color: #0000FF;">DataContextProperty</span>,
      <span style="color: #008000;">new</span> Binding<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;DataContext&quot;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        Source <span style="color: #008000;">=</span> parent
      <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>It is now possible to expose a property on the view model which provides the Gauge Value as an angle:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">double</span> ValueAngle
<span style="color: #008000;">&#123;</span>
  get
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>Gauge <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
      <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #FF0000;">0.0</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">return</span> ValueToAngle<span style="color: #008000;">&#40;</span>Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Value</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">double</span> ValueToAngle<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span> value<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #6666cc; font-weight: bold;">double</span> minAngle <span style="color: #008000;">=</span> <span style="color: #008000;">-</span><span style="color: #FF0000;">150</span><span style="color: #008000;">;</span>
  <span style="color: #6666cc; font-weight: bold;">double</span> maxAngle <span style="color: #008000;">=</span> <span style="color: #FF0000;">150</span><span style="color: #008000;">;</span>
  <span style="color: #6666cc; font-weight: bold;">double</span> angularRange <span style="color: #008000;">=</span> maxAngle <span style="color: #008000;">-</span> minAngle<span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span>value <span style="color: #008000;">-</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">/</span> <span style="color: #008000;">&#40;</span>Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Maximum</span> <span style="color: #008000;">-</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">*</span>
      angularRange <span style="color: #008000;">+</span> minAngle<span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>This can then be bound to in the template in order to rotate the needle. For an extra ‘flourish’ a drop shadow is also added to the needle which binds to this same rotation angle in order to give a subtle ‘3D’ effect:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path</span> <span style="color: #000066;">Stretch</span>=<span style="color: #ff0000;">&quot;Uniform&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.ColumnSpan</span>=<span style="color: #ff0000;">&quot;2&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">Stroke</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">StrokeThickness</span>=<span style="color: #ff0000;">&quot;0.5&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">Data</span>=<span style="color: #ff0000;">&quot;M 0,0 l 10,60 l -10, 40 l -10 -40&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">RenderTransformOrigin</span>=<span style="color: #ff0000;">&quot;0.5,1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- rotate the needle --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RotateTransform</span> <span style="color: #000066;">Angle</span>=<span style="color: #ff0000;">&quot;{Binding Path=ValueAngle}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path.Fill<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;LinearGradientBrush</span> <span style="color: #000066;">StartPoint</span>=<span style="color: #ff0000;">&quot;0,0&quot;</span> <span style="color: #000066;">EndPoint</span>=<span style="color: #ff0000;">&quot;1,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;DarkRed&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;DarkRed&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;0.45&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;Red&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;0.55&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;GradientStop</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;Red&quot;</span> <span style="color: #000066;">Offset</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/LinearGradientBrush<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path.Fill<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Path.Effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DropShadowEffect</span> <span style="color: #000066;">Color</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">Direction</span>=<span style="color: #ff0000;">&quot;{Binding Path=ValueAngle}&quot;</span></span>
<span style="color: #009900;">                      <span style="color: #000066;">BlurRadius</span>=<span style="color: #ff0000;">&quot;3&quot;</span></span>
<span style="color: #009900;">                      <span style="color: #000066;">Opacity</span>=<span style="color: #ff0000;">&quot;0.6&quot;</span></span>
<span style="color: #009900;">                      <span style="color: #000066;">ShadowDepth</span>=<span style="color: #ff0000;">&quot;5&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path.Effect<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Path<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/08/rotatedNeedle.jpg" alt="" title="rotatedNeedle" width="212" height="210" class="aligncenter size-full wp-image-769" /></p>
<h2>Adding a Scale</h2>
<p>The gauge control needs to have tick marks and labels render around the dial face at regularly spaced intervals between the Maximum and Minimum values. Here the view model comes into its own by providing a list of ‘Tick’ value objects, each of which provide the view with the required information to render tick marks and their labels:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> IEnumerable<span style="color: #008000;">&lt;</span>Tick<span style="color: #008000;">&gt;</span> MajorTicks
<span style="color: #008000;">&#123;</span>
  get
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>Gauge <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
      <span style="color: #0600FF; font-weight: bold;">yield</span> <span style="color: #0600FF; font-weight: bold;">break</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #6666cc; font-weight: bold;">double</span> tickSpacing <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Maximum</span> <span style="color: #008000;">-</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">/</span> <span style="color: #FF0000;">10</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span> tick <span style="color: #008000;">=</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Minimum</span><span style="color: #008000;">;</span> tick <span style="color: #008000;">&lt;=</span> Gauge<span style="color: #008000;">.</span><span style="color: #0000FF;">Maximum</span><span style="color: #008000;">;</span> tick <span style="color: #008000;">+=</span> tickSpacing<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      <span style="color: #0600FF; font-weight: bold;">yield</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> Tick<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        Angle <span style="color: #008000;">=</span> ValueToAngle<span style="color: #008000;">&#40;</span>tick<span style="color: #008000;">&#41;</span>,
        Value <span style="color: #008000;">=</span> tick<span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;N0&quot;</span><span style="color: #008000;">&#41;</span>,
        Parent <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">this</span>
      <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Tick
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">double</span> Angle <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Value <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> RadialGaugeControlViewModel Parent <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The XAML which renders the major tick marks uses an ItemsControl to create each tick instance:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- major ticks --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl</span> <span style="color: #000066;">ItemsSource</span>=<span style="color: #ff0000;">&quot;{Binding Path=MajorTicks}&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl.ItemsPanel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsPanelTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Canvas<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/Canvas<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsPanelTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl.ItemsPanel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;Black&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;8&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;8&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TransformGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- centre the ellipse --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TranslateTransform</span> <span style="color: #000066;">X</span>=<span style="color: #ff0000;">&quot;-4&quot;</span> <span style="color: #000066;">Y</span>=<span style="color: #ff0000;">&quot;-4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- offset to the edge of the gauge --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TranslateTransform</span> <span style="color: #000066;">X</span>=<span style="color: #ff0000;">&quot;0&quot;</span></span>
<span style="color: #009900;">                <span style="color: #000066;">Y</span>=<span style="color: #ff0000;">&quot;{Binding Path=Parent.GridHeight, Converter={StaticResource ScaleFactorConverter},</span>
<span style="color: #009900;">                                                                 ConverterParameter=-0.37}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- rotate --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RotateTransform</span> <span style="color: #000066;">Angle</span>=<span style="color: #ff0000;">&quot;{Binding Angle}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
          <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TransformGroup<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Ellipse.RenderTransform<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Ellipse<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ItemsControl<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>As you can see each tick is simply an ellipse. The clever part is how each Ellipse is transformed to position it appropriately. It is first centre to make subsequent transforms a little simpler, it is then translated y an offset which moves it to the edge of the gauge face. The offset factor is computed as some fraction of the overall size of the gauge control. In order to achieve this I reluctantly had to angle SizeChanged events on the template Grid in order to expose its ActualHeight / ActualWidth, this is because ElementName binding on these properties <a href="http://forums.silverlight.net/forums/t/180792.aspx">appears to be broken</a>. </p>
<p>On attachment the view model handles SizeChanged events as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
<span style="color: #008080; font-style: italic;">/// Handle SizeChanged events from the grid so that we can inform elements</span>
<span style="color: #008080; font-style: italic;">/// of changes in the ActualHeight / ActualWidth</span>
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
<span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">void</span> Grid_SizeChanged<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, SizeChangedEventArgs e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  OnPropertyChanged<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;GridHeight&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  OnPropertyChanged<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;GridWidth&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  Grid<span style="color: #008000;">.</span><span style="color: #0000FF;">Clip</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> EllipseGeometry<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    RadiusX <span style="color: #008000;">=</span> _grid<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualWidth</span> <span style="color: #008000;">/</span> <span style="color: #FF0000;">2</span>,
    RadiusY <span style="color: #008000;">=</span> _grid<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualHeight</span> <span style="color: #008000;">/</span> <span style="color: #FF0000;">2</span>,
    Center <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Point<span style="color: #008000;">&#40;</span>_grid<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualWidth</span> <span style="color: #008000;">/</span> <span style="color: #FF0000;">2</span>, _grid<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualHeight</span> <span style="color: #008000;">/</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">double</span> GridWidth
<span style="color: #008000;">&#123;</span>
  get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _grid<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualWidth</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">double</span> GridHeight
<span style="color: #008000;">&#123;</span>
  get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _grid<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualHeight</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Adding tick labels and minor tick marks both use a simple variation on the above described approach:</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/08/scale.jpg" alt="" title="scale" width="212" height="209" class="aligncenter size-full wp-image-770" /></p>
<p>I also added a ‘qualitative value’ range which renders a colour coded band beneath the needle. Again, this uses variations on the same approach, with the view model adapting the properties of the Gauge control and the template binding to these properties, together with the Grid size information in order to provide any required scaling.</p>
<p>The last flourish was to add a ‘glass’ effect to the Gauge. This was ‘borrowed’ directly from this fantastic codeproject article on creating ‘<a href="http://www.codeproject.com/KB/WPF/glassbuttons.aspx">round glassy buttons</a>’.</p>
<p>The finished Gauge is shown below, where its value is bound to a Slider control:</p>
<div><object width="300" height="300" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/08/GaugeControlTwo.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<h2>Conclusions</h2>
<p>I am pretty happy with how this Gauge control turned out, visually I think it looks pretty good. I am also happy that I have succeeded in my initial aim of making it completely lookless. The attached view model within the control template is an interesting approach that moves view specific concepts (in this case angular properties) into the view, which is where the belong.</p>
<p>This radial Gauge control could certainly be improved to allow a more flexible scale calculation. Also, the RadialGaugeControlViewModel could also expose some of the view specific properties such as the radial sweep angle (currently hard-coded to 300 degrees) allowing them to be set in the template. For now, I think I will leave this control as it is.</p>
<p>Tomorrow I am on another early flight, this time heading back home. I might take this as an opportunity to provide a view for this control making use of a different attached view model. </p>
<p>You can download the full source for this article: <a href='http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/08/GaugeControl.zip'>GaugeControl.zip</a></p>
<p>(Apologies for the lack of project structure, this code was written using VS 2010 Express).</p>
<p>Regards, Colin E.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/colin/2010/08/developing-a-very-lookless-silverlight-radial-gauge-control/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Exposing and Binding to a Silverlight ScrollViewer’s Scrollbars</title>
		<link>http://www.scottlogic.co.uk/blog/colin/2010/07/exposing-and-binding-to-a-silverlight-scrollviewer%e2%80%99s-scrollbars/</link>
		<comments>http://www.scottlogic.co.uk/blog/colin/2010/07/exposing-and-binding-to-a-silverlight-scrollviewer%e2%80%99s-scrollbars/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 19:59:26 +0000</pubDate>
		<dc:creator>Colin Eberhardt</dc:creator>
				<category><![CDATA[codeproject]]></category>
		<category><![CDATA[attached behaviour]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/colin/?p=740</guid>
		<description><![CDATA[The Silverlight ScrollViewer exposes readonly properties which indicate the current vertical and horizontal scroll offset, and methods for setting the current offset. In this blog post I demonstrate a simple attached behaviour that exposes these offsets as read / write dependency properties allowing them to be bound to. The Silverlight ScrollViewer is a very useful [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fcolin%252F2010%252F07%252Fexposing-and-binding-to-a-silverlight-scrollviewer%2525e2%252580%252599s-scrollbars%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Exposing%20and%20Binding%20to%20a%20Silverlight%20ScrollViewer%E2%80%99s%20Scrollbars%20%23%22%20%7D);"></div>
<p><em>The Silverlight ScrollViewer exposes readonly properties which indicate the current vertical and horizontal scroll offset, and methods for setting the current offset. In this blog post I demonstrate a simple attached behaviour that exposes these offsets as read / write dependency properties allowing them to be bound to.</em></p>
<p>The Silverlight ScrollViewer is a very useful control, if you have some content that is larger than the space available in your application, just sit it inside a ScrollViewer and it will automatically add vertical or horizontal scrollbars as required. Simple.</p>
<p>The ScrollViewer exposes readonly properties which indicate the current vertical and horizontal scroll offset. I have been used a ScrollViewer on many occasions without finding this to be an issue, however, recently I was creating an MVVM application which contained a list of items within a ScrollViewer. When the user clicks on an item, they are taken to its ‘details’ page, they then have the option to return to the list. I wanted the list to have the same state when the user returned to it, i.e. the same scroll location. Naturally, with this being an MVVM application, the scroll position belongs on the ViewModel and should be relayed to the View via a binding. However, with the offset properties on the ScrollViewer being readonly, this was not possible. Time to get creative!</p>
<p>The template of the ScrollViewer contains two ScrollBar instances, one horizontal and one vertical. The basic idea behind my solution is to add an attached behaviour (i.e. an attached property, that on attachment performs some logic on the target element) which walks the visual tree to find these scrollbars exposing their offset values.</p>
<p>Firstly, we’ll start by defining an attached property called VerticalOffset, which will be used to expose the position of the vertical scrollbar. Dependency property boiler plate code follows:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">class</span> ScrollViewerBinding
<span style="color: #008000;">&#123;</span>
  <span style="color: #008080;">#region VerticalOffset attached property</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Gets the vertical offset value</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">double</span> GetVerticalOffset<span style="color: #008000;">&#40;</span>DependencyObject depObj<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#41;</span>depObj<span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>VerticalOffsetProperty<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// Sets the vertical offset value</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> SetVerticalOffset<span style="color: #008000;">&#40;</span>DependencyObject depObj, <span style="color: #6666cc; font-weight: bold;">double</span> value<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    depObj<span style="color: #008000;">.</span><span style="color: #0000FF;">SetValue</span><span style="color: #008000;">&#40;</span>VerticalOffsetProperty, value<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
  <span style="color: #008080; font-style: italic;">/// VerticalOffset attached property</span>
  <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
  <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> DependencyProperty VerticalOffsetProperty <span style="color: #008000;">=</span>
      DependencyProperty<span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterAttached</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;VerticalOffset&quot;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#41;</span>,
      <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>ScrollViewerBinding<span style="color: #008000;">&#41;</span>, <span style="color: #008000;">new</span> PropertyMetadata<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0.0</span>, OnVerticalOffsetPropertyChanged<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
  <span style="color: #008080;">#endregion</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>We’ll also define a private attached property of type ScrollBar, which will be used to store a reference to the scrollbar once it has been located within the ScrollViewers visual tree:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
<span style="color: #008080; font-style: italic;">/// An attached property which holds a reference to the vertical scrollbar which</span>
<span style="color: #008080; font-style: italic;">/// is extracted from the visual tree of a ScrollViewer</span>
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
<span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> DependencyProperty VerticalScrollBarProperty <span style="color: #008000;">=</span>
    DependencyProperty<span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterAttached</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;VerticalScrollBar&quot;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>ScrollBar<span style="color: #008000;">&#41;</span>,
    <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>ScrollViewerBinding<span style="color: #008000;">&#41;</span>, <span style="color: #008000;">new</span> PropertyMetadata<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>Because this attached property is private, I haven&#8217;t bothered to create CLR property accessors which are only used for convenience.</p>
<p>The VerticalOffset attached property has a changed event handler. When the property is first attached to a ScrollViewer, this allows us to walk the visual tree constructed from the ScrollViewer’s template and extract the scrollbars. It is this extra logic that adds new functionality to the ScrollViewer which is what makes this an <a href="http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx">attached behaviour</a>, as opposed to a regular attached property which merely holds state.</p>
<p>When an attached property is first associated with its target, the visual tree described by the target&#8217;s template has not yet been constructed. With WPF, you would typically register for the <a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.loaded.aspx">Loaded</a> event on the target, and on handling this event walk the visual tree that will have been constructed. However, in Silverlight there is a very subtle difference, apparently <a href="http://blogs.msdn.com/b/silverlight_sdk/archive/2008/10/24/loaded-event-timing-in-silverlight.aspx">the Loaded event is not guaranteed to occur after the template is applied</a>. Oh dear. The only other alternative is to handle the <a href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.layoutupdated.aspx">LayoutUpdated</a> which is fired whenever changes are made to the visual tree. However, there is another complication! The LayoutUpdated event always has a null sender, this might look like a bug, but it is actually <a href="http://connect.microsoft.com/VisualStudio/feedback/details/293803/wpf-layoutupdated-has-sender-always-null">by design</a>. This means that if we handle the LayoutUpdated event on the ScrollViewer element which the property is attached to, the method invoked as the event handler no longer has a reference to the ScrollViewer!</p>
<p>In order to get around this problem, the attached property changed handler is as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
<span style="color: #008080; font-style: italic;">/// Invoked when the VerticalOffset attached property changes</span>
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
<span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnVerticalOffsetPropertyChanged<span style="color: #008000;">&#40;</span>DependencyObject d,
    DependencyPropertyChangedEventArgs e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  ScrollViewer sv <span style="color: #008000;">=</span> d <span style="color: #0600FF; font-weight: bold;">as</span> ScrollViewer<span style="color: #008000;">;</span>
  <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>sv <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #008080; font-style: italic;">// check whether we have a reference to the vertical scrollbar</span>
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>sv<span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>VerticalScrollBarProperty<span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
      <span style="color: #008080; font-style: italic;">// if not, handle LayoutUpdated, which will be invoked after the</span>
      <span style="color: #008080; font-style: italic;">// template is applied and extract the scrollbar</span>
      sv<span style="color: #008000;">.</span><span style="color: #0000FF;">LayoutUpdated</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">&#40;</span>s, ev<span style="color: #008000;">&#41;</span> <span style="color: #008000;">=&gt;</span>
        <span style="color: #008000;">&#123;</span>
          <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>sv<span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>VerticalScrollBarProperty<span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
          <span style="color: #008000;">&#123;</span>
            GetScrollBarsForScrollViewer<span style="color: #008000;">&#40;</span>sv<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
          <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">else</span>
    <span style="color: #008000;">&#123;</span>
      <span style="color: #008080; font-style: italic;">// update the scrollviewer offset</span>
      sv<span style="color: #008000;">.</span><span style="color: #0000FF;">ScrollToVerticalOffset</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span><span style="color: #008000;">&#41;</span>e<span style="color: #008000;">.</span><span style="color: #0000FF;">NewValue</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Firstly, we check whether we have already got a reference to the scrollbar, if not, we attached a LayoutUpdated event handler. But instead of defining this handler as a method, it is written as an  lambda expression (i.e. an anonymous delegate), so that the ScrollViewer reference is <a href="http://diditwith.net/PermaLink,guid,235646ae-3476-4893-899d-105e4d48c25b.aspx">captured using closure</a>.</p>
<p>When the LayoutUpdated event is fired the following method is invoked:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
<span style="color: #008080; font-style: italic;">/// Attempts to extract the scrollbars that are within the scrollviewers</span>
<span style="color: #008080; font-style: italic;">/// visual tree. When extracted, event handlers are added to their ValueChanged events.</span>
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
<span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> GetScrollBarsForScrollViewer<span style="color: #008000;">&#40;</span>ScrollViewer scrollViewer<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  ScrollBar scroll <span style="color: #008000;">=</span> GetScrollBar<span style="color: #008000;">&#40;</span>scrollViewer, Orientation<span style="color: #008000;">.</span><span style="color: #0000FF;">Vertical</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
  <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>scroll <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #008080; font-style: italic;">// save a reference to this scrollbar on the attached property</span>
    scrollViewer<span style="color: #008000;">.</span><span style="color: #0000FF;">SetValue</span><span style="color: #008000;">&#40;</span>VerticalScrollBarProperty, scroll<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// scroll the scrollviewer</span>
    scrollViewer<span style="color: #008000;">.</span><span style="color: #0000FF;">ScrollToVerticalOffset</span><span style="color: #008000;">&#40;</span>
      ScrollViewerBinding<span style="color: #008000;">.</span><span style="color: #0000FF;">GetVerticalOffset</span><span style="color: #008000;">&#40;</span>scrollViewer<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
&nbsp;
    <span style="color: #008080; font-style: italic;">// handle the changed event to update the exposed VerticalOffset</span>
    scroll<span style="color: #008000;">.</span><span style="color: #0000FF;">ValueChanged</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">&#40;</span>s, e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">=&gt;</span>
      <span style="color: #008000;">&#123;</span>
        SetVerticalOffset<span style="color: #008000;">&#40;</span>scrollViewer, e<span style="color: #008000;">.</span><span style="color: #0000FF;">NewValue</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
      <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
<span style="color: #008080; font-style: italic;">/// Searches the descendants of the given element, looking for a scrollbar</span>
<span style="color: #008080; font-style: italic;">/// with the given orientation.</span>
<span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
<span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> ScrollBar GetScrollBar<span style="color: #008000;">&#40;</span>FrameworkElement fe, Orientation orientation<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0600FF; font-weight: bold;">return</span> fe<span style="color: #008000;">.</span><span style="color: #0000FF;">Descendants</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">.</span><span style="color: #0000FF;">OfType</span><span style="color: #008000;">&lt;</span>ScrollBar<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">Where</span><span style="color: #008000;">&#40;</span>s <span style="color: #008000;">=&gt;</span> s<span style="color: #008000;">.</span><span style="color: #0000FF;">Orientation</span> <span style="color: #008000;">==</span> orientation<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">.</span><span style="color: #0000FF;">SingleOrDefault</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The GetScrollBar method is invoked, which then uses <a href="http://www.scottlogic.co.uk/blog/colin/2010/03/linq-to-visual-tree/">Linq-to-VisualTree</a> to walk the descendants of the ScrollViewer in an attempt  to find scrollbars of a given orientation. If one is found, it is stored in the private attached property. We also subscribe to the events which the scrollbar raises when its value changes, in order to update the VerticalOffsetProperty. Again, a lambda expression is used to capture the ScrollViewer which this scrollbar is associated with, so that we do not have to store a relationship from scrollbar to scrollviewer.</p>
<p>As an aside, it would have been a bit more elegant to use binding to connect our VerticalScrollOffset to the scrollbar value as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">scroll<span style="color: #008000;">.</span><span style="color: #0000FF;">SetBinding</span><span style="color: #008000;">&#40;</span>ScrollBar<span style="color: #008000;">.</span><span style="color: #0000FF;">ValueProperty</span>,
  <span style="color: #008000;">new</span> Binding<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;(ScrollViewerBinding.VerticalOffset)&quot;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    Source <span style="color: #008000;">=</span> scrollViewer
  <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>However, it appears that there is a <a href="http://forums.silverlight.net/forums/p/153389/342703.aspx">bug in Silverlight</a> which makes binding to custom attached properties in code behind fail with a critical error. Until this is fixed, we have to take care of the ‘binding’, by handling change events from both properties, manually.</p>
<p>Using this attached behaviour is as simple as the following:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ScrollViewer</span> </span>
<span style="color: #009900;">    <span style="color: #000066;">local:ScrollViewerBinding.VerticalOffset</span>=<span style="color: #ff0000;">&quot;{Binding YPosition, Mode=TwoWay}&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">local:ScrollViewerBinding.HorizontalOffset</span>=<span style="color: #ff0000;">&quot;{Binding XPosition, Mode=TwoWay}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- Big content goes here! --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ScrollViewer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The following little demo binds the X &#038; Y offset of the scrollviewer to two CLR properties (with property changed notifications) defined in code behind. These same properties are bound to the text fields below:</p>
<div id="slPluginHost1" > <object id="SilverlightPlugin1" width="400" height="180" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/07/ScrollOffsetBinding.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<p>You can download the complete sourcecode for this blog post: <a href='http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2010/07/ScrollOffsetBinding.zip'>ScrollOffsetBinding.zip</a></p>
<p>Regards, Colin E.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/colin/2010/07/exposing-and-binding-to-a-silverlight-scrollviewer%e2%80%99s-scrollbars/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Silverlight ClipToBounds &#8211; Can I Clip It?, Yes You Can!</title>
		<link>http://www.scottlogic.co.uk/blog/colin/2009/05/silverlight-cliptobounds-can-i-clip-it-yes-you-can/</link>
		<comments>http://www.scottlogic.co.uk/blog/colin/2009/05/silverlight-cliptobounds-can-i-clip-it-yes-you-can/#comments</comments>
		<pubDate>Tue, 12 May 2009 07:30:47 +0000</pubDate>
		<dc:creator>Colin Eberhardt</dc:creator>
				<category><![CDATA[codeproject]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[attached behaviour]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/colin/?p=292</guid>
		<description><![CDATA[With Silverlight, Panels do not clip their contents by default. See the following example: Where we have a Grid containing another Grid which itself contains an ellipse, and a Canvas which contains an ellipse: &#60;Grid x:Name=&#34;LayoutRoot&#34; Background=&#34;White&#34;&#62; &#60;Grid.ColumnDefinitions&#62; &#60;ColumnDefinition Width=&#34;*&#34;/&#62; &#60;ColumnDefinition Width=&#34;*&#34;/&#62; &#60;/Grid.ColumnDefinitions&#62; &#160; &#60;Grid Grid.Column=&#34;0&#34; Background=&#34;Blue&#34; Margin=&#34;20&#34;&#62; &#60;Grid Background=&#34;Yellow&#34; Margin=&#34;20,40,-20,20&#34;&#62; &#60;Ellipse Fill=&#34;LightGreen&#34; Width=&#34;80&#34; Height=&#34;80&#34; [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fcolin%252F2009%252F05%252Fsilverlight-cliptobounds-can-i-clip-it-yes-you-can%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Silverlight%20ClipToBounds%20-%20Can%20I%20Clip%20It%3F%2C%20Yes%20You%20Can%21%20%23%22%20%7D);"></div>
<p>With Silverlight, Panels do not clip their contents by default. See the following example:</p>
<p><a href="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/05/noclip.png"><img class="aligncenter size-full wp-image-293" title="noclip" src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/05/noclip.png" alt="noclip" width="292" height="187" /></a></p>
<p>Where we have a Grid containing another Grid which itself contains an ellipse, and a Canvas which contains an ellipse:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;LayoutRoot&quot;</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;White&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;Blue&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;20&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>                        
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;Yellow&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;20,40,-20,20&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;LightGreen&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;80&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;80&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;-40, -40, 0, 0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Canvas</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span>  <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;Aqua&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;20&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;Red&quot;</span> <span style="color: #000066;">Canvas.Top</span>=<span style="color: #ff0000;">&quot;-10&quot;</span> <span style="color: #000066;">Canvas.Left</span>=<span style="color: #ff0000;">&quot;-10&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;130&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;130&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Canvas<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Often this is not the desired effect (although it is actually quite a useful feature of Canvas; You can simply add a Canvas to your visual tree without explicitly or implicitly setting its Size and use it as a mechanism for absolute positioning its children).</p>
<p>Fortunately Silverlight provides a Clip property on UIElement, allowing you to provide the clipping geometry for the element:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;100&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>       
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.Clip<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RectangleGeometry</span> <span style="color: #000066;">Rect</span>=<span style="color: #ff0000;">&quot;0, 0, 200, 100&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.Clip<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The above example creates a clipping geometry which matches the rectangular geometry of the Grid itself. Clearly more funky clipping geometries can be created, allowing for really cool effects, however most of the time I simply want my Panel clipped so that its children cannot escape!</p>
<p>The above example has a few problems, Firstly, it is a bit long-winded having to explicitly create the geometry each time I want to clip; Secondly, if my Grid&#8217;s size is calculated from its parent&#8217;s layout, how can I define the clip geometry in my XAML?; Finally, if my Grid&#8217;s geometry changes, its clipped geometry does not change.</p>
<p>In order to solve this problem I created a simple little <a href="http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx">attached behaviour</a>, which allows you to define the clipping using the attached property Clip.ToBounds as illustrated below:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;UserControl</span> <span style="color: #000066;">x:Class</span>=<span style="color: #ff0000;">&quot;SilverlightClipToBounds.Page&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span> </span>
<span style="color: #009900;">    <span style="color: #000066;">xmlns:x</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span> </span>
<span style="color: #009900;">    <span style="color: #000066;">xmlns:util</span>=<span style="color: #ff0000;">&quot;clr-namespace:Util&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;300&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;200&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;LayoutRoot&quot;</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;White&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;Blue&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;20&quot;</span> <span style="color: #000066;">util:Clip.ToBounds</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>       
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;Yellow&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;20,40,-20,20&quot;</span> <span style="color: #000066;">util:Clip.ToBounds</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;LightGreen&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;80&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;80&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;-40, -40, 0, 0&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Canvas</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span>  <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;Aqua&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;20&quot;</span> <span style="color: #000066;">util:Clip.ToBounds</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;Red&quot;</span> <span style="color: #000066;">Canvas.Top</span>=<span style="color: #ff0000;">&quot;-10&quot;</span> <span style="color: #000066;">Canvas.Left</span>=<span style="color: #ff0000;">&quot;-10&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;130&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;130&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Canvas<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/UserControl<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The result can be seen below:</p>
<p><a href="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/05/crop.png"><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/05/crop.png" alt="crop" title="crop" width="277" height="179" class="aligncenter size-full wp-image-296" /></a></p>
<p>And here is the code for the attached behaviour itself:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Clip
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">bool</span> GetToBounds<span style="color: #008000;">&#40;</span>DependencyObject depObj<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">bool</span><span style="color: #008000;">&#41;</span>depObj<span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>ToBoundsProperty<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> SetToBounds<span style="color: #008000;">&#40;</span>DependencyObject depObj, <span style="color: #6666cc; font-weight: bold;">bool</span> clipToBounds<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        depObj<span style="color: #008000;">.</span><span style="color: #0000FF;">SetValue</span><span style="color: #008000;">&#40;</span>ToBoundsProperty, clipToBounds<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Identifies the ToBounds Dependency Property.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> DependencyProperty ToBoundsProperty <span style="color: #008000;">=</span>
        DependencyProperty<span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterAttached</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ToBounds&quot;</span>, <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">bool</span><span style="color: #008000;">&#41;</span>,
        <span style="color: #008000;">typeof</span><span style="color: #008000;">&#40;</span>Clip<span style="color: #008000;">&#41;</span>, <span style="color: #008000;">new</span> PropertyMetadata<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">false</span>, OnToBoundsPropertyChanged<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnToBoundsPropertyChanged<span style="color: #008000;">&#40;</span>DependencyObject d,
        DependencyPropertyChangedEventArgs e<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        FrameworkElement fe <span style="color: #008000;">=</span> d <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>fe <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            ClipToBounds<span style="color: #008000;">&#40;</span>fe<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">// whenever the element which this property is attached to is loaded</span>
            <span style="color: #008080; font-style: italic;">// or re-sizes, we need to update its clipping geometry</span>
            fe<span style="color: #008000;">.</span><span style="color: #0000FF;">Loaded</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">new</span> RoutedEventHandler<span style="color: #008000;">&#40;</span>fe_Loaded<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            fe<span style="color: #008000;">.</span><span style="color: #0000FF;">SizeChanged</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">new</span> SizeChangedEventHandler<span style="color: #008000;">&#40;</span>fe_SizeChanged<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Creates a rectangular clipping geometry which matches the geometry of the</span>
    <span style="color: #008080; font-style: italic;">/// passed element</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> ClipToBounds<span style="color: #008000;">&#40;</span>FrameworkElement fe<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>GetToBounds<span style="color: #008000;">&#40;</span>fe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            fe<span style="color: #008000;">.</span><span style="color: #0000FF;">Clip</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> RectangleGeometry<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                Rect <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Rect<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0</span>, <span style="color: #FF0000;">0</span>, fe<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualWidth</span>, fe<span style="color: #008000;">.</span><span style="color: #0000FF;">ActualHeight</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#125;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">else</span>
        <span style="color: #008000;">&#123;</span>
            fe<span style="color: #008000;">.</span><span style="color: #0000FF;">Clip</span> <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> fe_SizeChanged<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, SizeChangedEventArgs e<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        ClipToBounds<span style="color: #008000;">&#40;</span>sender <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> fe_Loaded<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, RoutedEventArgs e<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        ClipToBounds<span style="color: #008000;">&#40;</span>sender <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>    
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>When the <code>ToBounds</code> property is associated with an element, <code>ClipToBounds</code> is invoked to create a rectangular clip geometry. We also add event handlers for <code>Loaded</code>, which is a very useful event which is fired when an element has been laid out and rendered, in other words it&#8217;s size will have been computed, and <code>SizeChanged</code>. In the event handlers for both we simply update the clipping geometry.</p>
<p>This can be seen in action here, where clicking on the Grids or Canvas increases their size, with the clipping geometry growing accordingly:</p>
<div id="slPluginHost"> <object id="SilverlightPlugin" width="300" height="300" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/05/silverlightcliptobounds.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<p>You can download a demo project here: <a href='http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/05/sliverlightcliptobounds.zip'>sliverlightcliptobounds.zip</a></p>
<p>Can I Clip It?, Yes You Can!</p>
<p>Regards, Colin E.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/colin/2009/05/silverlight-cliptobounds-can-i-clip-it-yes-you-can/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Using CSS Selectors for Styling in WPF</title>
		<link>http://www.scottlogic.co.uk/blog/colin/2009/03/using-css-selectors-for-styling-in-wpf/</link>
		<comments>http://www.scottlogic.co.uk/blog/colin/2009/03/using-css-selectors-for-styling-in-wpf/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 17:14:31 +0000</pubDate>
		<dc:creator>Colin Eberhardt</dc:creator>
				<category><![CDATA[codeproject]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[attached behaviour]]></category>
		<category><![CDATA[styling]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/colin/?p=193</guid>
		<description><![CDATA[When I first encountered WPF I was really impressed by its styling and templating features which are more powerful than anything else I had previously seen for desktop software development. The property-value pairing within styles instantly reminded me of CSS, however the WPF styles lack the most powerful feature of CSS &#8211; the selector. This [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fcolin%252F2009%252F03%252Fusing-css-selectors-for-styling-in-wpf%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Using%20CSS%20Selectors%20for%20Styling%20in%20WPF%20%23%22%20%7D);"></div>
<p>When I first encountered WPF I was really impressed by its styling and templating features which are more powerful than anything else I had previously seen for desktop software development. The property-value pairing within styles instantly reminded me of CSS, however the WPF styles lack the most powerful feature of CSS &#8211; the selector. This blog post describes an attached behaviour for styling WPF application using CSS selectors.</p>
<p>Let&#8217;s first look at the anatomy of CSS. A CSS stylesheet is composed of a number of <em>rules</em>, each rule is composed of a <em>selector</em> which provides a pattern which the CSS selector engine matches against the target HTML document to locate nodes which to apply the style to. The styling information itself is defined within a <em>declaration block</em>, which consists of a number of comma-separated <em>declarations</em> enclosed within braces. The declaration block looks quite similar to a style within WPF &#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">div <span style="color: #00AA00;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Style</span> <span style="color: #000066;">TargetType</span>=<span style="color: #ff0000;">&quot;TextBlock&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Setter</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;FontSize&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;10&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>So let&#8217;s ignore the declaration block for the moment and concentrate on the interesting part, the CSS selector.</p>
<p>Selectors define a pattern which is matched, the information which the selector contains can include the element (tag) type, class or ID. More complex selectors might also include element attribute values or use pseudo-classes. We can easily find parallel concepts to these within WPF &#8230;</p>
<ul>
<li>HTML element type (e.g. div, p, a) => dependency object type (e.g. TextBlock, Button)</li>
<li>HTML ID (#menu) => dependency object Name (e.g. x:Name=&#8221;menu&#8221;)</li>
<li>HTML class (.title) => attached class property (e.g. css:Css.Class=&#8221;menu&#8221;)</li>
</ul>
<p>The only concept for which there really is no correspondent in WPF is CSS class. This can easily be introduced via an attached property.</p>
<p>So now that we have the concept mapping, all we need now is a CSS selector engine that can apply our selector in order to extract matching objects from our visual / logical tree. Luckily I found a .NET CSS selector engine implementation in codeplex called Fizzler, you can read about it on the <a href="http://colinramsay.co.uk/diary/2008/10/19/fizzler-a-css-selector-engine-for-c-sharp/">authors blog</a>, or go straight to codeplex to <a href="http://code.google.com/p/fizzler/">download it</a>. The author of this engine, Colin Ramsay, had done a great job of the implementation and had also written an exhaustive set of unit tests. The engine itself was tightly coupled to HtmlDocumentNodes, however I was able to slide a simple interface between the selector engine and the HTML document types as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">interface</span> IDocumentNode
<span style="color: #008000;">&#123;</span>
    IAttributeCollection Attributes <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    List<span style="color: #008000;">&lt;</span>IDocumentNode<span style="color: #008000;">&gt;</span> ChildNodes <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    IDocumentNode ParentNode <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    IDocumentNode PreviousSibling <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #6666cc; font-weight: bold;">string</span> Id <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #6666cc; font-weight: bold;">string</span> <span style="color: #6666cc; font-weight: bold;">Class</span> <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #6666cc; font-weight: bold;">string</span> Name <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #6666cc; font-weight: bold;">bool</span> IsElement <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">interface</span> IAttributeCollection
<span style="color: #008000;">&#123;</span>
    IAttribute <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">&#91;</span><span style="color: #6666cc; font-weight: bold;">string</span> name<span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">interface</span> IAttribute
<span style="color: #008000;">&#123;</span>
    <span style="color: #6666cc; font-weight: bold;">string</span> Value <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Again, thanks to the extensive unit tests, this refactor only took ~ 40 minutes.</p>
<p>The next job was to create an implementation of the above interfaces that walks the visual / logical trees, both were pretty easy to implement using the LogicalTreeHelper and VisualTreeHelper classes. With these classes implemented, I was able to query the visual tree using selectors as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">SelectorEngine engine <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> SelectorEngine<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
IList<span style="color: #008000;">&lt;</span>IDocumentNode<span style="color: #008000;">&gt;</span> matchingNodes <span style="color: #008000;">=</span> engine<span style="color: #008000;">.</span><span style="color: #0000FF;">Parse</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;.form TextBlock.warning&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #008080; font-style: italic;">// apply the style to all matching nodes</span>
<span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>DependencyObjectNode matchingNode <span style="color: #0600FF; font-weight: bold;">in</span> matchingNodes<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #008000;">...</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>In the above example, the selector engine returns any TextBlock with the class &#8216;warning&#8217;, which is a descendant of any element with the class &#8216;form&#8217;. This is certainly a novel way of querying the visual tree! </p>
<p>The next step is to define the declaration block and apply the style which they define to any matching elements.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> StyleDeclarationBlock <span style="color: #008000;">:</span> List<span style="color: #008000;">&lt;</span>StyleDeclaration<span style="color: #008000;">&gt;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> StyleDeclaration
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Property <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">object</span> Value <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>We can construct style declarations within XAML as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;BorderThickness&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;BorderBrush&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;Black&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;CornerRadius&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;5&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Margin&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;10,10,10,10&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The process for applying a style is pretty straightforward, the only subtle complication is that styles, once applied are frozen (i.e. immutable). Therefore, each time an element is selected via our selector engine, we clone the existing style then merge it with the new one. See the attached source-code for details.</p>
<p>Putting it all together involves the creation of an <a href="http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx">Attached Behaviour</a> which associates a stylesheet with an element within our XAML. When the element is loaded, the rules within the stylesheet are applied. Let&#8217;s look at a simple demo &#8230;</p>
<p>Here is a simple UI defined in XAML. Note the absence of any styling information:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Border</span> <span style="color: #000066;">css:Css.Class</span>=<span style="color: #ff0000;">&quot;form&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>                
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;StackPanel</span> <span style="color: #000066;">Orientation</span>=<span style="color: #ff0000;">&quot;Vertical&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">css:Css.Class</span>=<span style="color: #ff0000;">&quot;title&quot;</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;User Details&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Top&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>    
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>  
&nbsp;
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>        
&nbsp;
&nbsp;
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">css:Css.Class</span>=<span style="color: #ff0000;">&quot;mandatory&quot;</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Name&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span>  <span style="color: #000066;">css:Css.Class</span>=<span style="color: #ff0000;">&quot;mandatory&quot;</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Anthony Gatto&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Age&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span>  <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;36&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Profession&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span>  <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;Performer&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Button</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;3&quot;</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>Submit<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Button<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/StackPanel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Border<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The resulting UI looks like this:</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/03/no-style.png" alt="no-style" title="no-style" width="299" height="199" class="alignnone size-full wp-image-197" /></p>
<p>Now we apply our stylesheet to the root element in our XAML:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleSheet</span> <span style="color: #000066;">x:Key</span>=<span style="color: #ff0000;">&quot;cssStyles&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleSheet.Rules<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleRule</span> <span style="color: #000066;">Selector</span>=<span style="color: #ff0000;">&quot;.form Grid *&quot;</span> <span style="color: #000066;">SelectorType</span>=<span style="color: #ff0000;">&quot;LogicalTree&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleRule.DeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Margin&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;4,4,4,4&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleRule.DeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleRule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleRule</span> <span style="color: #000066;">Selector</span>=<span style="color: #ff0000;">&quot;.form TextBlock.mandatory&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleRule.DeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Foreground&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;Red&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleRule.DeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleRule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleRule</span> <span style="color: #000066;">Selector</span>=<span style="color: #ff0000;">&quot;Border.form&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleRule.DeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;BorderThickness&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;BorderBrush&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;Black&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;CornerRadius&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;5&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Margin&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;10,10,10,10&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleRule.DeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleRule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleRule</span> <span style="color: #000066;">Selector</span>=<span style="color: #ff0000;">&quot;.form .title&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleRule.DeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;HorizontalAlignment&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;Stretch&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;HorizontalContentAlignment&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;Center&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Background&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;DarkBlue&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Foreground&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;White&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;FontSize&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;13&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;Padding&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;3,3,3,3&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;css:StyleDeclaration</span> <span style="color: #000066;">Property</span>=<span style="color: #ff0000;">&quot;FontWeight&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;Bold&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleDeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleRule.DeclarationBlock<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleRule<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleSheet.Rules<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/css:StyleSheet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
...
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">css:Css.StyleSheet</span>=<span style="color: #ff0000;">&quot;{StaticResource cssStyles}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></pre></div></div>

<p>Which styles our WPF application as follows:</p>
<p><img src="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/03/styled.png" alt="styled" title="styled" width="299" height="299" class="alignnone size-full wp-image-199" /></p>
<p>Let&#8217;s look at those selector in a little more detail. The first one, <code>&lt;css:StyleRule Selector=".form Grid *" SelectorType="LogicalTree"&gt;</code> is quite interesting. Here we are selecting everything within the Grid within our form and applying a margin. Note that here we are using a selector on the logical tree, otherwise we will also match elements within the control template of our TextBoxes and Buttons and will hence apply the margin internally within these elements also. However, in other contexts the ability to be able to apply styles within a controls template is a powerful concept.</p>
<p>The next selector  <code>&lt;css:StyleRule Selector=".form TextBlock.mandatory"&gt;</code> styles our mandatory fields, the others styling the form title and borders.</p>
<p>The above is a pretty simple demonstration. The Fizzler CSS engine implements most of the CSS2.1 selectors and also some CSS3, so much more complex selector logic is possible. You can also include multiple comma-separated selectors on a rule.</p>
<p>Currently this code is not what I would call production-ready. It is just an idea that has been bugging me for a while that I wanted to get out of my head and share. I think this approach has a number of merits and it overcomes some of the restrictions in WPF styling. It provides a much more flexible mechanism for styling your UI, WPF gives you explicit styles and implicit styles, neither of which match the power of the CSS selector. This approach also adds the ability to merge styles, so if an element is matched by multiple rules these styles are merged. Furthermore, this approach does not impose the restriction that styles must have a TargetType, if the matching element does not have a corresponding dependency property, it simply does not pick up that piece of style information.</p>
<p>However, this implementation is not quite complete. I have not considered how to apply styles to dynamically generated content, ItemsControls for example. </p>
<p>I would be very interested to hear peoples opinions on this idea. Do you thin kit has potential? Perhaps if it was ported to Silverlight &#8211; it could even include mapping rules form &#8216;real&#8217; CSS documents so that your Silverlight application could share style information with the rest of the web page which hosts it. But that is a job for another day &#8230;</p>
<p>You can download the code for this blog post here: <a href="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/03/wpfcssstyling.zip">wpfcssstyling.zip</a></p>
<p><span style="color:red">UPDATE</span> &#8211; the concept of using CSS to style WPF and Silvelight applications has been discussed on the <a href="http://groups.google.com/group/wpf-disciples/t/251c90f31f603a8">WPF Discisples Group</a>.</p>
<p>Regards, Colin E.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/colin/2009/03/using-css-selectors-for-styling-in-wpf/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Implementing RelativeSource binding in Silverlight</title>
		<link>http://www.scottlogic.co.uk/blog/colin/2009/02/relativesource-binding-in-silverlight/</link>
		<comments>http://www.scottlogic.co.uk/blog/colin/2009/02/relativesource-binding-in-silverlight/#comments</comments>
		<pubDate>Fri, 27 Feb 2009 14:57:35 +0000</pubDate>
		<dc:creator>Colin Eberhardt</dc:creator>
				<category><![CDATA[codeproject]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[attached behaviour]]></category>
		<category><![CDATA[binding]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">http://www.scottlogic.co.uk/blog/colin/?p=139</guid>
		<description><![CDATA[In my previous post I demonstrated how an the WPF ElementName style binding can be emulated with Silverlight via an attached behaviour. As a brief recap, the technique involved creating an attached property, which when bound, adds a handler for the elements Loaded event. When the element is loaded, the even handler locates the named [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_light-green" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fwww.scottlogic.co.uk%252Fblog%252Fcolin%252F2009%252F02%252Frelativesource-binding-in-silverlight%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Implementing%20RelativeSource%20binding%20in%20Silverlight%20%23%22%20%7D);"></div>
<p>In my <a href="http://www.scottlogic.co.uk/blog/colin/2009/02/elementname-binding-in-silverlight-via-attached-behaviours/">previous post</a> I demonstrated how an the WPF ElementName style binding can be emulated with Silverlight via an attached behaviour. As a brief recap, the technique involved creating an attached property, which when bound, adds a handler for the elements Loaded event. When the element is loaded, the even handler locates the named element and constructs a binding via a relay object. Here is the attached property in use:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Rectangle</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;20&quot;</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;Green&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingProperties</span> <span style="color: #000066;">ElementName</span>=<span style="color: #ff0000;">&quot;Slider&quot;</span> <span style="color: #000066;">SourceProperty</span>=<span style="color: #ff0000;">&quot;Value&quot;</span> <span style="color: #000066;">TargetProperty</span>=<span style="color: #ff0000;">&quot;Width&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Rectangle<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Slider</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;Slider&quot;</span> <span style="color: #000066;">Value</span>=<span style="color: #ff0000;">&quot;20&quot;</span> <span style="color: #000066;">Minimum</span>=<span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #000066;">Maximum</span>=<span style="color: #ff0000;">&quot;300&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>Where the Rectangle&#8217;s Width is bound to the Slider&#8217;s Value. For details, and sourcecode, visit <a href="http://www.scottlogic.co.uk/blog/colin/2009/02/elementname-binding-in-silverlight-via-attached-behaviours/">this blog post</a>. Here I am going to extend this attached behaviour in order to emulate WPF&#8217;s RelativeSource binding.</p>
<p>For much of the time you will want to bind your visual elements to your data objects via their DataContext property. However, there are often times when you want too perform a binding for pure presentation purposes, for example, binding the width of two elements together. In this context WPFs RelativeSource and ElementName binding prove to be powerful and useful features of the binding framework.</p>
<p>Here I will extend the attached behaviour I described in my previous post to add RelativeSource binding capabilities. The properties of the attached property type have been extended:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> BindingProperties
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> SourceProperty <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> ElementName <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> TargetProperty <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> IValueConverter Converter <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">object</span> ConverterParameter <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">bool</span> RelativeSourceSelf <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> RelativeSourceAncestorType <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> RelativeSourceAncestorLevel <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> BindingProperties<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        RelativeSourceAncestorLevel <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>With the RelativeSourceSelf, RelativeSourceAncestorType and RelativeSourceAncestorLevel properties being used for relative source bindings. Taking RelativeSourceSelf as our first example, within WPF a <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.relativesource.self.aspx">RelativeSource.Self</a> property indicates that the source of a binding should be the element which the binding is associated with. (I know &#8211; it sounds a bit crazy, but search <a href="http://www.google.co.uk/search?q=RelativeSource+Self">google</a>, it is surprisingly useful!).</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnBinding<span style="color: #008000;">&#40;</span>
    DependencyObject depObj, DependencyPropertyChangedEventArgs e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    FrameworkElement targetElement <span style="color: #008000;">=</span> depObj <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">;</span>
&nbsp;
    targetElement<span style="color: #008000;">.</span><span style="color: #0000FF;">Loaded</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">new</span> RoutedEventHandler<span style="color: #008000;">&#40;</span>TargetElement_Loaded<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> TargetElement_Loaded<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, RoutedEventArgs e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    FrameworkElement targetElement <span style="color: #008000;">=</span> sender <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// get the value of our attached property</span>
    BindingProperties bindingProperties <span style="color: #008000;">=</span> GetBinding<span style="color: #008000;">&#40;</span>targetElement<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>bindingProperties<span style="color: #008000;">.</span><span style="color: #0000FF;">ElementName</span> <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">// perform our 'ElementName' lookup</span>
        <span style="color: #008000;">...</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>bindingProperties<span style="color: #008000;">.</span><span style="color: #0000FF;">RelativeSourceSelf</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">// bind an element to itself.</span>
        CreateRelayBinding<span style="color: #008000;">&#40;</span>targetElement, targetElement, bindingProperties<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>When the attached property becomes attached to our target element it adds a handler for the elements Loaded event (this is the <em>attached behaviour</em>). Within the event handler, we determine whether this is a relative source binding. If this is the case, the CreateRelayBinding method is invoked where the source and target element parameters are the same element. For details of how the CreateRelayBinding method works, see the <a href="http://www.scottlogic.co.uk/blog/colin/2009/02/elementname-binding-in-silverlight-via-attached-behaviours/">previous blog post</a>.  An example of a relative-source self binding is show below, where a TextBox&#8217;s Width property is bound to its Text, if you trype in a new text value, the TextBox Width adjusts accordingly.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;0,5,0,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingProperties</span> <span style="color: #000066;">TargetProperty</span>=<span style="color: #ff0000;">&quot;Width&quot;</span> <span style="color: #000066;">SourceProperty</span>=<span style="color: #ff0000;">&quot;Text&quot;</span></span>
<span style="color: #009900;">                                 <span style="color: #000066;">RelativeSourceSelf</span>=<span style="color: #ff0000;">&quot;True&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>                                
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TextBox<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The next type of RelativeSource binding I am going to tackle is the FindAncestor mode. You use this type of binding when you want to bind to an element of a specific type that is located further up the visual tree that the target element. The following code snippet shows how the attached behaviour achieves this type of binding:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> TargetElement_Loaded<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, RoutedEventArgs e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    FrameworkElement targetElement <span style="color: #008000;">=</span> sender <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">// get the value of our attached property</span>
    BindingProperties bindingProperties <span style="color: #008000;">=</span> GetBinding<span style="color: #008000;">&#40;</span>targetElement<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>bindingProperties<span style="color: #008000;">.</span><span style="color: #0000FF;">ElementName</span> <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">// perform our 'ElementName' lookup</span>
        <span style="color: #008000;">...</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>bindingProperties<span style="color: #008000;">.</span><span style="color: #0000FF;">RelativeSourceSelf</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #008080; font-style: italic;">// bind an element to itself.</span>
        <span style="color: #008000;">...</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsNullOrEmpty</span><span style="color: #008000;">&#40;</span>bindingProperties<span style="color: #008000;">.</span><span style="color: #0000FF;">RelativeSourceAncestorType</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">// navigate up the tree to find the type</span>
        DependencyObject currentObject <span style="color: #008000;">=</span> targetElement<span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #6666cc; font-weight: bold;">int</span> currentLevel <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">while</span> <span style="color: #008000;">&#40;</span>currentLevel <span style="color: #008000;">&lt;</span> bindingProperties<span style="color: #008000;">.</span><span style="color: #0000FF;">RelativeSourceAncestorLevel</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0600FF; font-weight: bold;">do</span>
            <span style="color: #008000;">&#123;</span>
                currentObject <span style="color: #008000;">=</span> VisualTreeHelper<span style="color: #008000;">.</span><span style="color: #0000FF;">GetParent</span><span style="color: #008000;">&#40;</span>currentObject<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
            <span style="color: #0600FF; font-weight: bold;">while</span> <span style="color: #008000;">&#40;</span>currentObject<span style="color: #008000;">.</span><span style="color: #0000FF;">GetType</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span> <span style="color: #008000;">!=</span> bindingProperties<span style="color: #008000;">.</span><span style="color: #0000FF;">RelativeSourceAncestorType</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            currentLevel<span style="color: #008000;">++;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        FrameworkElement sourceElement <span style="color: #008000;">=</span> currentObject <span style="color: #0600FF; font-weight: bold;">as</span> FrameworkElement<span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #008080; font-style: italic;">// bind them</span>
        CreateRelayBinding<span style="color: #008000;">&#40;</span>targetElement, sourceElement, bindingProperties<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The code above simply navigates up the visual tree to find the n&#8217;th element of a given type. When the given type has been located, the relay binding between the two is constructed.</p>
<p>This type of binding is incredibly flexible, the following shows a number of examples:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;UserControl</span> <span style="color: #000066;">x:Class</span>=<span style="color: #ff0000;">&quot;SilverlightBinding.PageTwo&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;UserControl.Resources<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:VisibilityConverter</span> <span style="color: #000066;">x:Key</span>=<span style="color: #ff0000;">&quot;VisibilityConverter&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/UserControl.Resources<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;StackPanel</span> <span style="color: #000066;">x:Name</span>=<span style="color: #ff0000;">&quot;TheOuterStackPanel&quot;</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;White&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> 
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;StackPanel</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;theInnerStackPanel&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;400&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- bind the textbox width to its text property --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;0,5,0,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingProperties</span> <span style="color: #000066;">TargetProperty</span>=<span style="color: #ff0000;">&quot;Width&quot;</span> <span style="color: #000066;">SourceProperty</span>=<span style="color: #ff0000;">&quot;Text&quot;</span></span>
<span style="color: #009900;">                                             <span style="color: #000066;">RelativeSourceSelf</span>=<span style="color: #ff0000;">&quot;True&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>                                
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TextBox<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- bind the textbox text to this UserControls width property --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;0,5,0,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingProperties</span> <span style="color: #000066;">TargetProperty</span>=<span style="color: #ff0000;">&quot;Text&quot;</span> <span style="color: #000066;">SourceProperty</span>=<span style="color: #ff0000;">&quot;Width&quot;</span></span>
<span style="color: #009900;">                                             <span style="color: #000066;">RelativeSourceAncestorType</span>=<span style="color: #ff0000;">&quot;PageTwo&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>                                
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TextBox<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- bind the textbox text to the inner stack panels name property --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;0,5,0,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingProperties</span> <span style="color: #000066;">TargetProperty</span>=<span style="color: #ff0000;">&quot;Text&quot;</span> <span style="color: #000066;">SourceProperty</span>=<span style="color: #ff0000;">&quot;Name&quot;</span></span>
<span style="color: #009900;">                                             <span style="color: #000066;">RelativeSourceAncestorType</span>=<span style="color: #ff0000;">&quot;StackPanel&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>                                
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TextBox<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- bind the textbox text to the outer stack panels name property --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;0,5,0,0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingProperties</span> <span style="color: #000066;">TargetProperty</span>=<span style="color: #ff0000;">&quot;Text&quot;</span> <span style="color: #000066;">SourceProperty</span>=<span style="color: #ff0000;">&quot;Name&quot;</span></span>
<span style="color: #009900;">                                             <span style="color: #000066;">RelativeSourceAncestorType</span>=<span style="color: #ff0000;">&quot;StackPanel&quot;</span></span>
<span style="color: #009900;">                                             <span style="color: #000066;">RelativeSourceAncestorLevel</span>=<span style="color: #ff0000;">&quot;2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>                                
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/TextBox<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- bind a slider's value to its parent grid's height property  --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;30&quot;</span>  <span style="color: #000066;">Margin</span>=<span style="color: #ff0000;">&quot;0,5,0,0&quot;</span> <span style="color: #000066;">Background</span>=<span style="color: #ff0000;">&quot;CadetBlue&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Left&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Slider</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;400&quot;</span>  <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Left&quot;</span> <span style="color: #000066;">Minimum</span>=<span style="color: #ff0000;">&quot;10&quot;</span> <span style="color: #000066;">Maximum</span>=<span style="color: #ff0000;">&quot;40&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingProperties</span> <span style="color: #000066;">TargetProperty</span>=<span style="color: #ff0000;">&quot;Value&quot;</span> <span style="color: #000066;">SourceProperty</span>=<span style="color: #ff0000;">&quot;Height&quot;</span></span>
<span style="color: #009900;">                                             <span style="color: #000066;">RelativeSourceAncestorType</span>=<span style="color: #ff0000;">&quot;Grid&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Slider<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/StackPanel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>     
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/StackPanel<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/UserControl<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>You can see in the above XAML, examples of relative-source self and find ancestor bindings with a variety of types and ancestor-levels. And here it is in action:</p>
<div id="slPluginHost"> <object id="SilverlightPlugin" width="400" height="200" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/02/silverlightbinding2.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<p>If you type in a new value in the top text box its width will change, or move the slider to see the height of its parent grid changing. And all without any code-behind of course!</p>
<p>Many of these effects shown above could be performed via element-name bindings. However, you are not always the creator, or template provider for all the visual elements rendered to screen. One common example is that of the ItemsControl, the ListBox being an example of this type of control. Here you supply a DataTemplate, with your visual elements being rendered inside a ListBoxItem container. Therefore, there is no way to bind to the ListBoxItem via an element name or otherwise. However, you can reach the ListBoxItem by navigating up the tree using a relative-source binding as show below:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ListBox</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;grid&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Left&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ListBox.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;180&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Text</span>=<span style="color: #ff0000;">&quot;{Binding Forename}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Ellipse</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;10&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;10&quot;</span> <span style="color: #000066;">Fill</span>=<span style="color: #ff0000;">&quot;Red&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Right&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;local:BindingProperties</span> <span style="color: #000066;">TargetProperty</span>=<span style="color: #ff0000;">&quot;Visibility&quot;</span> <span style="color: #000066;">SourceProperty</span>=<span style="color: #ff0000;">&quot;IsSelected&quot;</span></span>
<span style="color: #009900;">                                                 <span style="color: #000066;">Converter</span>=<span style="color: #ff0000;">&quot;{StaticResource VisibilityConverter}&quot;</span></span>
<span style="color: #009900;">                                                 <span style="color: #000066;">RelativeSourceAncestorType</span>=<span style="color: #ff0000;">&quot;ListBoxItem&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/local:BindingHelper.Binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Ellipse<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/DataTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ListBox.ItemTemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ListBox<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>In the above example we have a DataTemplate which contains an ellipse. As the ListBox generates each &#8216;row&#8217;, it creates a ListBoxItem and populates it with the visual elements from our data template. When our ellipse is created, and loaded, the attached behaviour fires, navigating up the visual tree to find the first ListBoxItem it encounters. When it finds it, it creates a single instance of our relay object, binding both the ListBoxItem.IsSelected and Ellipse.Visibilty (via a suitable value converter) together via the relay object.</p>
<p>And here it is in action (click an item to see the ellipse) &#8230;</p>
<div id="slPluginHost"> <object id="SilverlightPlugin" width="400" height="150" data="data:application/x-silverlight," type="application/x-silverlight-2" ><param name="source" value="http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/02/silverlightbinding1.xap"/><a href="http://go.microsoft.com/fwlink/?LinkID=124807"  style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/></a></object></div>
<p>You can download a visual studio project with all the sourcecode: <a href='http://www.scottlogic.co.uk/blog/colin/wp-content/uploads/2009/02/silverlightrelativesourcebinding.zip'>silverlightrelativesourcebinding.zip</a>.</p>
<p>Enjoy, Colin E.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scottlogic.co.uk/blog/colin/2009/02/relativesource-binding-in-silverlight/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
	</channel>
</rss>

