<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Lucas-Magder/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/c4f.Lucas-Magder/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/c4f.Lucas-Magder/Posts</link>
    <language>en</language>
    <pubDate>Wed, 19 Jun 2013 20:19:08 GMT</pubDate>
    <lastBuildDate>Wed, 19 Jun 2013 20:19:08 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>5</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Building a WPF Sudoku Game: Part 5 - The AI Battle: Loading and Comparing AI Plug-ins</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">Building Sudoku using Windows Presentation Foundation and XAML, Microsoft's new declarative programming language. This is the 5th article from a series of 5 articles and focusses on loading and comparing AI Plug-ins.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Lucas Magder</div>
<div class="entry_company"><a></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><strong>Software: </strong><span><a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/">Visual C# 2005 Express Edition</a>&nbsp;<a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&amp;displaylang=en">.NET
 Framework&nbsp;3.0 Runtime Components</a> <a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;displaylang=en">
Windows Vista RTM SDK</a> <a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=f54f5537-cc86-4bf5-ae44-f5a1e805680d&amp;DisplayLang=en">
Visual Studio Extensions for the .NET Framework 3.0 November 2006 CTP</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178235/262086_SudokuFX5.zip">Download</a> (note: Tasos Valsamidis has an updated version that supports
<a class="" href="http://channel9.msdn.com/ShowPost.aspx?PostID=282120">Expression Blend here</a>)</div>
</td>
</tr>
</tbody>
</table>
</span>
<p><span><strong>Note</strong>: This article has been updated to work and compile with the RTM version of the Windows SDK.</span>&nbsp;</p>
<p>Welcome to the fifth and final part of my Windows Presentation Foundation tutorial! In this tutorial we'll be wrapping up our Sudoku game by adding support for comparing multiple plug-ins, multiple threads, new notification messages, and a cool databound
 graph control. First, let's take a look at the new interface we are trying to build:
</p>
<p><img height="133" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178235/clip_image002.jpg" width="576">
</p>
<p>On the left, there is a list of all the installed plug-ins, in the middle, our graphing control, and on the right the details for the current plug-in. To get this working we first need a way to enumerate all the plug-ins available to the app. The simplest
 way of doing this is to dump all the .dll files into a directory, which I've called “Solvers”. It's pretty simple to get a list of the assemblies in the folder, using the directory class:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">string</span>[] plugins = Directory.GetFiles(<span class="str">&quot;Solvers\\&quot;, &quot;</span>*.dll&quot;);<br><span class="kwrd">foreach</span> (<span class="kwrd">string</span> p <span class="kwrd">in</span> plugins)<br>{<br>    LoadSolvers(p);<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>I've also added a new field in the Window1 class to hold the list of loaded plug-ins, which eventually ends up as the ItemsSource for the listbox:
</p>
<p>&nbsp;</p>
<pre class="csharpcode">ObservableCollection&lt;ISudokuSolver&gt; Solvers = <br>    <span class="kwrd">new</span> ObservableCollection&lt;ISudokuSolver&gt;();<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>We also need some other groundwork code to accept the new plug-in folder. First, we need to define that our application can load assemblies from a folder other than its base (where the .exe is) and the system folders. We do this by defining an app.config.
 Select the SudokuFX project, right click and select “Add new item…” then “Application Configuration File”. This file needs to be modified to specify the subdirectory as a valid assembly location:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;?</span><span class="html">xml</span> <span class="attr">version</span><span class="kwrd">=&quot;1.0&quot;</span> <span class="attr">encoding</span><span class="kwrd">=&quot;utf-8&quot;</span> ?<span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">configuration</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">runtime</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">assemblyBinding</span> <span class="attr">xmlns</span><span class="kwrd">=&quot;urn:schemas-microsoft-com:asm.v1&quot;</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">probing</span> <span class="attr">privatePath</span><span class="kwrd">=&quot;Solvers&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">assemblyBinding</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">runtime</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">configuration</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>On top of that, we also need to alter our new app domain, in a similar fashion:
</p>
<p>&nbsp;</p>
<pre class="csharpcode">AppDomainSetup ads = <span class="kwrd">new</span> AppDomainSetup();<br>ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;<br>ads.PrivateBinPath = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(path));<br>PermissionSet ps = <span class="kwrd">new</span> PermissionSet(<span class="kwrd">null</span>);<br>ps.AddPermission(<span class="kwrd">new</span> SecurityPermission(SecurityPermissionFlag.Execution));<br>SolverDomain = AppDomain.CreateDomain(<span class="str">&quot;New AD&quot;</span>, <span class="kwrd">null</span>, ads, ps);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Then we need to populate our list with the proxy object we create: </p>
<p>&nbsp;</p>
<pre class="csharpcode">Type[] ts = asm.GetTypes();<br><span class="kwrd">foreach</span> (Type t <span class="kwrd">in</span> ts)<br>{<br>    <span class="kwrd">if</span> (Array.IndexOf(t.GetInterfaces(), <span class="kwrd">typeof</span>(ISudokuSolver)) != -1)<br>    {<br>        Type container = <span class="kwrd">typeof</span>(SudokuSolverContainer);<br>        SudokuSolverContainer ssc = SolverDomain.CreateInstanceAndUnwrap(<br>            container.Assembly.FullName, container.FullName)<br>            <span class="kwrd">as</span> SudokuSolverContainer;<br>        ssc.Init(t);<br>        Solvers.Add(ssc);<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Finally, a simple datatemplate needs to be added to the listbox to display the Name property of the object, but you should be a pro at that by now. I also added a custom template to give the list items checkboxes, but that's purely cosmetic and isn't strictly
 required. Next, we can bind the right panel's datacontext to the selected item in the left listbox, this way as the selection changes the info will update:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">StackPanel</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;InfoPanel&quot;</span> <br>      <span class="attr">DataContext</span><span class="kwrd">=&quot;{Binding ElementName=SolverList, Path=SelectedItem}&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Foreground</span><span class="kwrd">=&quot;Black&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot;Solver Info:&quot;</span> <span class="attr">FontWeight</span><span class="kwrd">=&quot;Bold&quot;</span> <span class="attr">FontSize</span><span class="kwrd">=&quot;12&quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">FontSize</span><span class="kwrd">=&quot;8&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot; &quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Foreground</span><span class="kwrd">=&quot;Black&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot;{Binding Path=Name}&quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Foreground</span><span class="kwrd">=&quot;Black&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot;{Binding Path=Author}&quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">FontSize</span><span class="kwrd">=&quot;8&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot; &quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Foreground</span><span class="kwrd">=&quot;Black&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot;{Binding Path=Description}&quot;</span> <br>      <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Stretch&quot;</span> <span class="attr">TextWrapping</span><span class="kwrd">=&quot;WrapWithOverflow&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now that that's working, lets start building the graph control. Add a new user control to the project, but this time alter it to derive from ListBox. Wait? That control's just a listbox? Yup, and not only that, you can throw almost any type of object in
 it. How does it know the height of the bars then? The height of each bar is relative to the other bars since the height of the control itself is finite. The answer is attached properties. Using attached properties you can dynamically add new properties to
 an object at runtime, the only requirement is that the object derives from DependencyObject, which in WPF means almost any object will work. In fact you've already used attached properties, DockPanel.Dock is an example of one. Each control in a DockPanel needs
 to remember where it's docked but adding a property to each class would be redundant because being in a dockpanel is a special case. This way, we can use a property of DockPanel, but store a value on each object. Defining an attached property is very similar
 to declaring a dependency property: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DependencyProperty BarHeightProperty = <br>    DependencyProperty.RegisterAttached(<span class="str">&quot;BarHeight&quot;</span>, <span class="kwrd">typeof</span>(<span class="kwrd">double</span>), <br>    <span class="kwrd">typeof</span>(DependencyObject), <span class="kwrd">new</span> PropertyMetadata(0.0));<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>but, instead of defining a property, we need to define static access methods: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">double</span> GetBarHeight(DependencyObject d)<br>{<br>    <span class="kwrd">return</span> (<span class="kwrd">double</span>)d.GetValue(BarHeightProperty);<br>}<br><br><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> SetBarHeight(DependencyObject d, <span class="kwrd">double</span> h)<br>{<br>    d.SetValue(BarHeightProperty, h);<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>Now, we need to define the class we're going to store in the list, this simple class just holds a reference to the solver used, how long it took to run, and whether it was successful in solving the sudoku:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> SolverResult : DependencyObject<br>{<br>    TimeSpan timeTaken;<br><br>    <span class="kwrd">public</span> TimeSpan TimeTaken<br>    {<br>        get<br>        {<br>            <span class="kwrd">return</span> timeTaken;<br>        }<br>        set<br>        {<br>            timeTaken = <span class="kwrd">value</span>;<br>        }<br>    }<br><br>    ISudokuSolver solver;<br><br>    <span class="kwrd">public</span> ISudokuSolver Solver<br>    {<br>        get<br>        {<br>            <span class="kwrd">return</span> solver;<br>        }<br>        set<br>        {<br>            solver = <span class="kwrd">value</span>;<br>        }<br>    }<br><br>    <span class="kwrd">bool</span> failed;<br><br>    <span class="kwrd">public</span> <span class="kwrd">bool</span> Failed<br>    {<br>        get<br>        {<br>            <span class="kwrd">return</span> failed;<br>        }<br>        set<br>        {<br>            failed = <span class="kwrd">value</span>;<br>        }<br>    }<br>}<br><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Next, we need to add some code to figure out the heights of the bars in the graph, essentially I just find the highest bar and assume that it fills the control vertically, and then set the properties on each item. This only needs to be done when the contents
 change so conveniently we can override the event handler: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnItemsChanged(<br>    System.Collections.Specialized.NotifyCollectionChangedEventArgs e)<br>{<br>    <span class="kwrd">base</span>.OnItemsChanged(e);<br>    <span class="kwrd">long</span> maxVal = 0;<br>    <span class="kwrd">foreach</span> (SolverResult s <span class="kwrd">in</span> Items)<br>    {<br>        <span class="kwrd">if</span> (!s.Failed &amp;&amp; s.TimeTaken.Ticks &gt; maxVal) maxVal = s.TimeTaken.Ticks;<br>    }<br><br>    <span class="kwrd">foreach</span> (SolverResult s <span class="kwrd">in</span> Items)<br>    {<br>        <span class="kwrd">if</span> (s.Failed)<br>        {<br>            GraphControl.SetBarHeight(s, ActualHeight - 25);<br>        }<br>        <span class="kwrd">else</span>
        {
            <span class="kwrd">double</span> h = (<span class="kwrd">double</span>)s.TimeTaken.Ticks / <br>                (<span class="kwrd">double</span>)maxVal * (ActualHeight - 25);<br>            <span class="kwrd">if</span> (h &gt; 10)<br>            {<br>                GraphControl.SetBarHeight(s, h);<br>            }<br>            <span class="kwrd">else</span>
            {
                GraphControl.SetBarHeight(s, 10);
            }
        }
        GraphControl.SetIndex(s, Items.IndexOf(s));
    }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The index property is another attached property I've defined; you'll see where it's used in just a bit. For now though, it's all about the data templates:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">DataTemplate</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;BarTemplate&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Bar&quot;</span> <span class="attr">Margin</span><span class="kwrd">=&quot;3,3,3,0&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;50&quot;</span> <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Bottom&quot;</span>
    <span class="attr">Height</span><span class="kwrd">=&quot;{Binding Path=BarHeight}&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;Red&quot;</span> <span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;BarText&quot;</span> <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Center&quot;</span>
        <span class="attr">Foreground</span><span class="kwrd">=&quot;White&quot;</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <br>        <span class="attr">Text</span><span class="kwrd">=&quot;{Binding Path=TimeTaken}&quot;</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">TextBlock.LayoutTransform</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">RotateTransform</span> <span class="attr">Angle</span><span class="kwrd">=&quot;90&quot;</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">TextBlock.LayoutTransform</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">DataTemplate.Triggers</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">DataTrigger</span> <span class="attr">Binding</span><span class="kwrd">=&quot;{Binding Path=Failed}&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;True&quot;</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span><span class="kwrd">=&quot;Bar&quot;</span> <span class="attr">Property</span><span class="kwrd">=&quot;Opacity&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;0.5&quot;</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span><span class="kwrd">=&quot;BarText&quot;</span> <span class="attr">Property</span><span class="kwrd">=&quot;Text&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;Failed&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">DataTrigger</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">DataTemplate.Triggers</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">DataTemplate</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Here we make containers to hold the bars and set their heights based on our new property. I also added some triggers to ghost out the bar if the solver failed to solve the sudoku grid.
</p>
<p><img height="133" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178235/clip_image004.jpg" width="576">
</p>
<p>As you can see, it works but yuck, what is this, 16-color Windows 3.1? We've got to make this look a little better. First, let's throw in some kind of color scheme. Ok, but how do the colors map to the bars? Well, if you've read my previous article, you've
 probably already guessed: converters. We can link together our index value with our color scheme using a converter:
</p>
<p>&nbsp;</p>
<pre class="csharpcode">[ValueConversion(<span class="kwrd">typeof</span>(<span class="kwrd">int</span>), <span class="kwrd">typeof</span>(Color))]<br><span class="kwrd">public</span> <span class="kwrd">class</span> BarColorConverter : IValueConverter<br>{<br>    <span class="kwrd">static</span> Color[] BarColors = {<br>        Colors.SteelBlue,<br>        Colors.Green,<br>        Colors.Firebrick,<br>        Colors.DarkSlateGray,<br>        Colors.Orange,<br>        Colors.Khaki<br>        };<br><br>    <span class="kwrd">public</span> <span class="kwrd">object</span> Convert(<span class="kwrd">object</span> <span class="kwrd">value</span>, Type targetType, <span class="kwrd">object</span> parameter,<br><br>    CultureInfo culture)<br>    {<br>        <span class="kwrd">int</span> v = (<span class="kwrd">int</span>)<span class="kwrd">value</span>;<br>        <span class="kwrd">return</span> BarColors[v % BarColors.Length];<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">object</span> ConvertBack(<span class="kwrd">object</span> <span class="kwrd">value</span>, Type targetType, <span class="kwrd">object</span> parameter,<br><br>    CultureInfo culture)<br>    {<br>        Color v = (Color)<span class="kwrd">value</span>;<br>        <span class="kwrd">return</span> Array.IndexOf&lt;Color&gt;(BarColors, v);<br>    }<br>}<br><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now, if we want to get fancy, it's also possible to define this converter so that when you use it from XAML you can defined the color scheme similar to a gradient, but this way works too. After defining an instance of our converter in the resources section
 of our control, we can use it like this: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Grid.Background</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">SolidColorBrush</span>
    <span class="attr">Color</span><span class="kwrd">=&quot;{Binding Path=Index, Converter={StaticResource BarColorConverter}}&quot;</span><span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Grid.Background</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><img height="134" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178235/clip_image006.jpg" width="575"><br>
That's better, about a Windows Forms level of look and feel, but this isn't Windows Forms. We need to give the bars a more complex look based on their base color. Using converters we can setup a binding that will do this for us. First, let's define a new converter:
</p>
<p>&nbsp;</p>
<pre class="csharpcode">[ValueConversion(<span class="kwrd">typeof</span>(Color), <span class="kwrd">typeof</span>(Color))]<br><span class="kwrd">public</span> <span class="kwrd">class</span> ColorLightnessConverter : IValueConverter<br>{<br>    <span class="kwrd">public</span> <span class="kwrd">object</span> Convert(<span class="kwrd">object</span> <span class="kwrd">value</span>, Type targetType, <br>        <span class="kwrd">object</span> parameter, CultureInfo culture)<br>    {<br>        <span class="kwrd">if</span> (<span class="kwrd">value</span> == <span class="kwrd">null</span>) <span class="kwrd">return</span> <span class="kwrd">null</span>;<br>        <span class="kwrd">int</span> param = <span class="kwrd">int</span>.Parse(parameter.ToString());<br>        Color src = (Color)<span class="kwrd">value</span>;<br>        Color ret = <span class="kwrd">new</span> Color();<br>        ret.A = src.A;<br>        ret.R = (<span class="kwrd">byte</span>)Math.Max(Math.Min(src.R &#43; param, 255), 0);<br>        ret.G = (<span class="kwrd">byte</span>)Math.Max(Math.Min(src.G &#43; param, 255), 0);<br>        ret.B = (<span class="kwrd">byte</span>)Math.Max(Math.Min(src.B &#43; param, 255), 0);<br>        <span class="kwrd">return</span> ret;<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">object</span> ConvertBack(<span class="kwrd">object</span> <span class="kwrd">value</span>, Type targetType, <br>        <span class="kwrd">object</span> parameter, CultureInfo culture)<br>    {<br>        <span class="kwrd">if</span> (<span class="kwrd">value</span> == <span class="kwrd">null</span>) <span class="kwrd">return</span> <span class="kwrd">null</span>;<br>        <span class="kwrd">int</span> param = <span class="kwrd">int</span>.Parse(parameter.ToString());<br>        Color src = (Color)<span class="kwrd">value</span>;<br>        Color ret = <span class="kwrd">new</span> Color();<br>        ret.A = src.A;<br>        ret.R = (<span class="kwrd">byte</span>)Math.Max(Math.Min(src.R - param, 255), 0);<br>        ret.G = (<span class="kwrd">byte</span>)Math.Max(Math.Min(src.G - param, 255), 0);<br>        ret.B = (<span class="kwrd">byte</span>)Math.Max(Math.Min(src.B - param, 255), 0);<br>        <span class="kwrd">return</span> ret;<br>    }<br>}<br><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This converter allows us to lighten or darken a databound color as it passes through the binding. It also makes use of the parameter functionality on converters to allow us to specify how much we alter the color from XAML. After we've added the converter
 to our resource section can use it. First, we need to move output from out other converter, the base color of the bar into somewhere we can easily access; the Tag property is a great place to store random stuff like this so let's use it:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="attr">Tag</span><span class="kwrd">=&quot;{Binding Path=Index, Converter={StaticResource BarColorConverter}}&quot;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now we can reference the tag and pass it through our second converter: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Rectangle</span> <span class="attr">RadiusX</span><span class="kwrd">=&quot;3&quot;</span> <span class="attr">RadiusY</span><span class="kwrd">=&quot;3&quot;</span> <span class="attr">StrokeThickness</span><span class="kwrd">=&quot;2&quot;</span> <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Stretch&quot;</span>
      <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Stretch&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Rectangle.Stroke</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">SolidColorBrush</span> <span class="attr">Color</span><span class="kwrd">=&quot;{Binding ElementName=Bar, Path=Tag, <br>      Converter={StaticResource ColorLightnessConverter}, ConverterParameter=-64}&quot;</span><span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Rectangle.Stroke</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Rectangle.Fill</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush</span> <span class="attr">SpreadMethod</span><span class="kwrd">=&quot;Repeat&quot;</span> <span class="attr">MappingMode</span><span class="kwrd">=&quot;Absolute&quot;</span> <br>          <span class="attr">StartPoint</span><span class="kwrd">=&quot;0,0&quot;</span> <span class="attr">EndPoint</span><span class="kwrd">=&quot;1,1&quot;</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush.Transform</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">ScaleTransform</span> <span class="attr">ScaleX</span><span class="kwrd">=&quot;20&quot;</span> <span class="attr">ScaleY</span><span class="kwrd">=&quot;20&quot;</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush.Transform</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush.GradientStops</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <br>            <span class="attr">Color</span><span class="kwrd">=&quot;{Binding ElementName=Bar, Path=Tag, <br>            Converter={StaticResource ColorLightnessConverter}, <br>            ConverterParameter=-32}&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <br>          <span class="attr">Color</span><span class="kwrd">=&quot;{Binding ElementName=Bar, Path=Tag, <br>            Converter={StaticResource ColorLightnessConverter}, <br>            ConverterParameter=-32}&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0.499&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span><span class="kwrd">=&quot;{Binding ElementName=Bar, Path=Tag}&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0.501&quot;</span><span class="kwrd">/&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span><span class="kwrd">=&quot;{Binding ElementName=Bar, Path=Tag}&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush.GradientStops</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Rectangle.Fill</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Rectangle</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Here, I've created a gradient and border outline based on the base color by darkening it with our converter. This gradient adds the striped appearance to the graph bars so the MappingMode property is important, since it specifies that our gradient is sized
 relative to the screen not the area it is filling. This prevents the stripes from stretching in an ugly way as the bars change height. Once you do this though, the gradient now becomes 1 point long, hence the scale to 20 points. After adding some more glassy
 overlays you can see that the final effect is much better, pretty cool for doing everything in databinding eh?
</p>
<p><img height="133" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178235/clip_image007.jpg" width="576">
</p>
<p>Finally, we can force a special style onto our ListBoxItems, the class that wraps each item in list to turn it into a control:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">ListBox.ItemContainerStyle</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">TargetType</span><span class="kwrd">=&quot;{x:Type ListBoxItem}&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;VerticalContentAlignment&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;Bottom&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Style.Triggers</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Trigger</span> <span class="attr">Property</span><span class="kwrd">=&quot;IsVisible&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;true&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Trigger.EnterActions</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span>
              <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">From</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">To</span> <span class="kwrd">=&quot;1&quot;</span>
                <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;Opacity&quot;</span> <span class="attr">Duration</span><span class="kwrd">=&quot;0:0:0.5&quot;</span><span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">Trigger.EnterActions</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">Trigger</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Style.Triggers</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">ListBox.ItemContainerStyle</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This way bars hang at the bottom like they are supposed to and as an added bonus, we can throw in an animation to make the bars fade in as they appear.
</p>
<p>Now that the bar graph works, how do we get it to display useful info? Well the most obvious way it to write a method like this:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">void</span> BenchmarkClick(<span class="kwrd">object</span> sender, RoutedEventArgs e)<br>{<br>    SolverResult s = <span class="kwrd">new</span> SolverResult();<br>    s.Solver = SolverList.SelectedItem <span class="kwrd">as</span> ISudokuSolver;<br>    <span class="kwrd">int</span>?[,] arr = Board.GameBoard.ToArray();<br>    BenchButton.IsEnabled = <span class="kwrd">false</span>;<br>    <span class="kwrd">long</span> tick = DateTime.Now.Ticks;<br>    s.Failed = !s.Solver.Solve(<span class="kwrd">ref</span> arr);<br>    s.TimeTaken = TimeSpan.FromTicks((DateTime.Now.Ticks - tick));<br>    Graph.Items.Add(s);<br>    BenchButton.IsEnabled = <span class="kwrd">true</span>;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The works but there is a problem: solving a grid could take more than a few seconds and this method blocks, causing the UI to freeze until it returns. This is a bad thing. Your users will hate you and your more technical users will point and laugh (you don't
 believe me, but I've seen it). How can we fix this? The answer is threads! Unfortunately, it's not that easy, there are significant caveats when writing multithreaded code (which are way beyond the scope of this article). Essentially, for our purposes, the
 problem lies in that you can't interact with the UI objects from another thread! This makes it difficult to say, re-enable the button or update the graph. Luckily, the .NET Framework comes to the rescue with the BackgroundWorker class, although this doesn't
 completely solve our problem it provides an event which is fired when out background task (our other thread) is complete. Since this event handler runs in our UI thread we can easily interact with those objects. To make things a little more user-friendly I've
 also added a new hidden panel over the solver information controls that displays a “please wait” message, which we can show while our process is running. The new code looks like this:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"></pre>
<pre class="csharpcode">BackgroundWorker solverWorker;<br><br><span class="kwrd">void</span> BenchmarkClick(<span class="kwrd">object</span> sender, RoutedEventArgs e)<br>{<br>    SolverResult s = <span class="kwrd">new</span> SolverResult();<br>    s.Solver = SolverList.SelectedItem <span class="kwrd">as</span> ISudokuSolver;<br>    <span class="kwrd">int</span>?[,] arr = Board.GameBoard.ToArray();<br>    BenchButton.IsEnabled = <span class="kwrd">false</span>;<br>    InfoPanel.Visibility = Visibility.Hidden;<br>    WaitPanel.Visibility = Visibility.Visible;<br>    <span class="kwrd">long</span> tick = DateTime.Now.Ticks;<br>    solverWorker = <span class="kwrd">new</span> BackgroundWorker();<br>    solverWorker.DoWork &#43;= <span class="kwrd">new</span>
        DoWorkEventHandler(<span class="kwrd">delegate</span>(<span class="kwrd">object</span> dwsender, DoWorkEventArgs dwe)<br>        {<br>            s.Failed = !s.Solver.Solve(<span class="kwrd">ref</span> arr);<br>            s.TimeTaken = TimeSpan.FromTicks((DateTime.Now.Ticks - tick));<br>        });<br>    solverWorker.RunWorkerCompleted &#43;= <span class="kwrd">new</span> RunWorkerCompletedEventHandler(<br>        <span class="kwrd">delegate</span>(<span class="kwrd">object</span> rwcsender, RunWorkerCompletedEventArgs rwce)<br>        {<br>            Graph.Items.Add(s);<br>            InfoPanel.Visibility = Visibility.Visible;<br>            WaitPanel.Visibility = Visibility.Hidden;<br>            BenchButton.IsEnabled = <span class="kwrd">true</span>;<br>        });<br>    solverWorker.RunWorkerAsync();<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>If you're confused, the delegate(object dwsender, DoWorkEventArgs dwe){…} syntax defines an anonymous delegate, a new .NET 2.0 feature. Anonymous delegates are single-use nameless methods. This way we can define our event handlers on the fly without cluttering
 up our class with extra methods that aren't meant to be called. Also, since anonymous delegates have access to the scope in which they are defined, we can avoid creating lots of temporary variables to hold the objects local to our BenchmarkClick method. On
 top of that, the program execution conceptually flows in a linear fashion if you ignore the definitions around the delegates, so anonymous delegates also help the function of the method remain clear. In action, this looks like this, and it allows you keep
 playing sudoku as the solver runs: (It does run slow on my machine though, because much CPU time is spent on the absolutely critical pulsating background featureJ)
</p>
<p><img height="133" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178235/clip_image009.jpg" width="575">
</p>
<p>I've also added similar threading code the board generation routines and the “I give up” button and a little “x” button to the graph that allows you the clear the current results. Finally, as a finishing touch let's update the extremely dated-looking message
 box: </p>
<p><img height="504" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178235/clip_image011.jpg" width="576"><br>
I don't know about you, but this dinky non-xp-themed message box doesn't exactly scream “awesome!” at me. To at least partially fix this, I've added a new grid the covers the entire window and is placed in front. By default it's completely invisible, by setting
 to opacity to 0, and doesn't block input events, by setting the IsHitTestVisible property to false. Then when it's enabled, it springs into action and fades in, tinting the window black and disabling its controls:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Grid</span> <span class="attr">IsHitTestVisible</span><span class="kwrd">=&quot;False&quot;</span> <span class="attr">IsEnabled</span><span class="kwrd">=&quot;False&quot;</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;MessageLayer&quot;</span> <br>    <span class="attr">Opacity</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Stretch&quot;</span> <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Stretch&quot;</span> <br>    <span class="attr">Background</span><span class="kwrd">=&quot;#B0000000&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Grid.Style</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Style</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Style.Triggers</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">Trigger</span> <span class="attr">Property</span><span class="kwrd">=&quot;Grid.IsEnabled&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;True&quot;</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">Trigger.EnterActions</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span>
              <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">To</span><span class="kwrd">=&quot;1&quot;</span> <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;Opacity&quot;</span>
                    <span class="attr">Duration</span><span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">/&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">BooleanAnimationUsingKeyFrames</span>
                    <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;IsHitTestVisible&quot;</span>
                    <span class="attr">BeginTime</span><span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">&gt;</span>
                  <span class="kwrd">&lt;</span><span class="html">DiscreteBooleanKeyFrame</span> <span class="attr">KeyTime</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;True&quot;</span><span class="kwrd">/&gt;</span>
                <span class="kwrd">&lt;/</span><span class="html">BooleanAnimationUsingKeyFrames</span><span class="kwrd">&gt;</span>
              <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span><span class="html">Trigger.EnterActions</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">Trigger.ExitActions</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span>
              <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">To</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;Opacity&quot;</span>
                  <span class="attr">Duration</span><span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">/&gt;</span>
                <span class="kwrd">&lt;</span><span class="html">BooleanAnimationUsingKeyFrames</span>
                    <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;IsHitTestVisible&quot;</span>
                    <span class="attr">BeginTime</span><span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">&gt;</span>
                  <span class="kwrd">&lt;</span><span class="html">DiscreteBooleanKeyFrame</span> <span class="attr">KeyTime</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;False&quot;</span><span class="kwrd">/&gt;</span>
                <span class="kwrd">&lt;/</span><span class="html">BooleanAnimationUsingKeyFrames</span><span class="kwrd">&gt;</span>
              <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span><span class="html">Trigger.ExitActions</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">Trigger</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">Style.Triggers</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Grid.Style</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Grid</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Then, in the grid, I placed one of the custom styled expanders defined in our resources section and filled it with a textblock, button and glassy icon. Also I added another hidden expander, which contains a “please wait” message. After defining some new
 methods to make using these controls easy: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">void</span> ShowMessage(<span class="kwrd">string</span> m)<br>{<br>    MessageText.Text = m;<br>    MessageExpander.Visibility = Visibility.Visible;<br>    WaitExpander.Visibility = Visibility.Hidden;<br>    MessageLayer.IsEnabled = <span class="kwrd">true</span>;<br>}<br><br><span class="kwrd">void</span> ShowWait()<br>{<br>    MessageExpander.Visibility = Visibility.Hidden;<br>    WaitExpander.Visibility = Visibility.Visible;<br>    MessageLayer.IsEnabled = <span class="kwrd">true</span>;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>and an event handler for the close button on the expander </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">void</span> MessageClosed(<span class="kwrd">object</span> sender, RoutedEventArgs e)<br>{<br>    MessageLayer.IsEnabled = <span class="kwrd">false</span>;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>We just need to replace MessageBox.Show with ShowMessage to show a fake window:
</p>
<p><img height="503" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178235/clip_image013.jpg" width="575"><br>
Hey, as I said before, at least it's more colorful. </p>
<p>At this point, with the work we've done so far and a few extra lines of code you can find in the download, we have a fully functional Sudoku game. I hope you've enjoyed this tutorial series and have some great ideas about a cool WPF app you can build! We've
 only covered the basics and this is just the tip of the iceberg when it comes to XAML and WinFX. There's lots of cool stuff left like 3D graphics, video and multimedia, databinding to XML, loading XAML at runtime, and browser-based applications to name a few
 and that's just WPF! If you're itching to code more and want to build on the app, some missing things you might want to work on are:
</p>
<ul>
<li>More plug-ins! It supports plug-ins for a reason! Write a better solver that doesn't take forever to run
</li><li>Better message windows that you can actually move around and the ability to dock and move the UI containers
</li><li>Separate the styles and logic more cleanly and implement skins or color schemes
</li><li>Add sound effects or more animations </li><li>Re-skin ALL the controls for a cooler look and feel </li><li>Add an internet highscores feature or leaderboards </li></ul>
<p>Remember, if anybody asks, you're not writing a game, you're “updating your workplace skills to match evolving technology”</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Lucas-Magder/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:11d482e6b8cb48ef91629e7600d7aba4">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-5-The-AI-Battle-Loading-and-Comparing-AI-Plug-ins</comments>
      <itunes:summary>



&amp;nbsp;
Building Sudoku using Windows Presentation Foundation and XAML, Microsoft&#39;s new declarative programming language. This is the 5th article from a series of 5 articles and focusses on loading and comparing AI Plug-ins.



Lucas Magder


Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual C# 2005 Express Edition&amp;nbsp;.NET
 Framework&amp;nbsp;3.0 Runtime Components 
Windows Vista RTM SDK 
Visual Studio Extensions for the .NET Framework 3.0 November 2006 CTP
Hardware: 
Download: Download (note: Tasos Valsamidis has an updated version that supports
Expression Blend here)





Note: This article has been updated to work and compile with the RTM version of the Windows SDK.&amp;nbsp; 
Welcome to the fifth and final part of my Windows Presentation Foundation tutorial! In this tutorial we&#39;ll be wrapping up our Sudoku game by adding support for comparing multiple plug-ins, multiple threads, new notification messages, and a cool databound
 graph control. First, let&#39;s take a look at the new interface we are trying to build:
 

 
On the left, there is a list of all the installed plug-ins, in the middle, our graphing control, and on the right the details for the current plug-in. To get this working we first need a way to enumerate all the plug-ins available to the app. The simplest
 way of doing this is to dump all the .dll files into a directory, which I&#39;ve called “Solvers”. It&#39;s pretty simple to get a list of the assemblies in the folder, using the directory class:
 
&amp;nbsp; 
string[] plugins = Directory.GetFiles(&amp;quot;Solvers\\&amp;quot;, &amp;quot;*.dll&amp;quot;);foreach (string p in plugins){    LoadSolvers(p);}



I&#39;ve also added a new field in the Window1 class to hold the list of loaded plug-ins, which eventually ends up as the ItemsSource for the listbox:
 
&amp;nbsp; 
ObservableCollection&amp;lt;ISudokuSolver&amp;gt; Solvers =     new ObservableCollection&amp;lt;ISudokuSolver&amp;gt;();



We also need some other groundwork code to accept the new plug-in folder. First, we need to d</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-5-The-AI-Battle-Loading-and-Comparing-AI-Plug-ins</link>
      <pubDate>Thu, 30 Nov 2006 11:34:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-5-The-AI-Battle-Loading-and-Comparing-AI-Plug-ins</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1178235_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1178235_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Lucas Magder</dc:creator>
      <itunes:author>Lucas Magder</itunes:author>
      <slash:comments>9</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-5-The-AI-Battle-Loading-and-Comparing-AI-Plug-ins/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Puzzle</category>
    </item>
  <item>
      <title>Building a WPF Sudoku Game: Part 4 - Building a Least Privilege Plug-in System and Even More Custom Controls</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">Building Sudoku using Windows Presentation Foundation and XAML, Microsoft's new declarative programming language. This is the 4th article from a series of 5 articles and focusses on building a least privilege plug-in
 system and some more custom controls.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Lucas Magder</div>
<div class="entry_company"><a></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><strong>Software: </strong><span><a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/">Visual C# 2005 Express Edition</a>&nbsp;<a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&amp;displaylang=en">.NET
 Framework&nbsp;3.0 Runtime Components</a> <a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;displaylang=en">
Windows Vista RTM SDK</a> <a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=f54f5537-cc86-4bf5-ae44-f5a1e805680d&amp;DisplayLang=en">
Visual Studio Extensions for the .NET Framework 3.0 November 2006 CTP</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178206/262083_SudokuFX4.zip">Download</a> (note: Tasos Valsamidis has an updated version that supports
<a class="" href="http://channel9.msdn.com/ShowPost.aspx?PostID=282120">Expression Blend here</a>)</div>
</td>
</tr>
</tbody>
</table>
</span>
<p><span><strong>Note</strong>: This article has been updated to work and compile with the RTM version of the Windows SDK.</span></p>
<p>Welcome to the fourth part of my Windows Presentation Foundation tutorial! In this tutorial we'll be building a plug-in system for sudoku-solving algorithms, delving deeper into custom controls, including deriving from exiting controls and implementing custom
 properties. Also, we'll complete more of the UI and game logic to start turning this pile of unrelated code into a game! First, let's look at building a plug-in system: There are essentially two ways of providing an extensibility system in a .NET application:
</p>
<ul>
<li><b>Scripting:</b> We could provide a custom programming language that plug-in authors need to write their code in.
</li><li><b>Module Loading: </b>We could dynamically load pre-compiled modules at runtime.</li></ul>
<p><b></b></p>
<p><img height="283" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178206/clip_image0031.gif" width="480"><br>
If we take the scripting approach we need to either create our own language, which is a lot of work and honestly, who likes to reinvent the wheel? We could also use the built-in compilation functionality in the .NET Framework to compiler, say C# code as a script,
 which takes less work but doesn't allow us to create a “sandbox” language that can only perform certain actions. Plug-in modules suffer from the same issues, but they don't require us to provide a set of tools for plug-in developers since Visual Studio is
 all that's needed. With the availability of the free Visual Studio Express editions, there is really no excuse not to use precompiled modules not to mention that it's less work and therefore less chance of creating bugs or security problems…at least that's
 what I tell my boss. There's only one flaw in this method: most of the time standard applications like our Sudoku game run as so-called “full trust” applications that means they have the full permissions of the user they are running under, which in most cases,
 at least on Windows XP, is the administrator. Obviously this raises a security concern. Most likely, the user trusts the Sudoku game itself, since they knowingly installed it on their system but do they trust each individual plug-in? What if, for example,
 the program could automatically download solver plug-ins from a central web repository; does the user trust this plug-in? One way around this is to use .NET code access security (CAS). We can partition our application into a set of “application domains” You
 probably don't know it yet, but you've already used domains. When a .NET process starts a default domain is created. You can even access it from any of your “normal” code through the Current static property of the AppDomain class. We could just load more assemblies
 into the default domain but they would then run with same permissions as our application code:
</p>
<p>This is bad for two reasons: first, the plug-in can do anything the application can. For example, if the application is allowed to write to a certain registry location by the operating system, even if the plug-in can't break out of the Win32 limits it can
 still trash our game's settings, which is bad. Second, because there is no clear segregation of code, the CLR errs on the side of caution and doesn't allow us to unload the plug-in module since it's impossible to reasonably determine if any portions of it
 are still in use. If we use the second approach: </p>
<p><img height="481" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178206/clip_image0041.gif" width="480">
</p>
<p>The plug-in is sandboxed inside another domain. The only real caveat of this approach is that communication between domains requires the use of remoting, or in other words, the objects need to “self-contained” so that they can be serialized as they cross
 the boundary, but we'll get back to that later. </p>
<p>At this point you're probably saying “Application domains! .NET remoting! This isn't what I signed on for! I want to make a game!” Don't worry, most of this is automatic but it's important to understand what's going on so you can debug your code and so you
 can avoid creating security flaws. So, how do we go about actually getting this to work? First, we need to define a programming interface for plug-ins to use, to keep it simple, let's build an interface that is exported from our SudokuFX.exe assembly that
 plug-in authors are required to implement: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">namespace</span> SudokuFX<br>{<br>    <span class="kwrd">public</span> <span class="kwrd">interface</span> ISudokuSolver<br>    {<br>        <span class="kwrd">string</span> Name<br>        {<br>            get;<br>        }<br><br>        <span class="kwrd">string</span> Description<br>        {<br>            get;<br>        }<br><br>        <span class="kwrd">string</span> Author<br>        {<br>            get;<br>        }<br><br>        <span class="kwrd">bool</span> Solve(Board board);<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This would work well in the single domain approach but unfortunately it's not ideal for our situation. First, passing an instance of Board, while seemingly convenient, actually adds more complexity because of the serialization that occurs as an object crosses
 the domain boundary. This is a problem because the object contains links to event handlers and is databound to elements in the UI so it can't be easily written to self-contained stream. Also, it's generally a bad idea to expose unnecessary internal data to
 plug-in anyway. If instead of passing a Board, we say pass an ref int?[,], a simple type that exposes no implementation details can easily be serialized. Also, in order to use an object through remoting it must contain some boilerplate code, an easy way of
 adding this code is to derive from the MarshalByRef class. Ideally we also want to hide this detail from plug-in authors so it's actually better to make an abstract class like this:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">class</span> SudokuSolver : MarshalByRefObject<br>{<br>    <span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">string</span> Name<br>    {<br>        get;<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">string</span> Description<br>    {<br>        get;<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">string</span> Author<br>    {<br>        get;<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">abstract</span> <span class="kwrd">bool</span> Solve(<span class="kwrd">ref</span> <span class="kwrd">int</span>?[,] board);<br>}<br><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>That way, all plug-in classes automatically inherit the code. Wait no! STOP! It's likely I've convinced you that this is the best way of doing it, but it's not! Building something like this requires that you understand the security implications of what you're
 writing. There is a subtle flaw in what I've just described, which I fell into the trap of the first time I wrote this code: In order to directly interact with another object through an app domain, the caller must load the other assembly to process its types.
 If a hostile plug-in writer embedded malicious code in the constructor of a class that is used in a static member, this code would be run when the assembly is loaded in our main domain! Instead we should build a proxy object that is defined in our main assembly,
 which can sit in the un-trusted domain and provide a layer between our objects. This way the un-trusted assembly will not be loaded in our full trust domain:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> SudokuSolverContainer : MarshalByRefObject, ISudokuSolver<br>{<br>    ISudokuSolver solver;<br><br>    <span class="kwrd">public</span> <span class="kwrd">void</span> Init(Type t)<br>    {<br>        solver = Activator.CreateInstance(t) <span class="kwrd">as</span> ISudokuSolver;<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">string</span> Name<br>    {<br>        get { <span class="kwrd">return</span> solver.Name; }<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">string</span> Description<br>    {<br>        get { <span class="kwrd">return</span> solver.Description; }<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">string</span> Author<br>    {<br>        get { <span class="kwrd">return</span> solver.Author; }<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">bool</span> Solve(<span class="kwrd">ref</span> <span class="kwrd">int</span>?[,] board)<br>    {<br>        <span class="kwrd">return</span> solver.Solve(<span class="kwrd">ref</span> board);<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now, we can create our container object as our main assembly's “ambassador” to the least-privilege domain, then call the Init method with the type of solver we want to create. This way, calls to the plug-in are still straightforward but since the class from
 the plug-in assembly is never accessed directly from our trusted domain, there is no need to load the assembly there.
</p>
<p>Next, let's start building a plug-in we can use to test our system: </p>
<p>In Visual Studio, right-click on the SudokuFX solution and add a new class library project called “SampleSolver”. Now, in the new project, right-click on references and select “add”. In the “projects” tab select “SudokuFX”. Also, we need to add a post-build
 event to the new project to copy the dll into our folder: copy &quot;$(TargetPath)&quot; &quot;$(SolutionDir)SudokuFx\bin\Debug&quot;. Now, if we define a class that inherits from SudokuFX.SudokuSolver we can start building a plug-in:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd"></span></pre>
<pre class="csharpcode"><span class="kwrd">namespace</span> SampleSolver<br>{<br>    <span class="kwrd">public</span> <span class="kwrd">class</span> SampleSolver : SudokuFX.ISudokuSolver<br>    {<br>        <span class="kwrd">public</span> <span class="kwrd">string</span> Name<br>        {<br>            get<br>            {<br>                <span class="kwrd">return</span> <span class="str">&quot;Sample Sudoku Solver&quot;</span>;<br>            }<br>        }<br><br>        <span class="kwrd">public</span> <span class="kwrd">string</span> Description<br>        {<br>            get<br>            {<br>                <span class="kwrd">return</span> <span class="str">&quot;This is a sample algorithm that uses a combination &quot;</span> &#43;<br>                    <span class="str">&quot;of logic and guess-and-check.&quot;</span>;<br>            }<br>        }<br><br>        <span class="kwrd">public</span> <span class="kwrd">string</span> Author<br>        {<br>            get<br>            {<br>                <span class="kwrd">return</span> <span class="str">&quot;Lucas Magder&quot;</span>;<br>            }<br>        }<br><br>        <span class="kwrd">public</span> <span class="kwrd">bool</span> Solve(<span class="kwrd">ref</span> <span class="kwrd">int</span>?[,] board)<br>        {<br>            <span class="rem">//Do stuff</span><br>            <span class="kwrd">return</span> <span class="kwrd">true</span>;<br>        }<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Visual Studio will even set up the blank methods for you if you right-click on the “SudokuFX.SudokuSolver” and select “Implement Interface”. This is great if you're still not 100% on how to correctly set things up. I'll get back to how exactly my plug-in
 works in just a second but lets jump ahead and write some code to load it. </p>
<p>First, I've added a new field to the Window1 class: </p>
<p>&nbsp;</p>
<pre class="csharpcode">AppDomain PluginDomain = <span class="kwrd">null</span>;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>It's important we keep a reference to our new domain because, like any other object, it can get garbage collected and if that happens all the objects in the domain die, and that's bad. Next, I added a method to load a plug-in:
</p>
<p>&nbsp;</p>
<pre class="csharpcode">SudokuSolver LoadSolver(<span class="kwrd">string</span> path)<br>{<br>    AppDomainSetup ads = <span class="kwrd">new</span> AppDomainSetup();<br>    ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;<br>    PermissionSet ps = <span class="kwrd">new</span> PermissionSet(<span class="kwrd">null</span>);<br>    ps.AddPermission(<span class="kwrd">new</span> SecurityPermission(SecurityPermissionFlag.Execution));<br>    PluginDomain = AppDomain.CreateDomain(<span class="str">&quot;New AD&quot;</span>, <span class="kwrd">null</span>, ads, ps);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Here, we first create an AppDomainSetup, which contains the parameters for our new domain. Right now, the only field we need to worry about is the ApplicationBase, this makes sure the loader code, which runs in the new domain can locate our executable to
 resolve the references our plug-in contains to it. Next, we create a new <u>empty</u> permission set and add only one permission to it: execution. This means the code in that domain can run but do nothing else, which means no file access, no registry, no network
 access, etc. Finally, we create the new domain and store a reference to it in our new field. Now, it's time to load our DLL:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"></pre>
<pre class="csharpcode">    FileStream stream = <span class="kwrd">new</span> FileStream(path,FileMode.Open,FileAccess.Read);<br>    <span class="kwrd">byte</span>[] assemblyData = <span class="kwrd">new</span> <span class="kwrd">byte</span>[stream.Length];<br>    stream.Read(assemblyData,0,(<span class="kwrd">int</span>)stream.Length);<br>    stream.Close();<br>    Assembly asm = PluginDomain.Load(assemblyData);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>First, we read our plug-in from disk it's important to note that were are not “loading” the assembly at this point. No initialization code executes and no processing of the data is done we are merely reading the bytes from disk. We need to do this because
 the module loader itself runs in our new domain, which if you recall, doesn't have access to the file system, not even to load its own code. The actual module loading occurs in the new domain from our buffer, so there is no chance of any code “escaping” Finally,
 we search the assembly using reflection to find any classes that implement ISudokuSolver:
</p>
<p>&nbsp;</p>
<pre class="csharpcode">    Type[] ts = asm.GetTypes();<br>    <span class="kwrd">foreach</span> (Type t <span class="kwrd">in</span> ts)<br>    {<br>        <span class="kwrd">if</span> (Array.IndexOf(t.GetInterfaces(),<span class="kwrd">typeof</span>(ISudokuSolver)) != -1)<br>        {<br>            Type containter = <span class="kwrd">typeof</span>(SudokuSolverContainer);<br>            SudokuSolverContainer ssc = ad.CreateInstanceAndUnwrap(<br>            containter.Assembly.FullName,containter.FullName) <span class="kwrd">as</span> SudokuSolverContainer;<br>            ssc.Init(t);<br>            <span class="kwrd">return</span> ssc;<br>        }<br>    }<br>    <span class="kwrd">return</span> <span class="kwrd">null</span>;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The Type class is another way of representing the type of an object. Basically, imagine if you replaced all references to a type, say ArrayList, with a string variable, which you set to “ArrayList”, then at run-time you could change the string to, for example,
 “HashTable”, now all the code the used ArrayLists now uses HashTables, in a sense, you've made the type of variable, a variable itself. Ok, so if your head hasn't exploded yet, no imagine that instead of string you used an instance of Type. Why? Well first
 of all string comparisons are bad form for things like this and second, Type contains a plethora of useful stuff that allows you to do things like loop through the methods of a class or inspect the inheritance tree. How do you get Types you say? Well it's
 simple you just use the typeof keyword to extract it from your class. Here we search for a type that implements ISudokuSolver, then when we find one, we create an instance of it and return it. By default, creating an instance across a domain boundary creates
 an opaque proxy object that allows other domains to deal with types they don't reference. Because our code does have access to the SudokuSolver base class we can unwrap the proxy to a transparent proxy. Finally, I added a new field to Window1 to contain the
 solver, which I then load in the Loaded event handler. Then to make it work, I added a button to the timer pane, labeled “I Give Up”, which executes the solver like this:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">int</span>?[,] a = Board.GameBoard.ToArray();<br><span class="kwrd">if</span> (!Solver.Solve(<span class="kwrd">ref</span> a))<br>{<br>    MessageBox.Show(<span class="str">&quot;No Solution!&quot;</span>);<br>}<br><span class="kwrd">else</span><br>{<br>    Board.GameBoard.FromArray(a);<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Pretty straightforward eh? The proxy object does all the work of crossing the app domain. You can see that this works, if you try to put an offending line of code in the plug-in, execution stops immediately:
</p>
<p><img height="374" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178206/clip_image0061.jpg" width="480">
</p>
<p>I also added a new board generation algorithm. Really, the one I wrote last tutorial is pretty bad. It generates lots of unsolvable grids, which if you're strict, isn't allowed. The real way of generating a Sudoku board is to generate a full valid board
 then blank out cells. To accomplish this I've added a new method to the Board class to generate a board based on a solver. Basically, it seeds the solver by filling in a single random cell with a random number.
</p>
<p>&nbsp;</p>
<pre class="csharpcode">Random rnd = <span class="kwrd">new</span> Random();<br><span class="kwrd">int</span> row = rnd.Next(size);<br><span class="kwrd">int</span> col = rnd.Next(size);<br><span class="kwrd">this</span>[row, col].Value = rnd.Next(size)&#43;1;<br><span class="kwrd">int</span>?[,] a = <span class="kwrd">this</span>.ToArray();<br>s.Solve(<span class="kwrd">ref</span> a);<br><span class="kwrd">this</span>.FromArray(a);<br><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Then, it runs the solver to fill the rest of the grid, which it then selectively blanks. This takes a little longer (depending on the solver) than the default method so I also added a radio button to choose the algorithm:
</p>
<p><img height="359" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178206/clip_image0081.jpg" width="480">
</p>
<p>Ok, that's all well and good but how did I go about writing a Sudoku solving algorithm? Well my algorithm is a recursive one. First, I build a new board structure of List&lt;int&gt;s that contain the possible number at each square, so for example, on givens, the
 list is 1 item long and contains the given number, whereas on blank squares it contains all possible numbers. Then the algorithm looks for all column, row, and box conflicts that eliminate numbers from lists until there are no more items that can be definitely
 removed. Then, the solver finds the shortest list with length greater than 1 in the grid and picks and random starting point in its list. Then for each possible “guess” it performs a deep copy of the board and recurses, this way it can backtrack if a certain
 guess results in no solution. When all guesses have been tried and no solution is found then the algorithm returns false. Alternatively, if the board is full, e.g. each list is exactly 1 long and there are no conflicts then the board is solved. You can check
 the code out in the download but I'll be the first to tell you that this algorithm sucks, at least for solving the boards the program generates. I hereby challenge you to write a better one - That's the great about supporting plug-ins, it allows you to offload
 functionality onto the user….err, I mean include extensibility. </p>
<p>Ok, so now that's working, let's start getting the game more playable. First we need to implement a timer, we could do this in two ways: a) create our own threaded or polling timer code or b) use the built-in WPF animation system….guess which one I'm going
 to cover (it really is easier, I promise). First, we need to redefine our timer display to more easily accept a bound input source:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">StackPanel</span> <span class="attr">Orientation</span> <span class="kwrd">=&quot;Horizontal&quot;</span> <span class="attr">FlowDirection</span> <span class="kwrd">=&quot;LeftToRight&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;MinNumber&quot;</span> <span class="attr">FontSize</span> <span class="kwrd">=&quot;36&quot;</span> <span class="attr">FontWeight</span> <span class="kwrd">=&quot;Bold&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">FontSize</span><span class="kwrd">=&quot;36&quot;</span> <span class="attr">FontWeight</span><span class="kwrd">=&quot;Bold&quot;</span> <span class="attr">Text</span> <span class="kwrd">=&quot;:&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;SecNumber&quot;</span> <span class="attr">FontSize</span> <span class="kwrd">=&quot;36&quot;</span> <span class="attr">FontWeight</span><span class="kwrd">=&quot;Bold&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Margin</span><span class="kwrd">=&quot;0,5,0,0&quot;</span> <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <br>    <span class="attr">FontSize</span><span class="kwrd">=&quot;24&quot;</span> <span class="attr">FontWeight</span><span class="kwrd">=&quot;Bold&quot;</span> <span class="attr">Text</span> <span class="kwrd">=&quot;:&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Margin</span><span class="kwrd">=&quot;0,5,0,0&quot;</span> <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <br>    <span class="attr">x:Name</span> <span class="kwrd">=&quot;SubSecNumber&quot;</span><br>  <span class="attr">FontSize</span> <span class="kwrd">=&quot;24&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span><br><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>We also need define the storyboard that will control our animation, since we don't want the timer to associate with a particular event or control we can define it as “free floating” by putting in our &lt;Window.Resources&gt; tag (we'll write the Completed event
 handler later): </p>
<p>&nbsp;</p>
<pre class="csharpcode"></pre>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Storyboard</span> <span class="attr">x:Key</span> <span class="kwrd">=&quot;TimerAnimation&quot;</span> <span class="attr">Completed</span> <span class="kwrd">=&quot;TimerDone&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Int32Animation</span> <span class="attr">From</span> <span class="kwrd">=&quot;1&quot;</span> <span class="attr">To</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;MinNumber&quot;</span><br>    <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;Tag&quot;</span> <span class="attr">Duration</span> <span class="kwrd">=&quot;0:2:0&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Int32Animation</span> <span class="attr">From</span> <span class="kwrd">=&quot;59&quot;</span> <span class="attr">To</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">RepeatBehavior</span><span class="kwrd">=&quot;Forever&quot;</span><br>    <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;SecNumber&quot;</span> <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;Tag&quot;</span><br>    <span class="attr">Duration</span> <span class="kwrd">=&quot;0:1:0&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Int32Animation</span> <span class="attr">From</span> <span class="kwrd">=&quot;59&quot;</span> <span class="attr">To</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">RepeatBehavior</span><span class="kwrd">=&quot;Forever&quot;</span><br>    <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;SubSecNumber&quot;</span> <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;Tag&quot;</span><br>    <span class="attr">Duration</span> <span class="kwrd">=&quot;0:0:1&quot;</span><span class="kwrd">/&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>There are a couple of important things to notice here: First, how come the durations of the second counter and the and 1/60<sup>th</sup> of a second time are only one second and one minute respectively? Well, the storyboard expands to fit the longest animation
 it contains. With RepeatBehavior=&quot;Forever&quot; each animation repeats indefinitely, if we instead specify a duration, like we will in code later, then the animation will repeat within the overal duration, or in other words, if the total timer runs for 10 minutes
 then the second number animation will run 10 times since it counts down each second for a single minute. Second, why do the animations target the Tag property intead of Text? We have to do this because, the Text property is of type string, which cant be animated
 using an Int32Animation (there is no StringAnimation, in fact, could you even make one?) To make this work we can define the TextBlocks like so:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;MinNumber&quot;</span> <span class="attr">FontSize</span> <span class="kwrd">=&quot;36&quot;</span> <span class="attr">FontWeight</span> <span class="kwrd">=&quot;Bold&quot;</span> <br>    <span class="attr">Text</span> <span class="kwrd">=&quot;{Binding RelativeSource={RelativeSource Self},Path=Tag}&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock.Tag</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span>59<span class="kwrd">&lt;/</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">TextBlock.Tag</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><img height="184" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178206/clip_image011.gif" width="314">
</p>
<p>This way the control automatically displays the contents of its tag, which we initialize to an integer. Next, lets a pause button. Since this a WPF tutorial, a normal button just doesn't cut it so let's build a custom toggle button:
</p>
<p>The needle in the stopwatch should animate as the timer advances, so we'll also implement a custom dependency property that allows the needle to be animated and databound. First, add a new user control the project named “Stopwatch.xaml”, now in the .xaml
 and .cs files that compose the control replace the UserControl class with the ToggleButton type, this causes our control to inherit from ToggleButton instead of UserControl. Next, let's start by defining our custom property, to do this we need to define a
 property description object as a static member of our class: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> DependencyProperty CurrentTimeProperty = <br>    DependencyProperty.Register(<span class="str">&quot;CurrentTime&quot;</span>,<br>        <span class="kwrd">typeof</span>(<span class="kwrd">double</span>),<br>        <span class="kwrd">typeof</span>(Stopwatch),<br>        <span class="kwrd">new</span> FrameworkPropertyMetadata(0.0,<br>            FrameworkPropertyMetadataOptions.AffectsRender<br>            )<br>);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>When calling the DependencyProperty.Register method to create our descriptor we specify the name of our property (“CurrentTime”), the type it will contain ( a double), what type it is attached to (out new Stopwatch type), it's default value (a double set
 to 0), and finally any extra flags. In this case we want our control to be redrawn when the property changes so we include the AffectsRender flag. This is all well and good but we still cant access the property from C# code, to make this work we also need
 to define a matching instance property: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">double</span> CurrentTime<br>{<br>    get<br>    {<br>        <span class="kwrd">return</span> (<span class="kwrd">double</span>)<span class="kwrd">this</span>.GetValue(CurrentTimeProperty);<br>    }<br>    set<br>    {<br>        <span class="kwrd">this</span>.SetValue(CurrentTimeProperty, <span class="kwrd">value</span>);<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This property just wraps our WPF property in a more C# friendly package. We don't actually require this in this particular instance, but its good practice to automatically define these properties in pairs since it avoids some cryptic “why doesn't this work?!”
 situations down the road if you forget. As for the control itself, its really just a custom template, in fact if you want to get technical, we could have built this entire control as a ToggleButton style, storing the current time in the Tag property, but that's
 no fun! To make the control itself work, I've added triggers to alter the top button image displayed (the lit one uses a another bitmap effect called OuterGlowBitmapEffect) and to “clunk” the control when it is clicked:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Trigger</span> <span class="attr">Property</span> <span class="kwrd">=&quot;ToggleButton.IsChecked&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;True&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span> <span class="kwrd">=&quot;OffLight&quot;</span> <span class="attr">Property</span><span class="kwrd">=&quot;Visibility&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;Hidden&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span> <span class="kwrd">=&quot;OnLight&quot;</span> <span class="attr">Property</span><span class="kwrd">=&quot;Visibility&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;Visible&quot;</span><span class="kwrd">/&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Trigger</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;</span><span class="html">Trigger</span> <span class="attr">Property</span> <span class="kwrd">=&quot;ToggleButton.IsPressed&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;True&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span><span class="kwrd">=&quot;MainGrid&quot;</span> <span class="attr">Property</span><span class="kwrd">=&quot;RenderTransform&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">TranslateTransform</span> <span class="attr">X</span> <span class="kwrd">=&quot;1&quot;</span> <span class="attr">Y</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Trigger</span><span class="kwrd">&gt;</span><br><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Because we derive from ToggleButton, we can use the existing control logic and properties. I'll skip over most the actual XAML that defines the look of the control since you can find it in the download and we've covered doing basic shapes and gradients before,
 so the only relevant part is the definition of the needle, which is part of a larger drawing:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">GeometryDrawing</span> <span class="attr">Brush</span> <span class="kwrd">=&quot;Red&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">GeometryDrawing.Geometry</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">PathGeometry</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">PathGeometry.Figures</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">PathFigure</span> <span class="attr">IsClosed</span> <span class="kwrd">=&quot;True&quot;</span> <span class="attr">IsFilled</span> <span class="kwrd">=&quot;True&quot;</span> <span class="attr">StartPoint</span> <span class="kwrd">=&quot;50,40&quot;</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">LineSegment</span> <span class="attr">Point</span> <span class="kwrd">=&quot;51,66&quot;</span><span class="kwrd">/&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">LineSegment</span> <span class="attr">Point</span> <span class="kwrd">=&quot;49,66&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">PathFigure</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">PathGeometry.Figures</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">PathGeometry.Transform</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">RotateTransform</span> <span class="attr">CenterX</span> <span class="kwrd">=&quot;50&quot;</span> <span class="attr">CenterY</span> <span class="kwrd">=&quot;66&quot;</span> <br>           <span class="attr">Angle</span> <span class="kwrd">=&quot;{Binding Path=CurrentTime, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource AngleConverter}}&quot;</span><span class="kwrd">/&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">PathGeometry.Transform</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">PathGeometry</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing.Geometry</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">GeometryDrawing</span><span class="kwrd">&gt;</span><br><br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You can see here that the Angle property of our transform is bound to the custom CurrentTime property we defined. If you've been paying attention so far you'll notice that the convention in WPF is for angles to be specified in degrees (0-360) while, completion
 is usually specified as a double ranging from 0-1.0. How can we multiply our CurrentTime value by 360 in the process of binding it? The answer is converters. By defining s custom converter you can perform any operation on the values as they are bound. Since
 we just want to multiply by a number we can use the follow converter: </p>
<p>&nbsp;</p>
<pre class="csharpcode">[ValueConversion(<span class="kwrd">typeof</span>(<span class="kwrd">double</span>), <span class="kwrd">typeof</span>(<span class="kwrd">double</span>))]<br><span class="kwrd">public</span> <span class="kwrd">class</span> AngleConverter : IValueConverter<br>{<br>    <span class="kwrd">public</span> <span class="kwrd">object</span> Convert(<span class="kwrd">object</span> <span class="kwrd">value</span>, Type targetType,<br>        <span class="kwrd">object</span> parameter, CultureInfo culture)<br>    {<br>        <span class="kwrd">return</span> (<span class="kwrd">double</span>)<span class="kwrd">value</span> * 360;<br>    }<br><br>    <span class="kwrd">public</span> <span class="kwrd">object</span> ConvertBack(<span class="kwrd">object</span> <span class="kwrd">value</span>, Type targetType,<br><br>    <span class="kwrd">object</span> parameter, CultureInfo culture)<br>    {<br>        <span class="kwrd">return</span> (<span class="kwrd">double</span>)<span class="kwrd">value</span> / 360;<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Then, we just instantiate our AngleConverter class in our resources section and reference it from the binding as done above. Converters also support parameters so if we really wanted to be slick we could supply the multiplier as a parameter to a generic
 multiplication converter. </p>
<p>Just like the board control, I've placed the stopwatch on the main window, this time under the timer numbering:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">clr:Stopwatch</span> <span class="attr">Checked</span><span class="kwrd">=&quot;ResumeTimer&quot;</span> <span class="attr">Unchecked</span><span class="kwrd">=&quot;PauseTimer&quot;</span> <span class="attr">Margin</span><span class="kwrd">=&quot;0,5,0,0&quot;</span><br>   <span class="attr">x:Name</span><span class="kwrd">=&quot;StopwatchControl&quot;</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Stretch&quot;</span><span class="kwrd">/&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>I've also hooked up some of standard ToggleButton events to make the button actually do something. This works transparently, again because our control derives from ToggleButton. Also added is a new animation in our timer storyboard to animate the stopwatch
 needle: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">From</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">To</span> <span class="kwrd">=&quot;1&quot;</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;StopwatchControl&quot;</span><br>     <span class="attr">Duration</span><span class="kwrd">=&quot;0:2:0&quot;</span> <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;CurrentTime&quot;</span><span class="kwrd">/&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>And finally a new set of radio buttons to select the timer length: </p>
<p><img height="360" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178206/clip_image0131.jpg" width="480">
</p>
<p>Now, in the New Game button click handler, we need to add code to start the timer:
</p>
<p>&nbsp;</p>
<pre class="csharpcode">Storyboard s = <span class="kwrd">this</span>.Resources[<span class="str">&quot;TimerAnimation&quot;</span>] <span class="kwrd">as</span> Storyboard;<br>s.Stop(<span class="kwrd">this</span>);<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>First, we get the storyboard out of the window's resources section and stop it if it's already running. Next, we either disable and ghost out the related control or setup the timer:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">if</span> (NoTimerRadio.IsChecked == <span class="kwrd">true</span>)<br>{<br>    MinNumber.Tag = 59;<br>    SecNumber.Tag = 59;<br>    SubSecNumber.Tag = 59;<br>    TimerControls.Opacity = 0.25;<br>    TimerControls.IsEnabled = <span class="kwrd">false</span>;<br>    StopwatchControl.IsChecked = <span class="kwrd">false</span>;<br>}<br><span class="kwrd">else</span><br>{<br>    Int32 length;<br>    <span class="kwrd">if</span> (EasyTimerRadio.IsChecked == <span class="kwrd">true</span>)<br>    {<br>        length = 15;<br>    }<br>    <span class="kwrd">else</span> <span class="kwrd">if</span> (MediumTimerRadio.IsChecked == <span class="kwrd">true</span>)<br>    {<br>        length = 10;<br>    }<br>    <span class="kwrd">else</span><br>    {<br>        length = 5;<br>    }<br><br>    <span class="rem">//the stopwatch controller</span><br>    s.Children[0].Duration = <span class="kwrd">new</span> Duration(TimeSpan.FromMinutes(length));<br><br>    <span class="rem">//the minute ticker</span><br>    s.Children[1].Duration = <span class="kwrd">new</span> Duration(TimeSpan.FromMinutes(length));<br><br>    <span class="rem">//the second ticker</span><br>    s.Children[2].RepeatBehavior = <span class="kwrd">new</span> RepeatBehavior(TimeSpan.FromMinutes(length));<br><br>    <span class="rem">//the 1/60 second ticker</span><br>    s.Children[3].RepeatBehavior = <span class="kwrd">new</span> RepeatBehavior(TimeSpan.FromMinutes(length));<br>    ((Int32Animation)s.Children[1]).From = length - 1;<br>    StopwatchControl.IsChecked = <span class="kwrd">true</span>;<br>    MinNumber.Tag = length - 1;<br>    TimerControls.Opacity = 1;<br>    TimerControls.IsEnabled = <span class="kwrd">true</span>;<br>    s.Begin(<span class="kwrd">this</span>, <span class="kwrd">true</span>);<br>}<br>Board.IsEnabled = <span class="kwrd">true</span>;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>And finally we begin the storyboard, setting the main window as its parent control. Then we need to define the event handler to handle the timer completion:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">void</span> TimerDone(<span class="kwrd">object</span> sender, EventArgs e)<br>{<br>    TimerControls.Opacity = 0.25;<br>    TimerControls.IsEnabled = <span class="kwrd">false</span>;<br>    StopwatchControl.IsChecked = <span class="kwrd">false</span>;<br>    <span class="kwrd">if</span> (Board.GameBoard.IsFull &amp;&amp; Board.GameBoard.IsValid)<br>    {<br>        MessageBox.Show(<span class="str">&quot;You win!&quot;</span>);<br>    }<br>    <span class="kwrd">else</span><br>    {<br>        MessageBox.Show(<span class="str">&quot;You ran out of time! Better luck next time.&quot;</span>);<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>And the handlers for the pressed events of the stopwatch: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">void</span> PauseTimer(<span class="kwrd">object</span> sender, RoutedEventArgs e)<br>{<br>    Storyboard s = <span class="kwrd">this</span>.Resources[<span class="str">&quot;TimerAnimation&quot;</span>] <span class="kwrd">as</span> Storyboard;<br>    s.Pause(<span class="kwrd">this</span>);<br>    Board.IsEnabled = <span class="kwrd">false</span>;<br>}<br><br><span class="kwrd">void</span> ResumeTimer(<span class="kwrd">object</span> sender, RoutedEventArgs e)<br>{<br>    Storyboard s = <span class="kwrd">this</span>.Resources[<span class="str">&quot;TimerAnimation&quot;</span>] <span class="kwrd">as</span> Storyboard;<br>    s.Resume(<span class="kwrd">this</span>);<br>    Board.IsEnabled = <span class="kwrd">true</span>;<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Since the storyboard supports pausing and resuming it's dead simple! After adding some extra housekeeping code, an implementing a super-basic save game system using the built-in serialization functions in the .NET Framework to write the array representation
 of the game board to a file we now have a working Sudoku game! This code is included in the download so if you're still not a .NET pro (hey, it's ok!) you can check it out. Don't forget to come back next time for the 5<sup>th</sup> and final article in the
 series were we finish off the app and sand off all the rough edges. I'll be covering spiffy stuff like:
</p>
<ul>
<li>Implementing a cooler message box than MessageBox </li><li>Selecting and loading multiple solvers </li><li>Benchmarking solvers and displaying the results in a graphing control.</li></ul>
<p>See you next time!</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Lucas-Magder/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:6b41155e62274314ada89e7600d7b941">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-4-Building-a-Least-Privilege-Plug-in-System-and-Even-More-Custom-Con</comments>
      <itunes:summary>



&amp;nbsp;
Building Sudoku using Windows Presentation Foundation and XAML, Microsoft&#39;s new declarative programming language. This is the 4th article from a series of 5 articles and focusses on building a least privilege plug-in
 system and some more custom controls.



Lucas Magder


Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual C# 2005 Express Edition&amp;nbsp;.NET
 Framework&amp;nbsp;3.0 Runtime Components 
Windows Vista RTM SDK 
Visual Studio Extensions for the .NET Framework 3.0 November 2006 CTP
Hardware: 
Download: Download (note: Tasos Valsamidis has an updated version that supports
Expression Blend here)





Note: This article has been updated to work and compile with the RTM version of the Windows SDK. 
Welcome to the fourth part of my Windows Presentation Foundation tutorial! In this tutorial we&#39;ll be building a plug-in system for sudoku-solving algorithms, delving deeper into custom controls, including deriving from exiting controls and implementing custom
 properties. Also, we&#39;ll complete more of the UI and game logic to start turning this pile of unrelated code into a game! First, let&#39;s look at building a plug-in system: There are essentially two ways of providing an extensibility system in a .NET application:
 

Scripting: We could provide a custom programming language that plug-in authors need to write their code in.
Module Loading: We could dynamically load pre-compiled modules at runtime.
 

If we take the scripting approach we need to either create our own language, which is a lot of work and honestly, who likes to reinvent the wheel? We could also use the built-in compilation functionality in the .NET Framework to compiler, say C# code as a script,
 which takes less work but doesn&#39;t allow us to create a “sandbox” language that can only perform certain actions. Plug-in modules suffer from the same issues, but they don&#39;t require us to provide a set of tools for plug-in developers since Visual Studio is
 all that&#39;s needed. With the </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-4-Building-a-Least-Privilege-Plug-in-System-and-Even-More-Custom-Con</link>
      <pubDate>Thu, 30 Nov 2006 11:19:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-4-Building-a-Least-Privilege-Plug-in-System-and-Even-More-Custom-Con</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1178206_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1178206_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Lucas Magder</dc:creator>
      <itunes:author>Lucas Magder</itunes:author>
      <slash:comments>3</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-4-Building-a-Least-Privilege-Plug-in-System-and-Even-More-Custom-Con/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Puzzle</category>
    </item>
  <item>
      <title>Building a WPF Sudoku Game: Part 3 - Adding Polish and Customizing Controls</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">Building Sudoku using Windows Presentation Foundation and XAML, Microsoft's new declarative programming language. This is the 3rd article from a series of 5 articles and focusses on adding polish and customizing
 controls. </span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Lucas Magder</div>
<div class="entry_company"><a></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details">
<div class="entry_details"><strong>Software:</strong> <span class="entry_details_input">
<a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/">Visual C# 2005 Express Edition</a>&nbsp;<a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&amp;displaylang=en">.NET Framework&nbsp;3.0 Runtime Components</a>
<a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;displaylang=en">
Windows Vista RTM SDK</a> <a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=f54f5537-cc86-4bf5-ae44-f5a1e805680d&amp;DisplayLang=en">
Visual Studio Extensions for the .NET Framework 3.0 November 2006 CTP</a></span></div>
</div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/262078_SudokuFX3.zip">Download</a> (note: Tasos Valsamidis has an updated version that supports
<a class="" href="http://channel9.msdn.com/ShowPost.aspx?PostID=282120">Expression Blend here</a>)</div>
<div class="entry_details">&nbsp;</div>
</td>
</tr>
</tbody>
</table>
<span><strong>Note</strong>: This article has been updated to work and compile with the RTM version of the Windows SDK.</span></span>&nbsp;
<p><br>
Welcome to the third part of my Windows Presentation Foundation tutorial! In this tutorial we'll be adding some cool UI elements to spice up the application we built last time. First, let's redo the background a little; let's add a cool pulsating gradient,
 like the Xbox 360: </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image0012.jpg"><img height="135" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image0011.jpg" width="240" border="0"></a>
</p>
<p>(This picture is from a random internet search, I need to find an internal one I can use in the real article)
</p>
<p>Ok. So how we do this? If you've scoped out the documentation already you'll know there is a RadialGradientBrush we can use, but how can we layer multiple brushes, and most importantly how can we animate them? To make this work I've replaced the GradientPanel
 style with a new one. The new style uses a DrawingBrush to compose a collection of geometry objects into a single image. To create the desired effect I layered a bunch of rectangles painted with radial gradients like this:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">DrawingBrush</span> <span class="attr">Stretch</span> <span class="kwrd">=&quot;UniformToFill&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">DrawingBrush.Drawing</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">DrawingGroup</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">GeometryDrawing</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GeometryDrawing.Brush</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">SolidColorBrush</span> <span class="attr">Color</span> <span class="kwrd">=&quot;White&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing.Brush</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GeometryDrawing.Geometry</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">RectangleGeometry</span> <span class="attr">Rect</span><span class="kwrd">=&quot;0,0,1,1&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing.Geometry</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">GeometryDrawing</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GeometryDrawing.Brush</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">RadialGradientBrush</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">RadialGradientBrush.RelativeTransform</span><span class="kwrd">&gt;</span><br>              <span class="kwrd">&lt;</span><span class="html">TranslateTransform</span> <span class="attr">X</span> <span class="kwrd">=&quot;-0.2&quot;</span> <span class="attr">Y</span> <span class="kwrd">=&quot;0&quot;</span><span class="kwrd">/&gt;</span><br>            <span class="kwrd">&lt;/</span><span class="html">RadialGradientBrush.RelativeTransform</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span><span class="kwrd">=&quot;#850039d6&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0&quot;</span><span class="kwrd">/&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span><span class="kwrd">=&quot;#654577Ff&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0&quot;</span><span class="kwrd">/&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span><span class="kwrd">=&quot;#850039d6&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0.33&quot;</span><span class="kwrd">/&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span><span class="kwrd">=&quot;#654577FF&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0.66&quot;</span><span class="kwrd">/&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span><span class="kwrd">=&quot;#850039D6&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span><br>          <span class="kwrd">&lt;/</span><span class="html">RadialGradientBrush</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing.Brush</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GeometryDrawing.Geometry</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">RectangleGeometry</span> <span class="attr">Rect</span><span class="kwrd">=&quot;0,0,1,1&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing.Geometry</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>--Code Shortened…--</b> </p>
<p>&nbsp;</p>
<pre class="csharpcode">    <span class="kwrd">&lt;/</span><span class="html">DrawingGroup</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">DrawingBrush.Drawing</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">DrawingBrush</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>The full version of the code included in the source files produces a background like this (I've removed the controls so you can see it better)
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image00312.jpg"><img height="180" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image00311.jpg" width="240" border="0"></a><br>
Next, we can use a feature of the framework called triggers to create an animation to make the background pulse. Essentially, a trigger definition tells WPF to connect a cause and effect, or in other words, “when A happens do B”. Triggers can fire in response
 to events or a certain value of one or more properties. A trigger can then start, stop or pause animations, or set the value of a property. This is great because it means you only really have to write code if you want to do anything exotic, in this case we
 just want to start an animation on the “Loaded” event of our panel. </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Style.Triggers</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">EventTrigger</span> <span class="attr">RoutedEvent</span> <span class="kwrd">=&quot;Control.Loaded&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">EventTrigger.Actions</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">Storyboard</span> <span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">ColorAnimation</span> <span class="attr">RepeatBehavior</span><span class="kwrd">=&quot;Forever&quot;</span> <span class="attr">Duration</span> <span class="kwrd">=&quot;0:0:4&quot;</span> <br>              <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;Background.Drawing.Children[1].Brush.GradientStops[0].Color&quot;</span> <br>              <span class="attr">From</span> <span class="kwrd">=&quot;#654577Ff&quot;</span><span class="kwrd">/&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">RepeatBehavior</span><span class="kwrd">=&quot;Forever&quot;</span> <span class="attr">Duration</span><span class="kwrd">=&quot;0:0:4&quot;</span> <br>              <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;Background.Drawing.Children[1].Brush.GradientStops[0].Offset&quot;</span><br>              <span class="attr">From</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">To</span> <span class="kwrd">=&quot;0.33&quot;</span><span class="kwrd">/&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p><b>--Code Shortened…--</b> </p>
<p>&nbsp;</p>
<pre class="csharpcode">        <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">EventTrigger.Actions</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">EventTrigger</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Style.Triggers</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>From the code it should be pretty evident what's going on. The properties of the GradientStop objects are being animated in a loop. The Duration property is specified in h:m:s so the animation runs for 4 seconds and the From and To properties specify the
 beginning and ending values of the animated property. If you omit one of these, the current value at the beginning of the animation is used. The only other thing here probably needs explanation is the TargetProperty syntax. Since the storyboard is part of
 a trigger that is specified in a style, it has to point to the object the style is applied to. Since we need to affect a property a few levels down the hierarchy we can use a relative property path. The concept here is identical to how filenames work; if we
 are in the GradientStop object we can just reference the Color property directly. If we move up to the LinearGradientBrush we have to specify that the property we want is a member of Brush property of our current scope. (If you run the application and find
 that it runs unbearably slow with the animation code added, this could be due to WPF falling back to software-only mode. Upgrading your video drivers might help, but if all else fails, just comment out the triggers block)
</p>
<p>Next, let's make the expander controls we originally styled in article 1 look better and remove the need for the extra border kludge. To do this we need to modify the control's template, the XAML that defines the visual aspects of the control. Because this
 XAML is completely separate from the code used to create the control, we can redefine it easily. In fact, all the standard controls are really implemented through default control templates. The C# code behind them merely implements the “concept” of the control,
 for example, you can create any control that can be pressed, by creating a new template for the Button control. What's great about this is that we don't have to waste time duplicating the control's logic, events, or properties, and can change only what we
 want, the look. The easiest way to start working with control templates is to start with the default template and modify it. The easiest way to do this, since the default template is compiled into the control, is to dump the XAML to disk with a short code
 fragment (which you can then remove): </p>
<p>&nbsp;</p>
<pre class="csharpcode">System.Xml.XmlTextWriter xtr = <span class="kwrd">new</span> System.Xml.XmlTextWriter<br>    (<span class="str">@&quot;c:\temp.xaml&quot;</span>,System.Text.Encoding.UTF8);<br>System.Windows.Markup.XamlWriter.Save(MyControl.Template, xtr);<br>xtr.Close();</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>(If you have Expression Interactive Designer, it also has a feature to do this.) The template for the expander is pretty lengthy since it deals with other cases we don't care about like left-to-right expansion, so I won't show the code here, since your eyes
 would probably just glaze over and you know where to get it. Essentially, what's important about this code is it tells us the basic structure of the control, there is a DockPanel with a ToggleButton that's made to not look like a button and that contains the
 arrow and the header. The content of the expander fills the DockPanel. In the toggle button I've replaced the default circle/arrow thing with glassy looking button:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Ellipse</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;BackGrad&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;19&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;19&quot;</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <br>         <span class="attr">VerticalAlignment</span> <span class="kwrd">=&quot;Center&quot;</span> <span class="attr">StrokeThickness</span><span class="kwrd">=&quot;1&quot;</span> <span class="attr">Stroke</span> <span class="kwrd">=&quot;DarkBlue&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Ellipse.Fill</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush</span> <span class="attr">StartPoint</span> <span class="kwrd">=&quot;0,0&quot;</span> <span class="attr">EndPoint</span> <span class="kwrd">=&quot;0,1&quot;</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush.GradientStops</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span> <span class="kwrd">=&quot;LightSkyBlue&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span> <span class="kwrd">=&quot;Blue&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0.5&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span> <span class="kwrd">=&quot;LightSkyBlue&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush.GradientStops</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Ellipse.Fill</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Ellipse</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;</span><span class="html">Ellipse</span> <span class="attr">Height</span><span class="kwrd">=&quot;19&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;19&quot;</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <br>         <span class="attr">VerticalAlignment</span> <span class="kwrd">=&quot;Center&quot;</span> <span class="attr">Stroke</span> <span class="kwrd">=&quot;Transparent&quot;</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;FadeMask&quot;</span><br>         <span class="attr">StrokeThickness</span><span class="kwrd">=&quot;1&quot;</span> <span class="attr">Opacity</span> <span class="kwrd">=&quot;0&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Ellipse.Fill</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">SolidColorBrush</span> <span class="attr">Color</span> <span class="kwrd">=&quot;AliceBlue&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Ellipse.Fill</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Ellipse</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;</span><span class="html">Path</span> <span class="attr">Stroke</span><span class="kwrd">=&quot;White&quot;</span> <span class="attr">StrokeThickness</span><span class="kwrd">=&quot;2&quot;</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <br>      <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Arrow&quot;</span> <span class="attr">SnapsToDevicePixels</span><span class="kwrd">=&quot;False&quot;</span> <br>  <span class="attr">Data</span><span class="kwrd">=&quot;M1,1.5 L4.5,5 8,1.5&quot;</span><span class="kwrd">/&gt;</span><br><span class="kwrd">&lt;</span><span class="html">Ellipse</span> <span class="attr">Height</span><span class="kwrd">=&quot;19&quot;</span> <span class="attr">Width</span><span class="kwrd">=&quot;19&quot;</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Center&quot;</span> <span class="attr">VerticalAlignment</span> <span class="kwrd">=&quot;Center&quot;</span> <br>         <span class="attr">x:Name</span> <span class="kwrd">=&quot;Highlight&quot;</span> <span class="attr">StrokeThickness</span> <span class="kwrd">=&quot;2&quot;</span> <span class="attr">Stroke</span> <span class="kwrd">=&quot;Transparent&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Ellipse.Fill</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">DrawingBrush</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">DrawingBrush.Drawing</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GeometryDrawing</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">GeometryDrawing.Brush</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush</span> <span class="attr">Opacity</span> <span class="kwrd">=&quot;0.6&quot;</span> <span class="attr">StartPoint</span> <span class="kwrd">=&quot;0,0&quot;</span> <span class="attr">EndPoint</span> <span class="kwrd">=&quot;0,1&quot;</span><span class="kwrd">&gt;</span><br>              <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush.GradientStops</span><span class="kwrd">&gt;</span><br>                <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span> <span class="kwrd">=&quot;White&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0&quot;</span><span class="kwrd">/&gt;</span><br>                <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span> <span class="kwrd">=&quot;#AAFFFFFF&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span><br>              <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush.GradientStops</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing.Brush</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">GeometryDrawing.Geometry</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">EllipseGeometry</span> <span class="attr">Center</span> <span class="kwrd">=&quot;0.5,0.5&quot;</span> <span class="attr">RadiusX</span> <span class="kwrd">=&quot;0.25&quot;</span> <span class="attr">RadiusY</span> <span class="kwrd">=&quot;0.35&quot;</span><span class="kwrd">/&gt;</span><br>          <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing.Geometry</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">GeometryDrawing</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">DrawingBrush.Drawing</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">DrawingBrush.RelativeTransform</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">ScaleTransform</span> <span class="attr">CenterX</span> <span class="kwrd">=&quot;0.5&quot;</span> <span class="attr">CenterY</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">ScaleX</span> <span class="kwrd">=&quot;1&quot;</span> <span class="attr">ScaleY</span> <span class="kwrd">=&quot;0.5&quot;</span><span class="kwrd">/&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">DrawingBrush.RelativeTransform</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">DrawingBrush</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Ellipse.Fill</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Ellipse</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This code creates a sandwich of 3 ellipses and the arrow graphic to create the button face:
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image00512.gif"><img height="86" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image00511.gif" width="240"></a><br>
Next, I defined some triggers </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">ControlTemplate.Triggers</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Trigger</span> <span class="attr">Property</span><span class="kwrd">=&quot;ToggleButton.IsChecked&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;True&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">=&quot;LayoutTransform&quot;</span> <span class="attr">TargetName</span><span class="kwrd">=&quot;arrow&quot;</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">ScaleTransform</span> <span class="attr">ScaleY</span> <span class="kwrd">=&quot;-1&quot;</span><span class="kwrd">/&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Trigger</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Trigger</span> <span class="attr">Property</span> <span class="kwrd">=&quot;ToggleButton.IsPressed&quot;</span> <span class="attr">Value</span> <span class="kwrd">=&quot;True&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span> <span class="kwrd">=&quot;BackGrad&quot;</span> <span class="attr">Property</span> <span class="kwrd">=&quot;RenderTransform&quot;</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">TranslateTransform</span> <span class="attr">X</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">Y</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Trigger</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>These two triggers, respond to property changes. When the toggle button isn't checked (the control isn't expanded), the arrow if flipped vertically to indicate this. Also, when the button is pressed, the ellipse shifts down a pixel to look “pressed” and
 provide feedback to the user that their click was received. </p>
<p>&nbsp;</p>
<pre class="csharpcode">  <span class="kwrd">&lt;</span><span class="html">EventTrigger</span> <span class="attr">RoutedEvent</span> <span class="kwrd">=&quot;UIElement.MouseEnter&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">EventTrigger.Actions</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;FadeMask&quot;</span><br>            <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;Opacity&quot;</span> <span class="attr">To</span> <span class="kwrd">=&quot;0.4&quot;</span> <br>            <span class="attr">Duration</span> <span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">EventTrigger.Actions</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">EventTrigger</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">EventTrigger</span> <span class="attr">RoutedEvent</span> <span class="kwrd">=&quot;UIElement.MouseLeave&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">EventTrigger.Actions</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;FadeMask&quot;</span> <br>            <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;Opacity&quot;</span> <span class="attr">To</span> <span class="kwrd">=&quot;0&quot;</span> <br>            <span class="attr">Duration</span> <span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">EventTrigger.Actions</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">EventTrigger</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">ControlTemplate.Triggers</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>These triggers animate a mouse-over effect on the glassy button. When the mouse enters and exits the header they start animations that fade the FadeMask ellipse in and out. The animations have no From properties so that if the user moves the mouse away before
 the animation completes the fade out animation will smoothly start instead of jumping to full brightness then fading out. Next, I wrapped the ContentPresenter, the control that displays the expander's contents, in an extra border to implement the effect we
 want: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Border</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;ExpandSite&quot;</span> <span class="attr">Margin</span> <span class="kwrd">=&quot;5,0,5,5&quot;</span> <span class="attr">Background</span> <span class="kwrd">=&quot;#77FFFFFF&quot;</span> <br>    <span class="attr">BorderBrush</span><span class="kwrd">=&quot;{TemplateBinding Border.BorderBrush}&quot;</span> <br>  <span class="attr">BorderThickness</span><span class="kwrd">=&quot;{TemplateBinding Border.BorderThickness}&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Border.LayoutTransform</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">ScaleTransform</span> <span class="attr">ScaleY</span> <span class="kwrd">=&quot;0&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Border.LayoutTransform</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">ContentPresenter</span> <span class="attr">Margin</span><span class="kwrd">=&quot;{TemplateBinding Control.Padding}&quot;</span><br>    <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;{TemplateBinding Control.HorizontalContentAlignment}&quot;</span><br>    <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;{TemplateBinding Control.VerticalContentAlignment}&quot;</span><br>    <span class="attr">Focusable</span><span class="kwrd">=&quot;False&quot;</span> <span class="attr">ContentTemplate</span><span class="kwrd">=&quot;{TemplateBinding ContentControl.ContentTemplate}&quot;</span><br>    <span class="attr">Content</span><span class="kwrd">=&quot;{TemplateBinding ContentControl.Content}&quot;</span> <span class="attr">DockPanel</span>.<span class="attr">Dock</span><span class="kwrd">=&quot;Bottom&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">ContentPresenter</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Border</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The location is important, before we were modifying the ToggleButton that makes up the header, so we edited its template, which is specified in the Expander's template. You'll also notice that I removed unhidden the control and instead included a scale by
 0, the effective does the same thing. This is because I'm about to animate the control's expansion and contraction. To do this I've placed this code in the Expander's control template.
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">ControlTemplate.Triggers</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Trigger</span> <span class="attr">Property</span><span class="kwrd">=&quot;Expander.IsExpanded&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;True&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Trigger.EnterActions</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;ExpandSite&quot;</span> <br>            <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;LayoutTransform.ScaleY&quot;</span><br>            <span class="attr">To</span> <span class="kwrd">=&quot;1&quot;</span> <span class="attr">Duration</span> <span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">/&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;ExpandSite&quot;</span> <br>            <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;Opacity&quot;</span><br>            <span class="attr">To</span> <span class="kwrd">=&quot;1&quot;</span> <span class="attr">Duration</span> <span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">Trigger.EnterActions</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Trigger.ExitActions</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;ExpandSite&quot;</span> <br>            <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span> <span class="kwrd">=&quot;LayoutTransform.ScaleY&quot;</span><br>            <span class="attr">To</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">Duration</span> <span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">/&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">DoubleAnimation</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span> <span class="kwrd">=&quot;ExpandSite&quot;</span> <br>            <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;Opacity&quot;</span><br>            <span class="attr">To</span> <span class="kwrd">=&quot;0&quot;</span> <span class="attr">Duration</span> <span class="kwrd">=&quot;0:0:0.25&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">Trigger.ExitActions</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Trigger</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">ControlTemplate.Triggers</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This code shrinks and fades out the contents of the expander as it contracts and does the reverse when it expands. For the same reason as above the animations have no From property. Finally, let's modify the style to add a drop shadow (since drop shadows
 are cool). To do this you need to set the BitmapEffect property to a DropShadowBitmapEffect like so:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span> <span class="kwrd">=&quot;BitmapEffect&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">DropShadowBitmapEffect</span> <span class="attr">Opacity</span> <span class="kwrd">=&quot;0.5&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image00712.jpg"><img height="180" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image00711.jpg" width="240" border="0"></a><br>
It's that easy...ok well, its easy compared to doing it without WPF. The only caveat I should mention is that, in the current version of WPF, if you apply a bitmap effect to a control it forces that control to render in software mode, that should be fine for
 our simple controls, but for more complex controls it's a significant performance hit. (There are some tricks to lessen the impact of this, which I'll cover later though.) With the new expanders the program looks like this:
</p>
<p>You can also define more complex animations in XAML. To add a cheesy bounce effect to the Sudoku title text I modified the code like this:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Foreground</span> <span class="kwrd">=&quot;White&quot;</span> <span class="attr">Margin</span> <span class="kwrd">=&quot;5&quot;</span> <span class="attr">DockPanel</span>.<span class="attr">Dock</span> <span class="kwrd">=&quot;Top&quot;</span><br>    <span class="attr">FontSize</span> <span class="kwrd">=&quot;36&quot;</span> <span class="attr">Text</span> <span class="kwrd">=&quot;Sudoku&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock.RenderTransform</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">TranslateTransform</span> <span class="attr">X</span><span class="kwrd">=&quot;800&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">TextBlock.RenderTransform</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock.BitmapEffect</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">DropShadowBitmapEffect</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">TextBlock.BitmapEffect</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">TextBlock.Triggers</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">EventTrigger</span> <span class="attr">RoutedEvent</span> <span class="kwrd">=&quot;Control.Loaded&quot;</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">EventTrigger.Actions</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">DoubleAnimationUsingKeyFrames</span> <span class="attr">BeginTime</span> <span class="kwrd">=&quot;0:0:0.25&quot;</span> <br>                <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">=&quot;RenderTransform.X&quot;</span><br>                <span class="attr">AccelerationRatio</span><span class="kwrd">=&quot;0.25&quot;</span><span class="kwrd">&gt;</span><br>              <span class="kwrd">&lt;</span><span class="html">LinearDoubleKeyFrame</span> <span class="attr">Value</span><span class="kwrd">=&quot;800&quot;</span> <span class="attr">KeyTime</span><span class="kwrd">=&quot;0:0:0&quot;</span><span class="kwrd">/&gt;</span><br>              <span class="kwrd">&lt;</span><span class="html">LinearDoubleKeyFrame</span> <span class="attr">Value</span><span class="kwrd">=&quot;-30&quot;</span> <span class="attr">KeyTime</span><span class="kwrd">=&quot;0:0:0.3&quot;</span><span class="kwrd">/&gt;</span><br>              <span class="kwrd">&lt;</span><span class="html">LinearDoubleKeyFrame</span> <span class="attr">Value</span><span class="kwrd">=&quot;20&quot;</span> <span class="attr">KeyTime</span><span class="kwrd">=&quot;0:0:0.5&quot;</span><span class="kwrd">/&gt;</span><br>              <span class="kwrd">&lt;</span><span class="html">LinearDoubleKeyFrame</span> <span class="attr">Value</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">KeyTime</span><span class="kwrd">=&quot;0:0:0.6&quot;</span><span class="kwrd">/&gt;</span><br>            <span class="kwrd">&lt;/</span><span class="html">DoubleAnimationUsingKeyFrames</span><span class="kwrd">&gt;</span><br>          <span class="kwrd">&lt;/</span><span class="html">Storyboard</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">BeginStoryboard</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">EventTrigger.Actions</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">EventTrigger</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">TextBlock.Triggers</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>As you can see, adding animations this way is pretty straightforward, and is almost identical to non-key-framed animations. The only new stuff is the use of the BeginTime property that allows you to start the animation after the event occurs, in this case
 it is used to allow the expanders to drop down before the title slides in. Also, the AccelerationRatio specifies the fraction of the total time the object spends accelerating to its maximum velocity. A value of 1.0 means a smooth acceleration and a value of
 0 means no acceleration at all. </p>
<p>Ok, so after taking a detour defining some styles, it's time to get more of the basic game mechanics working. First let's modify the SudokuBoard class to allow the board to be altered externally. In reality, the GameBoard field contains the same thing as
 the data context of the main list, so instead of synchronizing them, we can eliminate this value altogether.
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> SudokuBoard : UserControl<br>{<br>    <span class="kwrd">public</span> Board GameBoard<br>    {<br>        get<br>        {<br>            <span class="kwrd">return</span> MainList.DataContext <span class="kwrd">as</span> Board;<br>        }<br><br>        set<br>        {<br>            MainList.DataContext = <span class="kwrd">value</span>;<br>        }<br>    }<br><br>    <span class="kwrd">public</span> SudokuBoard()<br>    {<br>        InitializeComponent();<br>        <span class="kwrd">this</span>.GameBoard = <span class="kwrd">new</span> Board(9);<br>    }<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Next, let's add a new method in the Board class to generate a board. The algorithm I use randomly places givens, checks if they are valid and if not removes them and tries again until it has placed enough. This algorithm sucks, but it is fast, we'll add
 a better one late through plug-ins. Next, if we modify the size selection drop-down to contain integers instead of ComboBoxItems then it will be easy to make the “New Game” button functional. We can link into the System namespace in the CLR and use the integer
 type directly from there, in fact we can link into any namespace and use any type!
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">ComboBox</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;BoardSize&quot;</span> <span class="attr">xmlns:s</span><span class="kwrd">=&quot;clr-namespace:System&quot;</span><br>    <span class="attr">ItemTemplate</span> <span class="kwrd">=&quot;{StaticResource BoardSizeTemplate}&quot;</span> <span class="attr">IsEditable</span> <span class="kwrd">=&quot;False&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">ComboBox.SelectedItem</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span>9<span class="kwrd">&lt;/</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">ComboBox.SelectedItem</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span>9<span class="kwrd">&lt;/</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span>16<span class="kwrd">&lt;/</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span>25<span class="kwrd">&lt;/</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span>36<span class="kwrd">&lt;/</span><span class="html">s:Int32</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">ComboBox</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p>Using a data template like this: </p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">DataTemplate</span> <span class="attr">x:Key</span> <span class="kwrd">=&quot;BoardSizeTemplate&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">StackPanel</span> <span class="attr">Orientation</span> <span class="kwrd">=&quot;Horizontal&quot;</span> <span class="attr">FlowDirection</span> <span class="kwrd">=&quot;LeftToRight&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span> <span class="kwrd">=&quot;{Binding}&quot;</span><span class="kwrd">/&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span> <span class="kwrd">=&quot;x&quot;</span><span class="kwrd">/&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Text</span> <span class="kwrd">=&quot;{Binding}&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">StackPanel</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">DataTemplate</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The appearance is identical to the user but it allows the behind the UI to easily work without having to hardcode the items in the list into it. The event handler for the “New Game” button is very simple; the data binding does most of the work:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">void</span> NewGameClicked(<span class="kwrd">object</span> sender, RoutedEventArgs e)<br>{<br>    Board.GameBoard = <span class="kwrd">new</span> Board((<span class="kwrd">int</span>)BoardSize.SelectedItem);<br>    Board.GameBoard.GenerateGame((<span class="kwrd">int</span>)BoardSize.SelectedItem *2);<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Finally, to make the Sudoku game playable, we need to add some triggers to the cell data template:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">DataTemplate.Triggers</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">DataTrigger</span> <span class="attr">Binding</span> <span class="kwrd">=&quot;{Binding IsValid}&quot;</span> <span class="attr">Value</span> <span class="kwrd">=&quot;False&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span> <span class="kwrd">=&quot;Border&quot;</span> <span class="attr">Property</span> <span class="kwrd">=&quot;Background&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;Red&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">DataTrigger</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">DataTrigger</span> <span class="attr">Binding</span> <span class="kwrd">=&quot;{Binding ReadOnly}&quot;</span> <span class="attr">Value</span> <span class="kwrd">=&quot;True&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span> <span class="kwrd">=&quot;Border&quot;</span> <span class="attr">Property</span> <span class="kwrd">=&quot;Background&quot;</span> <span class="attr">Value</span><span class="kwrd">=&quot;Blue&quot;</span><span class="kwrd">/&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">TargetName</span> <span class="kwrd">=&quot;Border&quot;</span> <span class="attr">Property</span><span class="kwrd">=&quot;ContextMenu&quot;</span> <span class="attr">Value</span> <span class="kwrd">=&quot;{x:Null}&quot;</span><span class="kwrd">/&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">DataTrigger</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">DataTemplate.Triggers</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Data triggers perform an action based on the property of a data source, in this case the triggers change the background of the cell depending on whether it's a given cell or not and to mark invalid cell values. The context menu of a read-only cell is also
 removed so its value cannot be altered. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image0092.jpg"><img height="180" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image0091.jpg" width="240" border="0"></a>
</p>
<p>Not that cool looking, but it does the job. In the sample application, I've replaced the solid color fills with better looking effects in the sample app but layering up gradients is just more of the same so I'll move on. I've also added a drop shadow to
 the board, but I did this slightly differently then before. Because adding a drop shadow to a control causes it to render in software-mode, sometimes it's worth it to cheat, especially for large, square controls. I layered an empty panel behind the board and
 gave it a drop shadow. This has the same effect but avoids the need to process the board graphic itself. I also used this trick to in the template for the expander control; I've included the modified version in the download.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image0112.jpg"><img height="180" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image0111.jpg" width="240" border="0"></a>
</p>
<p>Another cool effect you can do with very little code is control reflections. Let's add a reflection to the title text. First, since we want the reflection to follow the title's animation, we need to refactor the animation from the TextBlock to a Grid surrounding
 the text. Then we need to add a rectangle to the grid so that it sits over the text.
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Rectangle</span> <span class="attr">VerticalAlignment</span> <span class="kwrd">=&quot;Top&quot;</span> <span class="attr">HorizontalAlignment</span> <span class="kwrd">=&quot;Left&quot;</span> <br>    <span class="attr">x:Name</span> <span class="kwrd">=&quot;TitleReflect&quot;</span><br>    <span class="attr">Width</span> <span class="kwrd">=&quot;{Binding ElementName=TitleText,Path=ActualWidth}&quot;</span><br>    <span class="attr">Height</span> <span class="kwrd">=&quot;{Binding ElementName=TitleText,Path=ActualHeight}&quot;</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Rectangle.RenderTransform</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">TransformGroup</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">ScaleTransform</span> <span class="attr">CenterY</span><span class="kwrd">=&quot;{Binding ElementName=TitleText,Path=ActualHeight}&quot;</span><br>        <span class="attr">ScaleY</span> <span class="kwrd">=&quot;-1&quot;</span><span class="kwrd">/&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">TranslateTransform</span> <span class="attr">Y</span> <span class="kwrd">=&quot;-10&quot;</span><span class="kwrd">/&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">TransformGroup</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Rectangle.RenderTransform</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;</span><span class="html">Rectangle.OpacityMask</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush</span> <span class="attr">StartPoint</span> <span class="kwrd">=&quot;0,0&quot;</span> <span class="attr">EndPoint</span> <span class="kwrd">=&quot;0,1&quot;</span><span class="kwrd">&gt;</span><br>      <span class="kwrd">&lt;</span><span class="html">LinearGradientBrush.GradientStops</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span> <span class="kwrd">=&quot;#00112233&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;0.3&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">GradientStop</span> <span class="attr">Color</span> <span class="kwrd">=&quot;#a0112233&quot;</span> <span class="attr">Offset</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span><br>      <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush.GradientStops</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">LinearGradientBrush</span><span class="kwrd">&gt;</span><br>  <span class="kwrd">&lt;/</span><span class="html">Rectangle.OpacityMask</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">Rectangle</span><span class="kwrd">&gt;</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The rectangle is flipped and transformed vertically to the correct position using a render transform. Using a render transform as opposed to a layout transform is important because render transforms are evaluated after the controls have been arranged. This
 way the reflection rectangle does actually take up any extra space below the text in the window layout. Also new here is the use of an opacity mask, which is a brush that is used to mask out areas in the control. For each pixel drawn, the opacity value is
 taken from the opacity mask brush, whose other components are ignored. Next, we need to create an event hander for the window's Loaded event in which we hook up the rectangle to the text:
</p>
<p>&nbsp;</p>
<pre class="csharpcode"><span class="kwrd">void</span> WindowLoaded(<span class="kwrd">object</span> sender, RoutedEventArgs e)<br>{<br>    TitleReflect.Fill = <span class="kwrd">new</span> VisualBrush(TitleText);<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>We do this by filling the rectangle with a VisualBrush, which paints an area with a Visual. Since most controls inherit from Visual, this allows you to essentially paint an area with the dynamic image of a control. This can do more than just reflection,
 you could build a magnifier control or even paint other controls on a 3D object. This unification of the graphics system is great example of what's cool about WPF!
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image0132.jpg"><img height="180" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1178193/clip_image0131.jpg" width="240" border="0"></a>
</p>
<p>Well, you can play Sudoku now, but we're still not done! Stay tuned for the next tutorial where I'll be going over:
</p>
<p>· Creating more complex custom controls, inheriting from existing controls, and defining custom properties that can be animated or data bound
</p>
<p>· Updating the UI to be more functional and to have a real timer </p>
<p>· Building a Sudoku solver as a plug-in </p>
<p>· Running solver plug-ins with least privilege </p>
<p>See you next time!</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Lucas-Magder/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:1f0461ac3c714e5488779e7600d7c34b">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-3-Adding-Polish-and-Customizing-Controls</comments>
      <itunes:summary>



&amp;nbsp;
Building Sudoku using Windows Presentation Foundation and XAML, Microsoft&#39;s new declarative programming language. This is the 3rd article from a series of 5 articles and focusses on adding polish and customizing
 controls. 



Lucas Magder


Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free

Software: 
Visual C# 2005 Express Edition&amp;nbsp;.NET Framework&amp;nbsp;3.0 Runtime Components

Windows Vista RTM SDK 
Visual Studio Extensions for the .NET Framework 3.0 November 2006 CTP

Hardware: 
Download: Download (note: Tasos Valsamidis has an updated version that supports
Expression Blend here)
&amp;nbsp;




Note: This article has been updated to work and compile with the RTM version of the Windows SDK.&amp;nbsp;

Welcome to the third part of my Windows Presentation Foundation tutorial! In this tutorial we&#39;ll be adding some cool UI elements to spice up the application we built last time. First, let&#39;s redo the background a little; let&#39;s add a cool pulsating gradient,
 like the Xbox 360:  

 
(This picture is from a random internet search, I need to find an internal one I can use in the real article)
 
Ok. So how we do this? If you&#39;ve scoped out the documentation already you&#39;ll know there is a RadialGradientBrush we can use, but how can we layer multiple brushes, and most importantly how can we animate them? To make this work I&#39;ve replaced the GradientPanel
 style with a new one. The new style uses a DrawingBrush to compose a collection of geometry objects into a single image. To create the desired effect I layered a bunch of rectangles painted with radial gradients like this: 
&amp;lt;DrawingBrush Stretch =&amp;quot;UniformToFill&amp;quot;&amp;gt;  &amp;lt;DrawingBrush.Drawing&amp;gt;    &amp;lt;DrawingGroup&amp;gt;      &amp;lt;GeometryDrawing&amp;gt;        &amp;lt;GeometryDrawing.Brush&amp;gt;          &amp;lt;SolidColorBrush Color =&amp;quot;White&amp;quot;/&amp;gt;        &amp;lt;/GeometryDrawing.Brush&amp;gt;        &amp;lt;GeometryDrawing.Geometry&amp;gt;          &amp;lt;RectangleGeometry Rect=&amp;quot;0,0,1,1&amp;quot;/&amp;gt;        &amp;lt;/GeometryDrawi</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-3-Adding-Polish-and-Customizing-Controls</link>
      <pubDate>Thu, 30 Nov 2006 11:09:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-3-Adding-Polish-and-Customizing-Controls</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1178193_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1178193_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Lucas Magder</dc:creator>
      <itunes:author>Lucas Magder</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-3-Adding-Polish-and-Customizing-Controls/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Puzzle</category>
    </item>
  <item>
      <title>Building a WPF Sudoku Game, Part 2: The Board UI and Validation</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">Building Sudoku using Windows Presentation Foundation and XAML, Microsoft's new declarative programming language. This is the 2nd article from a series of 5 articles and focusses on creating the Board UI and validations.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Lucas Magder</div>
<div class="entry_company"><a></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details">
<div class="entry_details"><strong>Software:</strong> <span class="entry_details_input">
<a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/">Visual C# 2005 Express Edition</a>&nbsp;<a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&amp;displaylang=en">.NET Framework&nbsp;3.0 Runtime Components</a>
<a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7614FE22-8A64-4DFB-AA0C-DB53035F40A0&amp;displaylang=en">
Windows Vista RTM SDK</a> <a class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=f54f5537-cc86-4bf5-ae44-f5a1e805680d&amp;DisplayLang=en">
Visual Studio Extensions for the .NET Framework 3.0 November 2006 CTP</a></span></div>
<strong>Hardware: </strong><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a class="" href="http://channel9.msdn.com/playground/Sandbox/250391-Coding4Fun-Sample-Building-a-WPF-Sudoku-Game-Part-2--The-Board-UI-and-Validation/">Download</a>&nbsp;(note: Tasos Valsamidis has an updated version that
 supports <a class="" href="http://channel9.msdn.com/ShowPost.aspx?PostID=282120">
Expression Blend here</a>)</div>
</td>
</tr>
</tbody>
</table>
</span><span>
<div class="entry_details"><b></b>&nbsp;</div>
<div class="entry_details"><span><strong>Note</strong>: This article has been updated to work and compile with the RTM version of the Windows SDK.</span></span></div>
<p class="MsoNormal"><span>Welcome to the second part of my Windows Presentation Foundation tutorial! If you've missed the first part you probably want to check it out here (link) since we'll be building on what we did last. In this tutorial I'll be covering
 creating a custom control for our Sudoku board and databinding it to the game logic.</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>First, I think it would be a good idea to go over just what databinding in WPF means, since it's used quite differently than in say Windows Forms or MFC. Hopefully this will give more insight in to why the internal classes are designed
 the way they are; you can databind anything but you can only <i>easily</i> databind some things. First off all, despite its name, databinding in no way involves databases, complex schemas, or any boring stuff like that. It's really all about tying your UI
 to your code. We've all written that WinForms or VB code that synchronizes a control like a listbox or treeview with an internal array, collection, or other data structure and we all remember how painful it is. Why!? Why can't the control just use my object
 for data storage instead of its own memory that I have to keep synced? Well, we don't have to worry about that anymore because that's how it works in WPF, in fact, controls only have their own storage if you explicitly request it and you'll find if you write
 clean code you'll almost never need it. So where am I going with this? How does it tie in? Well, if we structure our code correctly, we can have our Sudoku board control automatically display our Sudoku board object and easily enter and validate moves. To
 do this we are going to use a hierarchy of listboxes. Before you think I've gone off the deep end, it's important to note that in WPF listboxes are controls that list
<i>anything</i> not just strings. So, lets start hammering out the data structures by looking at a typical Sudoku board for a 9x9 game:</span></p>
<p>&nbsp;</p>
<div align="center">
<table class="MsoTableGrid" height="462" cellspacing="0" cellpadding="0" width="482" border="1" class="MsoTableGrid">
<tbody>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>5</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>3</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>7</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
</tr>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>6</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>1</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>9</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>5</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
</tr>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>9</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>8</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>6</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
</tr>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>8</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>6</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>3</span></b></p>
</td>
</tr>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>4</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>8</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>3</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>1</span></b></p>
</td>
</tr>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>7</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>2</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>6</span></b></p>
</td>
</tr>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>6</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>2</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>8</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
</tr>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>4</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>1</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>9</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>5</span></b></p>
</td>
</tr>
<tr>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>8</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>&nbsp;</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>7</span></b></p>
</td>
<td class="" width="38">
<p class="MsoNormal" align="center"><b><span>9</span></b></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Actually it's a 3x3 grid of 3x3 grids. But let's abstract this to any size. Starting at the deepest level we have a cell itself.</span></p>
<pre><code>public class Cell<br>{<br>    public bool ReadOnly = false;<br>    public int? Value = null;<br>    public bool IsValid = true;<br>}</code></pre>
<p class="MsoNormal"><span>It's simple, but gets the job done and maintains which cells are part of the original puzzle.
<span>&nbsp;</span>Unfortunately this won't work so well with databinding. First of all, databinding only works on properties, not fields and how can the control know when a property has changed? To make this work we have to implement the
</span><span>INotifyPropertyChanged</span><span> interface and turn the fields into properties like this:</span></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> Cell: INotifyPropertyChanged <br>{<br>    <span class="kwrd">bool</span> readOnlyValue = <span class="kwrd">false</span>;<br>    <span class="kwrd">public</span> <span class="kwrd">bool</span> ReadOnly<br>    {<br>        get<br>        {<br>            <span class="kwrd">return</span> readOnlyValue; <br>        }<br>        set<br>        {<br>            <span class="kwrd">if</span> (readOnlyValue != <span class="kwrd">value</span>)<br>            {<br>                readOnlyValue = <span class="kwrd">value</span>;<br>                <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>) PropertyChanged(<span class="kwrd">this</span>, <br>                    <span class="kwrd">new</span> PropertyChangedEventArgs(<span class="str">&quot;ReadOnly&quot;</span>));<br>            }<br>        }<br>    }<br>    <span class="kwrd">int</span>? valueValue = <span class="kwrd">null</span>;<br>    <span class="kwrd">public</span> <span class="kwrd">int</span>? Value<br>    {<br>        get<br>        {<br>            <span class="kwrd">return</span> valueValue; <br>        }<br>        set<br>        {<br>            <span class="kwrd">if</span> (valueValue != <span class="kwrd">value</span>)<br>            {<br>                valueValue = <span class="kwrd">value</span>;<br>                <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>) PropertyChanged(<span class="kwrd">this</span>, <br>                    <span class="kwrd">new</span> PropertyChangedEventArgs(<span class="str">&quot;Value&quot;</span>));  <br>            }<br>        }<br>    }<br>    <span class="kwrd">bool</span> isValidValue = <span class="kwrd">true</span>;<br>    <span class="kwrd">public</span> <span class="kwrd">bool</span> IsValid<br>    {<br>        get<br>        {<br>            <span class="kwrd">return</span> isValidValue;<br>        }<br>        set<br>        {<br>            <span class="kwrd">if</span> (isValidValue != <span class="kwrd">value</span>)<br>            {<br>                isValidValue = <span class="kwrd">value</span>;<br>                <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>) PropertyChanged(<span class="kwrd">this</span>,<br>                    <span class="kwrd">new</span> PropertyChangedEventArgs(<span class="str">&quot;IsValid&quot;</span>));<br>            }<br>        }<br>    }<br>    <span class="preproc">#region</span> INotifyPropertyChanged Members<br><br>    <span class="kwrd">public</span> <span class="kwrd">event</span> PropertyChangedEventHandler PropertyChanged;<br><br>    <span class="preproc">#endregion</span><br>}<br></pre>
<p class="MsoNormal"><span>Ok, before you run away screaming, bear with me for a second. First, you only have to do this for properties that will be databound then changed after they are initially read. Second, there are other methods such as dependency properties
 that accomplish something similar that I'll discuss later. Dependency properties support animation, metadata, and all sorts other fun stuff but they have more overhead so this way is probably best if you just want the databindings to update. All that's going
 on here is firing off the </span><span>PropertyChanged</span><span> event when one of the properties changes, pretty simple and a good candidate for a code snippet or good old copy and paste.</span></p>
<p class="MsoNormal"><span>Next, let's define the inner grid:</span></p>
<pre><code>public class InnerGrid: INotifyPropertyChanged <br>{<br>    ObservableCollection&lt;ObservableCollection&lt;Cell&gt;&gt; Rows;<br>    public ObservableCollection&lt;ObservableCollection&lt;Cell&gt;&gt; GridRows<br>    {<br>        get<br>        {<br>            return Rows;<br>        }<br>    }</code></pre>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Here we initialize the collections in the inner grid cell and populate then with
</span><span>Cell</span><span>s. What's neat here is that not only can the framework itself use the
</span><span>INotifyPropertyChanged</span><span> interface but so can our code. We are adding a handler to the cell's event in order to revalidate ourselves when one of our child cells is altered.</span></p>
<p>&nbsp;</p>
<pre><code>    public InnerGrid(int size)<br>    {<br>        Rows = new ObservableCollection&lt;ObservableCollection&lt;Cell&gt;&gt;();<br>        for (int i = 0; i &lt; size; i&#43;&#43;)<br>        {<br>            ObservableCollection&lt;Cell&gt; Col = new ObservableCollection&lt;Cell&gt;();<br>            for (int j = 0; j &lt; size; j&#43;&#43;)<br>            {<br>                Cell c = new Cell();<br>                c.PropertyChanged &#43;= new PropertyChangedEventHandler(c_PropertyChanged); <br>                Col.Add(c);  <br>            }<br>            Rows.Add(Col);  <br>        }<br>    }<br><br>    void c_PropertyChanged(object sender, PropertyChangedEventArgs e)<br>    {<br>        if (e.PropertyName == &quot;Value&quot;)<br>        {<br>            bool valid = CheckIsValid();<br><br>            foreach (ObservableCollection&lt;Cell&gt; r in Rows)<br>            {<br>                foreach (Cell c in r)<br>                {<br>                    c.IsValid = valid;<br>                }<br>            }<br>           <br>            isValidValue = valid;<br>            if (PropertyChanged != null) <br>		PropertyChanged(this, new PropertyChangedEventArgs(&quot;IsValid&quot;));  <br>        }<br>    }</code></pre>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Here we cache the result of the last </span><span>IsValid</span><span> value.<span>&nbsp;
</span>We can do this because we now have a notification event that is fired whenever there is a possibility of that value changing.</span></p>
<pre><code>    bool isValidValue = true;<br>    public bool IsValid<br>    {<br>        get<br>        {<br>            return isValidValue; <br>        }<br>    }</code></pre>
And finally, here we have a private validation method that actually does the work. This method simply checks if there are any duplicate cells in our inner grid square.
<pre><code>    private bool CheckIsValid()<br>    {<br>        bool[] used = new bool[Rows.Count * Rows.Count];      <br>        foreach (ObservableCollection&lt;Cell&gt; r in Rows)<br>        {<br>            foreach (Cell c in r)<br>            {<br>                if (c.Value.HasValue)<br>                {<br>                    if (used[c.Value.Value-1])<br>                    {<br>                        return false; //this is a duplicate<br>                    }<br>                    else<br>                    {<br>                        used[c.Value.Value-1] = true; <br>                    }<br>                }<br>             }<br>        }<br>        return true;<br>    }<br>    #region INotifyPropertyChanged Members<br>    public event PropertyChangedEventHandler PropertyChanged;<br>    #endregion<br>}</code></pre>
<p>&nbsp;</p>
<p class="MsoNormal"><span>As you can see I've defined the class to store its data in collections of type
</span><span>ObservableCollection</span><span>, this is because </span><span>ObservableCollection</span><span> already implements
</span><span>INotifyCollectionChanged</span><span> and </span><span>INotifyPropertyChanged</span><span> and that's great because I'm lazy.
</span><span>I've essentially defined an array of arrays containing the cells in the inner grid. This works great for databinding but it kind of sucks to access the cells from C# code. To solve this I also added an indexer to the class like so:</span></p>
<p>&nbsp;</p>
<pre><code>public Cell this[int row, int col]<br>{<br>    get<br>    {<br>        if (row &lt; 0 || row &gt;= Rows.Count) <br>	    throw new ArgumentOutOfRangeException(&quot;row&quot;, row, &quot;Invalid Row Index&quot;);<br>        if (col &lt; 0 || col &gt;= Rows.Count) <br>            throw new ArgumentOutOfRangeException(&quot;col&quot;, col, &quot;Invalid Column Index&quot;);<br>        return Rows[row][col];<br>    }<br>}</code></pre>
<p class="MsoNormal"><span>The </span><span>Board</span><span> class is extremely similar to the<span>&nbsp;
</span></span><span>InnerGrid</span><span> except it stores </span><span>InnerGrid</span><span>s instead of
</span><span>Cell</span><span>s so I wont list the entire thing here (you can check it out, and the
</span><span>IsValid</span><span> implementations if you download the source). I also changed the constructor and the indexer to drill-down through the two levels of containers. If you're not sure on how this would work you should probably check out the source
 before you continue just so we're on the same page. <span></span></span></p>
<p class="MsoNormal"><span>Ok, so now we've written all these class it's time to hit the XAML and make a custom control. So we need to add a new WinFX user control to the project. I've modified some of the properties of the user control, but basically we start
 with this:</span></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">UserControl</span> <span class="attr">x:Class</span><span class="kwrd">=&quot;SudokuFX.SudokuBoard&quot;</span><br>    <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span><br>    <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span><br>    <br>    <span class="attr">HorizontalAlignment</span> <span class="kwrd">=&quot;Stretch&quot;</span><br>    <span class="attr">HorizontalContentAlignment</span> <span class="kwrd">=&quot;Stretch&quot;</span><br>    <span class="attr">VerticalAlignment</span> <span class="kwrd">=&quot;Stretch&quot;</span><br>    <span class="attr">VerticalContentAlignment</span> <span class="kwrd">=&quot;Stretch&quot;</span><br>    <span class="attr">Background</span><span class="kwrd">=&quot;{StaticResource ControlGradient}&quot;</span><br>    <span class="attr">Foreground</span><span class="kwrd">=&quot;White&quot;</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;</span><span class="html">UserControl</span><span class="kwrd">/&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p class="MsoNormal"><span>The basic idea here is that we'll use a series of nested
</span><span>ItemsControl</span><span>s to display our board. An </span><span>ItemsControl</span><span> is a generic panel that contains any number of other items, for example the
</span><span>ListBox</span><span> control inherits from </span><span>ItemsControl</span><span> and adds support for things like scrolling and selection but we don't need those. We define the outer control that holds the rows on inner squares.</span></p>
<p>&nbsp;</p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">ItemsControl</span>  <span class="attr">ItemTemplate</span> <span class="kwrd">=&quot;{StaticResource OuterRowTemplate}&quot;</span> <br><span class="attr">ItemsSource</span> <span class="kwrd">=&quot;{Binding Path=GridRows}&quot;</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;MainList&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">ItemsControl.ItemsPanel</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">ItemsPanelTemplate</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">UniformGrid</span> <span class="attr">Columns</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">ItemsPanelTemplate</span><span class="kwrd">&gt;</span> <br>    <span class="kwrd">&lt;/</span><span class="html">ItemsControl.ItemsPanel</span><span class="kwrd">&gt;</span> <br><span class="kwrd">&lt;/</span><span class="html">ItemsControl</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p class="MsoNormal"><span>Ok, so this is where the fun starts. Every item that can be databound has a
</span><span>DataContext</span><span> property that specifies the object it's bound to. We'll set this later from C# code but it's important to know that it's there because it's the basis for the binding syntax. When specifying a data binding, if no source
 is explicitly set the data context is used. In this code </span><span>ItemsSource</span><span>, the collection containing the child items is bound to the
</span><span>GridRows</span><span> property of the data context, which will eventually be an instance of our
</span><span>Board</span><span> class.</span><span></span></p>
<p class="MsoNormal"><span>Another thing of note is the use of the </span><span>UniformGrid</span><span> class. By default the items control lays out items by stacking them from top to bottom. Instead of this behavior we would rather have the items stacked
 in a single column and stretched to fill the entire space evenly. The </span><span>UniformGrid</span><span> container does this and so I've substituted it for the default using the
</span><span>ItemsPanel</span><span> property, but in general you could use any kind of standard or custom panel here, for example to arrange the items in a ring. Also you'll notice
</span><span>ItemTemplate</span><span> points to a resource:</span></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">DataTemplate</span> <span class="attr">x:Key</span> <span class="kwrd">=&quot;OuterRowTemplate&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">ItemsControl</span> <span class="attr">ItemsSource</span> <span class="kwrd">=&quot;{Binding}&quot;</span> <br><span class="attr">	ItemTemplate</span> <span class="kwrd">=&quot;{StaticResource InnerGridTemplate}&quot;</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">ItemsControl.ItemsPanel</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">ItemsPanelTemplate</span><span class="kwrd">&gt;</span><br>                <span class="kwrd">&lt;</span><span class="html">UniformGrid</span> <span class="attr">Rows</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">/&gt;</span><br>            <span class="kwrd">&lt;/</span><span class="html">ItemsPanelTemplate</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">ItemsControl.ItemsPanel</span><span class="kwrd">&gt;</span>  <br>    <span class="kwrd">&lt;/</span><span class="html">ItemsControl</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">DataTemplate</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p class="MsoNormal"><span>A data template describes how each item in the source list is interpreted as an item in the
</span><span>ItemsControl</span><span>. The data context is the current item, which is the list of blocks in the row, which we bind to the
</span><span>ItemsSource</span><span> of another </span><span>ItemsControl</span><span>. Currently, we have a vertical list of horizontal lists. Then, we do this all over again for the cells inside each block. You can also add other controls in the template
 and I've added a border to the </span><span>InnerGridTemplate</span><span> to show the boundary between cells.</span></p>
<p class="MsoNormal"><span>Finally, we reach the innermost data template, the one for the
</span><span>Cell</span><span>:</span></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">DataTemplate</span> <span class="attr">x:Key</span> <span class="kwrd">=&quot;CellTemplate&quot;</span><span class="kwrd">&gt;</span><br>    <span class="kwrd">&lt;</span><span class="html">Border</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;Border&quot;</span> <span class="attr">BorderBrush</span> <span class="kwrd">=&quot;DimGray&quot;</span> <span class="attr">BorderThickness</span> <span class="kwrd">=&quot;1&quot;</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">HorizontalAlignment</span> <span class="kwrd">=&quot;Center&quot;</span> <span class="attr">VerticalAlignment</span> <span class="kwrd">=&quot;Center&quot;</span> <br>	     <span class="attr">FontWeight</span> <span class="kwrd">=&quot;Bold&quot;</span> <span class="attr">FontSize</span> <span class="kwrd">=&quot;16&quot;</span> <span class="attr">Text</span> <span class="kwrd">=&quot;{Binding Path=Value}&quot;</span><span class="kwrd">/&gt;</span><br>    <span class="kwrd">&lt;/</span><span class="html">Border</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">DataTemplate</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Here, we draw a lighter border around the cell then display the
</span><span>Value</span><span> property of the current cell, which is the data context of the template. Finally, we want the entire thing to stay square as it resizes. Normally this would require a few lines of C# code but thanks to the insanely flexible databinding
 available in WPF we can do this with no code! All you need to do it to bind the </span>
<span>Width</span><span> property of the </span><span>UserControl</span><span> to its
</span><span>ActualHeight</span><span> property, which contains the final height of the control after it's been laid out. We can do this with the
</span><span>RelativeSource</span><span> property, to bind to object itself instead of the data context. This sounds complicated but it's actually really simple:</span></p>
<p>&nbsp;</p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="attr">Width</span><span class="kwrd">=&quot;{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}&quot;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Now, we need to put the control onto our main window. First, we need to map out C# namespace, SudokuFX, to an XML namespace that we can reference from XAML. To do this we define a new namespace in the document root using this syntax:</span></p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="attr">xmlns:clr</span><span class="kwrd">=&quot;clr-namespace:SudokuFX&quot;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Where the </span><span>xmlns:clr</span><span> indicates the xml namespace. “clr” is in no way special an I could have called it</span></p>
<p class="MsoNormal"><span>xmlns:stuff</span><span>=</span><span>&quot;<span>clr-namespace:SudokuFX</span>&quot;</span><span> or whatever I wanted. Once that's done I can use my control just like any other. I've replaced the stand-in canvas with our custom control tag:</span></p>
<p class="MsoNormal"><span></span></p>
<p>&nbsp;</p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">clr:SudokuBoard</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">=&quot;Stretch&quot;</span> <span class="attr">VerticalAlignment</span><span class="kwrd">=&quot;Stretch&quot;</span> <span class="attr">Margin</span><span class="kwrd">=&quot;5&quot;</span><span class="kwrd">/&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>If you run the app now you should see this:</p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999781/sudoku_2_2.gif" border="0"></p>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Not that amazing, but we haven't bound any data yet. We can modify the C# component of the control to add a data source:</span></p>
<pre><code>public partial class SudokuBoard : UserControl<br>{<br>    public Board GameBoard = new Board(9);<br>    public SudokuBoard()<br>    {<br>        InitializeComponent();<br>        MainList.DataContext = GameBoard; <br>    }<br>}</code></pre>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Now, it should look more like this (I've added the numbers just to show that it works):</span></p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999781/sudoku_2_3.gif" border="0"></p>
<p>&nbsp;</p>
<p class="MsoNormal"><span>You can see it rebuilds correctly to match the data, when I change from a 9x9 grid to a 16x16 grid:</span></p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999781/sudoku_2_4.gif" border="0"></p>
<p>&nbsp;</p>
<p class="MsoNormal"><span>Ok, so now that we've got that working, to close of this tutorial lets add the ability to change the numbers on the board. I've added a new collection property to the
</span><span>Cell</span><span> class called </span><span>PossibleValues</span><span> that is populated with all the possible values when the class is created. Let's add a context menu that's bound to this new property so that the cell values can be changed.
 To do this the XAML needs to be changed like this:</span></p>
<p>&nbsp;</p>
<pre><code></code></pre>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">DataTemplate</span> <span class="attr">x:Key</span> <span class="kwrd">=&quot;CellTemplate&quot;</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;</span><span class="html">Border</span> <span class="attr">x:Name</span> <span class="kwrd">=&quot;Border&quot;</span> <span class="attr">BorderBrush</span> <span class="kwrd">=&quot;DimGray&quot;</span> <span class="attr">BorderThickness</span> <span class="kwrd">=&quot;1&quot;</span> <span class="attr">Background</span><span class="kwrd">=&quot;#00112233&quot;</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">TextBlock</span> <span class="attr">Focusable</span> <span class="kwrd">=&quot;False&quot;</span> <span class="attr">HorizontalAlignment</span> <span class="kwrd">=&quot;Center&quot; </span><span class="attr">VerticalAlignment</span> <span class="kwrd">=&quot;Center&quot;<br></span>			<span class="attr">FontWeight</span> <span class="kwrd">=&quot;Bold&quot;</span> <span class="attr">FontSize</span> <span class="kwrd">=&quot;16&quot; </span><span class="attr">Text</span> <span class="kwrd">=&quot;{Binding Path=Value}&quot;</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;/</span><span class="html">TextBlock</span><span class="kwrd">&gt;</span><br>        <span class="kwrd">&lt;</span><span class="html">Border.ContextMenu</span><span class="kwrd">&gt;</span><br>            <span class="kwrd">&lt;</span><span class="html">ContextMenu</span><span class="kwrd">&gt;</span><br>                <span class="kwrd">&lt;</span><span class="html">ContextMenu.ItemContainerStyle</span><span class="kwrd">&gt;</span><br>                    <span class="kwrd">&lt;</span><span class="html">Style</span> <span class="attr">TargetType</span> <span class="kwrd">=&quot;{x:Type MenuItem}&quot;</span><span class="kwrd">&gt;</span><br>                        <span class="kwrd">&lt;</span><span class="html">Setter</span> <span class="attr">Property</span> <span class="kwrd">=&quot;Template&quot;</span><span class="kwrd">&gt;</span><br>                            <span class="kwrd">&lt;</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span><br>                                <span class="kwrd">&lt;</span><span class="html">ControlTemplate</span> <span class="attr">TargetType</span> <span class="kwrd">=&quot;{x:Type MenuItem}&quot;</span><span class="kwrd">&gt;</span><br>                                    <span class="kwrd">&lt;</span><span class="html">ContentPresenter</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;Header&quot; </span><span class="attr">ContentSource</span><span class="kwrd">=&quot;Header&quot;<br></span>								<span class="attr">RecognizesAccessKey</span><span class="kwrd">=&quot;True&quot;</span> <span class="kwrd">/&gt;</span><br>                                <span class="kwrd">&lt;/</span><span class="html">ControlTemplate</span><span class="kwrd">&gt;</span><br>                            <span class="kwrd">&lt;/</span><span class="html">Setter.Value</span><span class="kwrd">&gt;</span> <br>                        <span class="kwrd">&lt;/</span><span class="html">Setter</span><span class="kwrd">&gt;</span><br>                    <span class="kwrd">&lt;/</span><span class="html">Style</span><span class="kwrd">&gt;</span><br>                <span class="kwrd">&lt;/</span><span class="html">ContextMenu.ItemContainerStyle</span><span class="kwrd">&gt;</span><br>                <span class="kwrd">&lt;</span><span class="html">ListBox</span> <span class="attr">BorderThickness</span><span class="kwrd">=&quot;0&quot;</span> <span class="attr">Width</span> <span class="kwrd">=&quot;35&quot;</span> <span class="attr">Margin</span> <span class="kwrd">=&quot;0&quot;</span> <br>				<span class="attr">SelectedItem</span> <span class="kwrd">=&quot;{Binding Path=Value,Mode=TwoWay}&quot;<br></span><span class="attr">				HorizontalAlignment</span> <span class="kwrd">=&quot;Stretch&quot;</span> <span class="attr">VerticalAlignment</span> <span class="kwrd">=&quot;Stretch&quot; <br></span><span class="attr">				DataContext</span> <span class="kwrd">=&quot;{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}&quot;</span> <br>				<span class="attr">ItemsSource</span><span class="kwrd">=&quot;{Binding Path=PossibleValues}&quot;</span><span class="kwrd">/&gt;</span><br>            <span class="kwrd">&lt;/</span><span class="html">ContextMenu</span><span class="kwrd">&gt;</span> <br>        <span class="kwrd">&lt;/</span><span class="html">Border.ContextMenu</span><span class="kwrd">&gt;</span>  <br>    <span class="kwrd">&lt;/</span><span class="html">Border</span><span class="kwrd">&gt;</span><br><span class="kwrd">&lt;/</span><span class="html">DataTemplate</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">
<!--
.csharpcode
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{margin:0em;
	width:100%;
	background-color:#f4f4f4}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p class="MsoNormal"><span>The key here is the binding of the listbox to our data source. Because the context menu exists in a separate hierarchy the data context isn't automatically inherited. We can work around this by binding the new data context to the
 data content of the parent element just outside our sub-hierarchy. To do this we use the
</span><span>RelativeSource</span><span> syntax to access our </span><span>TemplatedParent</span><span>. Next, we bind the
</span><span>ItemsSource</span><span> property to the new property, which populates the listbox, and then we bind the
</span><span>SelectedItem</span><span> property to the object's Value property. Because we specify a two-way binding, when the value of Value changes, so will the selected item in the listbox, and, when the use selects a new item through the UI, Value will
 updated also. A listbox is needed because a menu doesn't have the capability to retain item selections. To work around this I added the listbox to the menu as a single item, and then altered the
</span><span>MenuItem</span><span> Template to remove all padding and selection logic. I haven't covered altering control templates yet, so don't worry about how exactly that part of the code works, we'll revisit it in the next tutorial.
</span></p>
<p class="MsoNormal"><span>Now, if you run the application, you'll see that you can edit the displayed grid:</span></p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999781/sudoku_2_5.gif" border="0"></p>
<p class="MsoNormal"><span>This is really cool because, essentially, there is no code that ties the internal data classes to our UI! The UI automatically and dynamically displays and edits an instance of our custom class. How awesome is that?</span></p>
<p class="MsoNormal"><span>Don't worry, we're not done yet! Come back for my next article were we take a break from data and spiff up the coolness of the app's look and feel. I'll be covering cool stuff like:&nbsp;</span></p>
<ul type="disc">
<li class="MsoNormal"><span>Automatically selecting data templates based on properties of the object</span>
</li><li class="MsoNormal"><span>Modifying control templates to completely customize the look, and operation of a control</span>
</li><li class="MsoNormal"><span>Adding animations</span> </li><li class="MsoNormal"><span>Automatically starting and stopping animations and altering objects based on UI events or other conditions</span>
</li><li class="MsoNormal"><span>Adding reflections and other imagery based on existing controls</span></li></ul>
<p class="MsoNormal"><span>See you next time!</span></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Lucas-Magder/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:3c9adeadd3a14d329b129e7600d9155a">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-2-The-Board-UI-and-Validation</comments>
      <itunes:summary>



&amp;nbsp;
Building Sudoku using Windows Presentation Foundation and XAML, Microsoft&#39;s new declarative programming language. This is the 2nd article from a series of 5 articles and focusses on creating the Board UI and validations.



Lucas Magder


Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free

Software: 
Visual C# 2005 Express Edition&amp;nbsp;.NET Framework&amp;nbsp;3.0 Runtime Components

Windows Vista RTM SDK 
Visual Studio Extensions for the .NET Framework 3.0 November 2006 CTP
Hardware: 
Download: Download&amp;nbsp;(note: Tasos Valsamidis has an updated version that
 supports 
Expression Blend here)





&amp;nbsp;
Note: This article has been updated to work and compile with the RTM version of the Windows SDK.
Welcome to the second part of my Windows Presentation Foundation tutorial! If you&#39;ve missed the first part you probably want to check it out here (link) since we&#39;ll be building on what we did last. In this tutorial I&#39;ll be covering
 creating a custom control for our Sudoku board and databinding it to the game logic. 
&amp;nbsp; 
First, I think it would be a good idea to go over just what databinding in WPF means, since it&#39;s used quite differently than in say Windows Forms or MFC. Hopefully this will give more insight in to why the internal classes are designed
 the way they are; you can databind anything but you can only easily databind some things. First off all, despite its name, databinding in no way involves databases, complex schemas, or any boring stuff like that. It&#39;s really all about tying your UI
 to your code. We&#39;ve all written that WinForms or VB code that synchronizes a control like a listbox or treeview with an internal array, collection, or other data structure and we all remember how painful it is. Why!? Why can&#39;t the control just use my object
 for data storage instead of its own memory that I have to keep synced? Well, we don&#39;t have to worry about that anymore because that&#39;s how it works in WPF, in fact, controls only have their own storage if you </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-2-The-Board-UI-and-Validation</link>
      <pubDate>Mon, 06 Nov 2006 11:46:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-2-The-Board-UI-and-Validation</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/999781_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/999781_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Lucas Magder</dc:creator>
      <itunes:author>Lucas Magder</itunes:author>
      <slash:comments>14</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-2-The-Board-UI-and-Validation/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Puzzle</category>
    </item>
  <item>
      <title>Building a WPF Sudoku Game, Part 1: Introduction to WPF and XAML</title>
      <description><![CDATA[<span id="c4fmetadata">
<table border="0" cellspacing="0" cellpadding="1" width="100%">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">Building Sudoku using Windows Presentation Foundation and XAML, Microsoft's new declarative programming language. This is the 1st article from a series of 5 articles and focusses on introducing WPF and XAML.</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Lucas Magder</div>
<div class="entry_company"><a></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://www.microsoft.com/express/">Visual C#&nbsp;2008 Express Edition</a></span></div>
<div class="entry_details"><strong>Hardware: </strong>None<span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a href="http://channel9.msdn.com/playground/Sandbox/250390-Coding4Fun-Sample-Building-a-WPF-Sudoku-Game-Part-1--Introduction-to-WPF-and-XAML/">Download</a> (note: Tasos Valsamidis has an updated version that supports
<a href="http://channel9.msdn.com/ShowPost.aspx?PostID=282120">Expression Blend here</a>)</div>
</td>
</tr>
</tbody>
</table>
</span>
<p><span><strong>Note</strong>: This article has been updated to work and compile with the RTM version of the Windows SDK.</span></p>
<p><span>Whenever I want to learn something new I find that just working through a tutorial is much easier and less painful then reading the documentation cold and I assume most people feel the same way, because come on, do you actually read the instructions
 for something before you try to use it? I sure don't. To this end, I've decided the jump right into the action and walk though building a Windows Presentation Foundation application right away and since this is Coding4Fun and since, let's face it, the world
 has enough enterprise-web 2.0-data-portal-dodads, were going to make a game.<span>&nbsp;
</span>Unfortunately, I don't think it's realistic to jump right into making Halo 3 here, so I figured a more bite-sized game might be in order, something we might actually finish by the end of these tutorials, like say a Sudoku game.
<span>&nbsp;</span>(Hey, the upside is you might actually get away with playing Sudoku at work). Ok so what do we need to get started? (Install in this order)</span></p>
<p class="MsoNormal"><span></span></p>
<ul type="disc">
<li class="MsoNormal"><span>Visual C# 2005 Express Edition (Grab it for free at <a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/">
http://msdn.microsoft.com/vstudio/express/visualcsharp/</a>!)<span>&nbsp; </span></span></li><li class="MsoNormal"><span>WinFX February 2006 CTP (Grab it at <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=F51C4D96-9AEA-474F-86D3-172BFA3B828B&amp;displaylang=en">
http://www.microsoft.com/downloads/details.aspx?FamilyId=F51C4D96-9AEA-474F-86D3-172BFA3B828B&amp;displaylang=en</a>)</span>
</li><li class="MsoNormal"><span>Windows SDK February 2006 CTP (Grab it at <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=9BE1FC7F-0542-47F1-88DD-61E3EF88C402&amp;displaylang=en#filelist">
http://www.microsoft.com/downloads/details.aspx?FamilyId=9BE1FC7F-0542-47F1-88DD-61E3EF88C402&amp;displaylang=en#filelist</a>)</span>
</li><li class="MsoNormal"><span>Visual Studio Extensions for WinFX February 2006 CTP (Grab it at
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=AD0CE56E-D7B6-44BC-910D-E91F3E370477&amp;displaylang=en">
http://www.microsoft.com/downloads/details.aspx?FamilyId=AD0CE56E-D7B6-44BC-910D-E91F3E370477&amp;displaylang=en</a>)</span><span>&nbsp;</span></li></ul>
<p class="MsoNormal"><span>You also need to be running Windows XP SP2, Windows Server 2003 SP1, or the Vista February CTP.</span></p>
<p class="MsoNormal"><span>Of course, I just happened to have all that installed on my workstation (yeah right). But now that everything is loaded up lets get started. Fire up VC#, create a new project and select “WinFX Windows Application.” (If you can't see
 this item you should make sure you've installed the Visual Studio Extensions since this is one of the things they add.). I entered “SudokuFX” as the project name, and that's what you'll see in the screenshots, but it's up to you what you call it. Right now
 you should be starring at this:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Window</span><span> </span><span>x:Class</span><span>=</span><span>&quot;<span>SudokuFX.Window1</span>&quot;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>xmlns</span><span>=</span><span>&quot;<span>http://schemas.microsoft.com/winfx/2006/xaml/presentation</span>&quot;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>xmlns:x</span><span>=</span><span>&quot;<span>http://schemas.microsoft.com/winfx/2006/xaml</span>&quot;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span></span><span>Title</span><span>=</span><span>&quot;<span>SudokuFX</span>&quot;<span>
</span><span>Height</span><span>=</span>&quot;<span>300</span>&quot;<span> </span><span>Width</span><span>=</span>&quot;<span>300</span>&quot;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Grid</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>Grid</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&lt;/</span><span>Window</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>This is XAML, Microsoft's new declarative programming language. Classes in XAML can have both code (C# or VB.NET) and declarative (XAML) components.<span>&nbsp;
</span>The </span><span>x:Class</span><span> attribute of the </span><span>Window</span><span> tag specifies the name of C# component of the class we are defining. The C# part should look like this:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>namespace</span><span> SudokuFX</span></p>
<p class="MsoNormal"><span>{</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span><span>public</span> <span>partial</span>
<span>class</span> <span>Window1</span> : <span>Window</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>public</span> Window1()</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>InitializeComponent();</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p class="MsoNormal"><span>}</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>When the program is compiled and run the two halves combine together to create a complete
</span><span>Window1</span><span> class, which derives from the </span><span>System.Windows.Window</span><span> class provided by WinFX. The only other non-obvious thing you need to know here is that all the objects declared in XAML can be accessed from code
 or vice-versa. In fact, you can write a class using the same API with no XAML at all! The nested elements are placed into collection stored as a property on their parent called
</span><span>Children</span><span>, or in object that can contain only one other object they are assigned to the
</span><span>Content</span><span> property. So in other words this XAML code creates an instance of
</span><span>Grid </span><span>and places it in the window's </span><span>Content</span><span> property.</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>So, how do we go about laying out the application? Well basically the goal layout is to have a title at the top, the game menu down the left, similar to the “tasks” pane in Windows explorer, the game timing info on the right, the
 move history on the bottom, and the board in the center. Of course this should all be resolution independent and dynamically resize and flow. (If you've used Windows Forms before, the sweat might be already beading on your forehead as your migraine develops,
 but don't worry, dynamic resizing and flow is the <u>default.</u>) The best container for the job is the obviously-named
</span><span>DockPanel</span><span>. The </span><span>DockPanel</span><span> is a container control that arranges it children based which side they are attached to; the last element added is then used to fill the remaining space. For example, replace the
</span><span>Grid</span><span> tag with:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>DockPanel</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>TextBlock</span><span>
</span><span>Background</span><span>=</span><span>&quot;<span>Red</span>&quot;<span> </span>
<span>DockPanel.Dock</span><span> =</span>&quot;<span>Top</span>&quot;<span> </span><span>FontSize
</span><span>=</span>&quot;<span>36</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span>Sudoku</span></p>
<p class="MsoNormal"><span>&lt;/</span><span>TextBlock</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>StackPanel</span><span>
</span><span>Background</span><span>=</span><span>&quot;<span>Green</span>&quot;<span> </span>
<span>DockPanel.Dock</span><span> =</span>&quot;<span>Left</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>A<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>StackPanel</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>StackPanel</span><span>
</span><span>Background</span><span>=</span><span>&quot;<span>Blue</span>&quot;<span> </span>
<span>DockPanel.Dock</span><span> =</span>&quot;<span>Right</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>B<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>StackPanel</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>ListBox</span><span>
</span><span>Background</span><span> =</span><span>&quot;<span>Gray</span>&quot;<span> </span>
<span>DockPanel.Dock</span><span>=</span>&quot;<span>Bottom</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>StackPanel</span><span>
</span><span>Background</span><span> =</span><span>&quot;<span>Yellow</span>&quot;<span>/&gt; </span>
</span></p>
<p class="MsoNormal"><span>&lt;/</span><span>DockPanel</span><span>&gt;</span><span></span></p>
<p class="MsoNormal"><u><span><span>&nbsp;</span></span></u></p>
<p class="MsoNormal"><span>The </span><span>DockPanel.Dock</span><span> syntax is used to refer to a per-child but container-specific property. Another example of this is the
</span><span>Canvas.Left</span><span> property, which is used with elements inside a
</span><span>Canvas</span><span>, a container control that allows you to explicitly position elements. The
</span><span>StackPanel</span><span> container arranges its children in vertical or horizontal stack, going either up or down or left or right. Right now I've added some buttons just pad out the panels so they don't shrink away to nothing and some garishly
 horrible background colors we'll remove later so it's evident exactly how things are laid out. If you compile and run the program you get this monstrosity:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&nbsp;<img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999502/sudoku1_1.png" width="300" height="302"></span></p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal"><span>Ok, now its time to grind out some code to get a basic UI going. First lets layout the left panel: there's going to be the main menu and the new game settings and lets throw them in expander controls just incase anyone who uses our
 program runs at 800x600 (It's frightening I know, but I've seen it). </span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>StackPanel</span><span> </span><span>DockPanel.Dock</span><span> =</span><span>&quot;<span>Left</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span>&lt;</span><span>Expander</span><span> </span><span>IsExpanded</span><span> =</span><span>&quot;<span>True</span>&quot;<span>
</span><span>Header</span><span> =</span>&quot;<span>Main Menu</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>StackPanel</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>New Game<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>Load Game<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>Save Game<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>Quit<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>StackPanel</span><span>&gt;
</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>Expander</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Expander</span><span>
</span><span>IsExpanded</span><span> =</span><span>&quot;<span>True</span>&quot;<span> </span>
<span>Header</span><span> =</span>&quot;<span>New Game Settings</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>StackPanel</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>TextBlock</span><span>&gt;</span><span>Board Size:<span>&lt;/</span><span>TextBlock</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>ComboBox</span><span>
</span><span>IsEditable</span><span> =</span><span>&quot;<span>False</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>ComboBoxItem</span><span>
</span><span>IsSelected </span><span>=</span><span>&quot;<span>True</span>&quot;<span>&gt;</span>9x9<span>&lt;/</span><span>ComboBoxItem</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>ComboBoxItem</span><span>&gt;</span><span>16x16<span>&lt;/</span><span>ComboBoxItem</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>ComboBoxItem</span><span>&gt;</span><span>25x25<span>&lt;/</span><span>ComboBoxItem</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>ComboBoxItem</span><span>&gt;</span><span>36x36<span>&lt;/</span><span>ComboBoxItem</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>ComboBox</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>StackPanel</span><span>&gt;
</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>Expander</span><span>&gt;
</span></p>
<p class="MsoNormal"><span>&lt;/</span><span>StackPanel</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>This gives you:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span></span></p>
<p class="MsoNormal"><span><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999502/sudoku1_2.png" width="156" height="174">&nbsp;</span></p>
<p class="MsoNormal"><span></span>&nbsp;</p>
<p class="MsoNormal"><span>Ok, so maybe that doesn't look too awesome right now, but wait there's more the come! After fleshing out the rest of the UI in similar fashion and adding a dummy image for the board (we'll make the board in a future tutorial) we get
 this:</span></p>
<p class="MsoNormal"><span></span>&nbsp;</p>
<p class="MsoNormal"><span><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999502/sudoku1_3.png" width="500" height="409">&nbsp;</span></p>
<p class="MsoNormal"><span>&nbsp;</span><br clear="all">
<span></span></p>
<p class="MsoNormal"><span>Now, how do we improve the look and feel of this UI? Well, one way would be to tweak all the properties of the controls individually to make them look better; another would be to use some kind of skinning. Unfortunately, these techniques
 add clutter to your code and are difficult to maintain, what we can use instead is WPF's notion of styles. WPF makes it quite easy to customize controls across a given scope, for example: the application as a whole, a particular dialog, or a single container,
 by defining a new set of default property values. You can do this by adding styles to the
</span><span>Resources</span><span> collection of another object. In XAML, if you want to assign a more complex object or collection of objects to a property you can expand the property out from the
</span><span>Property</span><span>=</span><span>&quot;</span><span>Value</span><span>&quot;
</span><span>syntax to the </span><span><span>&nbsp;</span></span><span></span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Object.Property</span><span>&gt;</span><span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>&lt;</span><span>ValueObject</span><span>/&gt;</span><span></span></p>
<p class="MsoNormal"><span>&lt;/</span><span>Object.Property</span><span>&gt;</span><span></span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>syntax. For example, this code assigns the color blue as the background color for all buttons in the application, unless it is explicitly set otherwise:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Application.Resources</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Style</span><span> </span>
<span>TargetType</span><span> =</span><span>&quot;<span>{x:Type Button}</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter</span><span>
</span><span>Property</span><span> =</span><span>&quot;<span>Background</span>&quot;<span> </span>
<span>Value</span><span> =</span>&quot;<span>Blue</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>Style</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&lt;/</span><span>Application.Resources</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Styles can also be named using the </span><span>x:Key</span><span> property. The reason why
</span><span>x:Key </span><span>is used instead of </span><span>x:Name</span><span> is because
</span><span>&lt;</span><span>Application.Resources</span><span>&gt; </span><span>is actually a list of key-value pairs. For example we could define:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Application.Resources</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Style</span><span> </span>
<span>x:Key</span><span> =</span><span>&quot;<span>BlueButton</span>&quot;<span> </span><span>TargetType</span><span> =</span>&quot;<span>{x:Type Button}</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter</span><span>
</span><span>Property</span><span> =</span><span>&quot;<span>Background</span>&quot;<span> </span>
<span>Value</span><span> =</span>&quot;<span>Blue</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>Style</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&lt;/</span><span>Application.Resources</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>This creates a style which only applies to certain buttons, buttons that reference it with their
</span><span>Style</span><span> property. For example:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Button</span><span> </span><span>Style</span><span>=</span><span>&quot;<span>{StaticResource BlueButton}</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>You can also define resources (there are also other types than styles) inside windows, panels, or other objects that have a
</span><span>Resources</span><span> property. When code references a resource a search is made outwards up to the application level thus styles or other resources defined in
</span><span>&lt;</span><span>Window.Resources</span><span>&gt;</span><span>, for example, only apply inside that window.</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>So far I haven't explained the brace notation I've been using. Essentially, braces are used to declare references to other object but not instantiate them. For example,
</span><span>{x:Type Button} </span><span>refers to the </span><span>Button</span><span> class, while
</span><span>{StaticResource BlueButton}</span><span> searches the resource hierarchy for the item with the key “BlueButton”. The
</span><span>StaticResource</span><span> directive indicates that this search is to be carried out when the object is first created, but
</span><span>DynamicResource</span><span> can also be used to specify that the value should be continually updated.<span>&nbsp;&nbsp;&nbsp;
</span></span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Now we can start adding a style to improve the look of the expander. I added this to the
</span><span>&lt;</span><span>Application.Resources</span><span>&gt;</span><span> section:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Style</span><span> </span><span>TargetType</span><span> =</span><span>&quot;<span>{x:Type Expander}</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter</span><span> </span>
<span>Property</span><span> =</span><span>&quot;<span>Background</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter.Value</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>LinearGradientBrush</span><span>
</span><span>StartPoint</span><span> =</span><span>&quot;<span>0,0</span>&quot;<span> </span>
<span>EndPoint</span><span> =</span>&quot;<span>1,0</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>LinearGradientBrush.GradientStops</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>GradientStop</span><span>
</span><span>Color</span><span> =</span><span>&quot;<span>LightGray</span>&quot;<span> </span>
<span>Offset</span><span> =</span>&quot;<span>0</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>GradientStop</span><span>
</span><span>Color</span><span> =</span><span>&quot;<span>Gray</span>&quot;<span> </span><span>Offset</span><span> =</span>&quot;<span>1</span>&quot;<span>/&gt;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>LinearGradientBrush.GradientStops</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>LinearGradientBrush</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>Setter.Value</span><span>&gt;
</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>Setter</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Setter</span><span> </span><span>Property</span><span> =</span><span>&quot;<span>BorderBrush</span>&quot;<span>
</span><span>Value</span><span> =</span>&quot;<span>DimGray</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter</span><span> </span>
<span>Property</span><span> =</span><span>&quot;<span>BorderThickness</span>&quot;<span> </span>
<span>Value</span><span> =</span>&quot;<span>1</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter</span><span> </span>
<span>Property</span><span> =</span><span>&quot;<span>Margin</span>&quot;<span> </span><span>Value</span><span> =</span>&quot;<span>5</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter</span><span> </span>
<span>Property</span><span> =</span><span>&quot;<span>HorizontalContentAlignment</span>&quot;<span>
</span><span>Value</span><span> =</span>&quot;<span>Stretch</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter</span><span> </span>
<span>Property</span><span> =</span><span>&quot;<span>Foreground</span>&quot;<span> </span>
<span>Value</span><span> =</span>&quot;<span>White</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Setter</span><span> </span>
<span>Property</span><span> =</span><span>&quot;<span>VerticalContentAlignment</span>&quot;<span>
</span><span>Value</span><span> =</span>&quot;<span>Stretch</span>&quot;<span>/&gt;</span></span></p>
<p class="MsoNormal"><span>&lt;/</span><span>Style</span><span>&gt;</span><span></span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>This is a pretty straightforward style, although it does nicely demonstrate the two property assignment syntaxes. The background is set to a horizontal gradient between two shades of gray and the rest of the properties are assigned
 to sensible defaults the work well with the background. I've also added an extra border around the inside of the control by adding an extra
</span><span>Border</span><span> tag inside the expander's content like so:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Expander</span><span> </span><span>IsExpanded</span><span> =</span><span>&quot;<span>True</span>&quot;<span>
</span><span>Header</span><span>=</span>&quot;<span>Main Menu</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span>&lt;</span><span>Border</span><span> </span><span>Margin</span><span> =</span><span>&quot;<span>5</span>&quot;<span>
</span><span>Padding</span><span> =</span>&quot;<span>10</span>&quot;<span> </span></span></p>
<p class="MsoNormal"><span>Background</span><span> =</span><span>&quot;<span>#77FFFFFF</span>&quot;<span>
</span><span>BorderBrush</span><span> =</span>&quot;<span>DimGray</span>&quot;<span> </span>
<span>BorderThickness</span><span> =</span>&quot;<span>1</span>&quot;<span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>StackPanel</span><span>&gt;</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>New Game<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>Load Game<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>Save Game<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;</span><span>Button</span><span>&gt;</span><span>Quit<span>&lt;/</span><span>Button</span><span>&gt;</span></span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>StackPanel</span><span>&gt;
</span></p>
<p class="MsoNormal"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&lt;/</span><span>Border</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&lt;/</span><span>Expander</span><span>&gt;</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>The </span><span>Margin</span><span> property specifies the spacing border on the outside, while the
</span><span>Padding</span><span> property specifies the extra spacing on the inside although only container controls can have padding. Both values are specified by either four comma separated values for left, top, right, and bottom, respectively, or a single
 number if all four are the same (as they are here).</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>If you think this is kind of a kludge, you're right. In fact I could have included the extra border inside the control itself using my custom style. To do this you can modify what's called the control's template, but that's a whole
 other topic so I'll just do this for now. Don't worry, we'll come back and fix this later. After whipping up some other styles, which you can check out if you download the code, and adding a nice gradient for the window background the application looks a lot
 better……ok, well at least it's more colorful.</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span></span></p>
<p class="MsoNormal"><span><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/999502/sudoku1_4.png" width="500" height="391">&nbsp;</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Finally, to close off this part of the tutorial, let's add some simple event handling to make the “Quit” button work. This is actually very easy. Just define a method that conforms to the
</span><span>RoutedEventHandler</span><span> delegate in your </span><span>Window1</span><span> class. For example:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>void</span><span> QuitClicked(<span>object</span> sender,
<span>RoutedEventArgs</span> e)</span></p>
<p class="MsoNormal"><span>{</span></p>
<p class="MsoNormal"><span>this</span><span>.Close(); </span></p>
<p class="MsoNormal"><span>}</span><span></span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Then just set the </span><span>Clicked</span><span> property of the button to the name of your handler like this:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>&lt;</span><span>Button</span><span> </span><span>Click</span><span> =</span><span>&quot;<span>QuitClicked</span>&quot;<span>&gt;</span>Quit<span>&lt;/</span><span>Button</span><span>&gt;</span></span><span></span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Now, if you click the quit button the program will exit. This is essentially all there is to handling simple events!</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Ok, well that's all for now, I hope this tutorial has at least given you a feel for how WPF applications work and how to start building an app. We're just scratching the surface of what you can do with this framework and .NET 2.0!
 Stay tuned for the next parts of the tutorial that finish the application and cover cool stuff like:</span></p>
<p class="MsoNormal"><span>&nbsp;</span></p>
<ul type="disc">
<li class="MsoNormal"><span>Databinding, have the UI automatically display and manipulate your programs objects</span>
</li><li class="MsoNormal"><span>Custom controls and control skinning, completely alter the look and feel of existing controls or create you own</span>
</li><li class="MsoNormal"><span>Cool effects, reflections, transitions, and automatically running animations</span>
</li><li class="MsoNormal"><span>Triggers, have the UI operate itself and control its appearance with no code</span>
</li><li class="MsoNormal"><span>Creating a plug-in system, loading plug-ins written in any .NET language into a sandbox</span>
</li><li class="MsoNormal"><span>Writing multithreaded code on .NET</span></li></ul>
<p class="MsoNormal"><span>&nbsp;</span></p>
<p class="MsoNormal"><span>Keep coding!</span></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Lucas-Magder/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:3ead2728a76841d9b7da9e7600d92802">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-1-Introduction-to-WPF-and-XAML</comments>
      <itunes:summary>



&amp;nbsp;
Building Sudoku using Windows Presentation Foundation and XAML, Microsoft&#39;s new declarative programming language. This is the 1st article from a series of 5 articles and focusses on introducing WPF and XAML.



Lucas Magder


Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual C#&amp;nbsp;2008 Express Edition
Hardware: None
Download: Download (note: Tasos Valsamidis has an updated version that supports
Expression Blend here)





Note: This article has been updated to work and compile with the RTM version of the Windows SDK. 
Whenever I want to learn something new I find that just working through a tutorial is much easier and less painful then reading the documentation cold and I assume most people feel the same way, because come on, do you actually read the instructions
 for something before you try to use it? I sure don&#39;t. To this end, I&#39;ve decided the jump right into the action and walk though building a Windows Presentation Foundation application right away and since this is Coding4Fun and since, let&#39;s face it, the world
 has enough enterprise-web 2.0-data-portal-dodads, were going to make a game.&amp;nbsp;
Unfortunately, I don&#39;t think it&#39;s realistic to jump right into making Halo 3 here, so I figured a more bite-sized game might be in order, something we might actually finish by the end of these tutorials, like say a Sudoku game.
&amp;nbsp;(Hey, the upside is you might actually get away with playing Sudoku at work). Ok so what do we need to get started? (Install in this order) 
 

Visual C# 2005 Express Edition (Grab it for free at 
http://msdn.microsoft.com/vstudio/express/visualcsharp/!)&amp;nbsp; WinFX February 2006 CTP (Grab it at 
http://www.microsoft.com/downloads/details.aspx?FamilyId=F51C4D96-9AEA-474F-86D3-172BFA3B828B&amp;amp;displaylang=en)
Windows SDK February 2006 CTP (Grab it at 
http://www.microsoft.com/downloads/details.aspx?FamilyId=9BE1FC7F-0542-47F1-88DD-61E3EF88C402&amp;amp;displaylang=en#filelist)
Visual Studio Extensions for WinFX Fe</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-1-Introduction-to-WPF-and-XAML</link>
      <pubDate>Mon, 06 Nov 2006 11:32:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-1-Introduction-to-WPF-and-XAML</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/999502_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/999502_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Lucas Magder</dc:creator>
      <itunes:author>Lucas Magder</itunes:author>
      <slash:comments>13</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Building-a-WPF-Sudoku-Game-Part-1-Introduction-to-WPF-and-XAML/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Puzzle</category>
    </item>    
</channel>
</rss>