<?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 - Entries tagged with puzzle</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Tags/puzzle/RSS"/>
    <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 - Entries tagged with puzzle</title>
      <link>http://channel9.msdn.com/Tags/puzzle</link>
    </image>
    <itunes:image href=""/>
    <itunes:category text="Technology"/>
    <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/Tags/puzzle</link>
    <language>en</language>
    <pubDate>Sun, 12 Feb 2012 12:15:05 GMT</pubDate>
    <lastBuildDate>Sun, 12 Feb 2012 12:15:05 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>10</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>New from FUSE: Team Crossword Beta</title>
      <description><![CDATA[ <p>The team from <a shape="rect" href="http://fuse.microsoft.com/" shape="rect">FUSE Labs</a> (the folks behind <a shape="rect" href="http://www.microsoft.com/presspass/features/2010/mar10/03-25Affronti.mspx" shape="rect">Outlook Social Connector</a>, <a shape="rect" href="http://www.spindex.me/" shape="rect">Spindex</a>, <a shape="rect" href="http://fuse.microsoft.com/project/kodu.aspx" shape="rect">Kodu</a>, <a shape="rect" href="http://www.projectemporia.com/" shape="rect">Emporia</a>, <a shape="rect" href="http://www.bing.com/maps/explore/#5003/0.40326=&amp;o=&amp;a=0/5872/style=auto&amp;lat=47.668999&amp;lon=-122.124001&amp;z=11&amp;pid=5874" shape="rect">Bing Twitter Maps</a> and <a shape="rect" href="http://docs.com/" shape="rect">Docs</a>) have just launched a new project called <a shape="rect" href="http://www.teamcrossword.com/" shape="rect">Team Crossword</a>. This application isn’t a major release like Docs.com, the Facebook-enabled Microsoft Office service, but is rather just a simple but fun social game. At <a shape="rect" href="http://www.teamcrossword.com/" shape="rect">TeamCrossword.com</a>, you and your friends can solve crossword puzzles together online. The site also tracks the fastest time a team took to solve a puzzle, so you can see how you and your friends compare. </p><p>There’s a new puzzle available every day via the website. You can get started <a shape="rect" href="http://www.teamcrossword.com/" shape="rect">here</a> by signing in with Facebook and inviting your Facebook friends to join. </p><p><em>(Thanks </em><a shape="rect" href="http://blogs.msdn.com/b/stevecla01/archive/2010/08/28/microsoft-s-fuse-labs-releases-teamcrossword-beta.aspx" shape="rect"><em>Steve Clayton</em></a><em> for pointing this out!)</em></p> <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/puzzle/RSS&WT.dl=0&WT.entryid=Entry:RSSView:3c7bc0700d7040629d249e0e00fcb917">]]></description>
      <comments>http://channel9.msdn.com/Blogs/coolstuff/New-from-FUSE-Team-Crossword-Beta</comments>
      <itunes:summary> The team from FUSE Labs (the folks behind Outlook Social Connector, Spindex, Kodu, Emporia, Bing Twitter Maps and Docs) have just launched a new project called Team Crossword. This application isn’t a major release like Docs.com, the Facebook-enabled Microsoft Office service, but is rather just a simple but fun social game. At TeamCrossword.com, you and your friends can solve crossword puzzles together online. The site also tracks the fastest time a team took to solve a puzzle, so you can see how you and your friends compare. There’s a new puzzle available every day via the website. You can get started here by signing in with Facebook and inviting your Facebook friends to join. (Thanks Steve Clayton for pointing this out!)</itunes:summary>
      <link>http://channel9.msdn.com/Blogs/coolstuff/New-from-FUSE-Team-Crossword-Beta</link>
      <pubDate>Tue, 31 Aug 2010 08:40:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/coolstuff/New-from-FUSE-Team-Crossword-Beta</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/100/on10_70513_100x75.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/220/on10_70513_220x165.jpg" height="165" width="220"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/320/on10_9e1f7798-e6cb-46d9-9a85-b3737e48de26.jpg" height="145" width="248"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/previewImages/85/on10_12192d6d-5b36-4ca4-9890-801dfdd43aa5.jpg" height="64" width="85"/>      
      <dc:creator>Sarah Perez</dc:creator>
      <itunes:author>Sarah Perez</itunes:author>
      <slash:comments>0</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/coolstuff/New-from-FUSE-Team-Crossword-Beta/RSS</wfw:commentRss>
      <category>Facebook</category>
      <category>puzzle</category>
      <category>facebook app</category>
    </item>
  <item>
      <title>Building Multiplayer Texas Holdem Poker For The Zune</title>
      <description><![CDATA[
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582637/clip_image002_2.gif"><img title="clip_image002" border="0" alt="clip_image002" align="right" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582637/clip_image002_thumb.gif" width="240" height="320"></a>Have
 you ever been interested in creating a game that harnesses XNA's powerful network library to create multiplayer experiences for the Zune device?</p>
<p>The Zune firmware version 3.1 brought us a professionally built incarnation of Texas Holdem that supports network play. Understanding how to send and receive data with the Zune can be a little daunting at first, but once you understand the pattern, it's
 easy. </p>
<p>To build out the entire game, you probably need about a week, but you can build some simpler examples in far less time.
</p>
<p>This is an earlier project from before the release of my <a href="http://www.tinyurl.com/zunebook">
Zune game development book</a>. Accordingly, some of the code samples you see in this article may be inconsistent with what you find in the download. The code in the article is the “correct” way to do things. The code in the download is still a work in progress.</p>

<h3>The Workflow</h3>
<p>Developing multiplayer games for the Zune is interesting because you have to deploy to each device individually. Once you have a build that works for you, it's helpful to run-deploy (Control&#43;F5) to one device, leave it running there, and then plug in the
 other Zune and debug-deploy (F5) to it. This way you have one debuggable instance of the game running. Make sure to set the appropriate Zune device as the default in the XNA Game Studio Device Center (accessible from the Tools menu).</p>
<h3>Starting A Network Session</h3>
<p>Because the Zunes connect over an ad-hoc, peer-to-peer connection rather than through an access point, you will have to designate one Zune as the host device. The host is usually determined to be the one that creates a new game. Therefore, all Zunes that
 join the host's network session are simply peers. The difference between the host and the peers is that the host usually maintains the game state on top of executing the game as well, because the game data has to be centralized somewhere. Keep that in mind,
 because if one Zune is doing substantially more processing, it can lag behind and mess up your network session. Also, remember that all Zunes are running the exact same copy of the game, so the game must support both host and peer scenarios.</p>
<h4>Create / Join / Lobby Model</h4>
<p>Most peer-to-peer connected games allow a user to create or join a game. After doing so, the player is funneled into an area called the Lobby where they can specify their readiness. When all players are ready, the host can start the game. Some of this functionality
 is provided directly by the XNA Framework's Net and GamerServices libraries. </p>
<p>I normally create three separate screens based on the <a href="http://creators.xna.com/en-US/sample/network_game_state_mgt_sample">
Network Game State Management sample</a> from the Creators Club website. The first is the Create screen, which looks exactly like a lobby. It starts up a network session and waits for players to join and become ready. The code to create a network session looks
 like this (note that I have employed some abstraction to make my code a little more cohesive):</p>
<p><b>C#</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> CreateZuneSession(<span class="kwrd">int</span> maxNetworkPlayers)
{
    KillSession();

    <span class="kwrd">try</span>
    {
        Session = NetworkSession.Create(NetworkSessionType.SystemLink, 1,      
            maxNetworkPlayers); 
        Me = Session.LocalGamers[0];
    }
    <span class="kwrd">catch</span> (NetworkNotAvailableException)
    {
        <span class="kwrd">throw</span> <span class="kwrd">new</span> NetworkNotAvailableException(<span class="str">&quot;Zune wireless is not 
            enabled.&quot;</span>);
    }
    <span class="kwrd">catch</span> (NetworkException ne)
    {
        <span class="kwrd">throw</span> ne;
    }

    <span class="kwrd">if</span> (Session == <span class="kwrd">null</span>)
        <span class="kwrd">throw</span> <span class="kwrd">new</span> NetworkException(<span class="str">&quot;The network session could not be 
            created.&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>All Zune network sessions are of the type SystemLink, much like LAN-networked Xbox consoles. The ‘1' parameter specifies the number of local players – of course, on a Zune, there can only be one.</p>
<p>This line of code sets the Session property to a newly created network session. The Join screen, running on another Zune, will find this session asynchronously as an available network session and attempt to join it. The first step is to enumerate available
 network sessions:</p>
<p><b>C# <br>
</b></p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// Asynchronous: Begins to discover network sessions.</span>
<span class="rem">/// &lt;/summary&gt;</span>
<span class="kwrd">public</span> <span class="kwrd">void</span> BeginGetAvailableSessions()
{
    <span class="rem">// Destroy any existing connections</span>
    KillSession();

    NetworkSession.BeginFind(NetworkSessionType.SystemLink, 1, <span class="kwrd">null</span>, <span class="kwrd">new</span> 
        AsyncCallback(SessionsFoundCallback), <span class="kwrd">null</span>);
}</pre>
<p>This code looks for SystemLink sessions and calls the callback method SessionsFoundCallback when the operation completes (successfully or unsuccessfully). If sessions are found, an event is fired. Other screens can subscribe to this event and transition
 to other screens or do other processing with the network session.</p>
<p><b>C#</b></p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// Called when network sessions are found.</span>
<span class="rem">/// &lt;/summary&gt;</span>
<span class="rem">/// &lt;param name=&quot;result&quot;&gt;&lt;/param&gt;</span>
<span class="kwrd">public</span> <span class="kwrd">void</span> SessionsFoundCallback(IAsyncResult result)
{
    AvailableNetworkSessionCollection availableSessions = <span class="kwrd">null</span>;
    availableSessions = NetworkSession.EndFind(result);

    <span class="kwrd">if</span> (NetworkSessionsFound != <span class="kwrd">null</span>)
        NetworkSessionsFound(availableSessions);
}        </pre>
<p>When all players are ready and the host presses the middle button, the network session's StartGame() method is called, which will cause all connected peers to receive a GameStarted event. This loads up the playing screen.</p>
<p><b>C#</b></p>
<pre class="csharpcode"><span class="kwrd">if</span> (allPlayersReady &amp;&amp; atLeastTwoPlayers)
{
    <span class="kwrd">if</span> (ScreenManager.Network.Session != <span class="kwrd">null</span>)
        ScreenManager.Network.Session.StartGame();
}</pre>
<p>That's basically how to connect up two Zunes in a network session. See my <a href="http://www.tinyurl.com/zunebook">
book</a> for a much more detailed explanation.</p>
<h3>Dealing With Cards</h3>
<p>As Poker is a card game, you might want to develop a testable, standalone library that you can use not only to house your objects, but also to write out all the intense logic required for a game like poker. The task of determining what a player's best hand
 is out of seven cards (and whether it beats another player's hand) is more in-depth than you might expect.
</p>
<p>An easy way to go about this is to create a Zune game library. I called mine CardLib. CardLib has objects such as these:</p>
<ul>
<li>Card which has a suit, a value, some comparers and some utility methods) </li><li>Deck, which has a collection of cards and methods like Shuffle, ResetDeck, etc.
</li><li>Dealer, which has a deck, a list of the five community cards, and methods like Shuffle, DealCard, Burn, DealFlop, DealTurn, etc.
</li><li>HoldemHand, which contains all of the logic for determining what a hand is (always 7 cards)
</li><li>BestHand, which takes a HoldemHand and determines what the best possible hand is within that hand
</li></ul>
<h4>Shuffling Cards</h4>
<p>Shuffling cards is surprisingly easy. I use the <a href="http://www.codinghorror.com/blog/archives/001015.html">
Knuth-Fisher-Yates shuffling algorithm</a>, which takes every card in the deck and randomly swaps it with another.</p>
<p><b>C# <br>
</b></p>
<pre class="csharpcode"><span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// Knuth-Fisher-Yates shuffling algorithm:</span>
<span class="rem">/// http://www.codinghorror.com/blog/archives/001015.html</span>
<span class="rem">/// &lt;/summary&gt;</span>
<span class="kwrd">public</span> <span class="kwrd">void</span> Shuffle()
{
    Random rand = <span class="kwrd">new</span> Random();
    <span class="kwrd">for</span> (<span class="kwrd">int</span> cardIndex = _cards.Count - 1; cardIndex &gt; 0; cardIndex--)
    {
        <span class="kwrd">int</span> randomIndex = rand.Next(cardIndex &#43; 1);
        SwapCardsByIndex(cardIndex, randomIndex);
    }
    _dealIndex = 0;
}</pre>
<h4>Poker Logic</h4>
<p>An example method you'll see in this library is this snippet to check if the hand is a royal flush:</p>
<p><b>C# <br>
</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">bool</span> IsRoyalFlush(<span class="kwrd">out</span> List&lt;Card&gt; winningCards)
{
    List&lt;Card&gt; straightFlushCards;

    <span class="kwrd">if</span> (IsStraightFlush(<span class="kwrd">out</span> straightFlushCards))
    {                
        <span class="rem">// Check to make sure the straight flush cards are: 10 J Q K A</span>
        straightFlushCards.Sort();

        <span class="kwrd">if</span> (straightFlushCards[0].Value == 10 &amp;&amp;
            straightFlushCards[1].Value == Card.Jack &amp;&amp;
            straightFlushCards[2].Value == Card.Queen &amp;&amp;
            straightFlushCards[3].Value == Card.King &amp;&amp;
            straightFlushCards[4].Value == Card.Ace)
        {
            winningCards = straightFlushCards;
            <span class="kwrd">return</span> <span class="kwrd">true</span>;
        }

        <span class="kwrd">else</span>
        {
            winningCards = <span class="kwrd">null</span>;
            <span class="kwrd">return</span> <span class="kwrd">false</span>;
        }
    }
    <span class="kwrd">else</span>
    {
        winningCards = <span class="kwrd">null</span>;
        <span class="kwrd">return</span> <span class="kwrd">false</span>;
    }
}</pre>
<p>There is a ton of similar and even more disgusting logic to peruse in the HoldemHand.cs file in the region entitled “Poker Logic Fun Times.” This logic covers every possible poker hand and could probably be refactored to be way more elegant.</p>
<p>When it comes time to evaluate the winner, each player's best hand is determined and they are evaluated against each other to determine the winner. This code returns a list of WinnerInfo objects, which returns the player info and a list of the cards they
 won with.</p>
<p><b>C#</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> List&lt;WinnerInfo&gt; DetermineWinners()
{
    BestHand overallBestHand = <span class="kwrd">null</span>;
    HoldemPlayer winner = <span class="kwrd">null</span>;

    List&lt;WinnerInfo&gt; winners = <span class="kwrd">new</span> List&lt;WinnerInfo&gt;();

    <span class="kwrd">foreach</span> (HoldemPlayer player <span class="kwrd">in</span> _players)
    {
        <span class="kwrd">if</span> (player.Status != PlayerStatus.Folded)
        {
            HoldemHand tempHand = <span class="kwrd">new</span> HoldemHand(player.Pocket, _communityCards);
            BestHand bestHand = tempHand.GetBestHand();

            <span class="kwrd">if</span> (overallBestHand == <span class="kwrd">null</span>) <span class="rem">// if there is no best hand yet</span>
            {
                overallBestHand = bestHand;
                winner = player;
                winners.Add(<span class="kwrd">new</span> WinnerInfo(overallBestHand, winner, Me));
            }
            <span class="kwrd">else</span>
            {
                <span class="rem">// if this hand beats the current best hand</span>
                <span class="kwrd">if</span> (BestHand.Beats(bestHand, overallBestHand))
                {
                    winners.Clear();
                    overallBestHand = bestHand;
                    winner = player;
                    winners.Add(<span class="kwrd">new</span> WinnerInfo(overallBestHand, winner, Me));
                }
                <span class="kwrd">else</span>
                {
                    <span class="kwrd">if</span> (BestHand.IsEquivalentTo(bestHand, overallBestHand))
                    {
                        winners.Add(<span class="kwrd">new</span> WinnerInfo(bestHand, player, Me));
                    }
                }
            }
        }
    }

    _winners = winners;
    <span class="kwrd">return</span> winners;
}</pre>
<h4>Drawing Cards On The Screen</h4>
<p>Rather than have 52 different sprites that represent each possible card, I just made my own sheet of Zune-sized playing cards. Horizontally, they are ordered by value (1-13) and vertically they are ordered by suit (both alphabetically and corresponding to
 the numeric value of the Suit enumeration in the project, 1-4).</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582637/clip_image004_2.gif"><img title="clip_image004" border="0" alt="clip_image004" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/9582637/clip_image004_thumb.gif" width="572" height="240"></a></p>
<p>When a specific card is requested to be drawn, a formula is used to calculate the source rectangle from this larger image. This is very similar to how fonts worked before spritefonts were introduced into XNA. This allows us to strip out the graphic of a
 specific card and draw it onscreen at some other location.</p>
<p><b>C# <br>
</b></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> DrawCard(Card card, Vector2 position)
{
    <span class="kwrd">if</span> (card != Card.Undefined &amp;&amp; card.Suit != Suit.Unassigned)
        ScreenManager.SpriteBatch.Draw(_texDeck, position, GetCardSourceRect(card), Color.White);
}

<span class="kwrd">private</span> Rectangle GetCardSourceRect(Card card)
{
    <span class="kwrd">if</span> (card.Suit == Suit.Unassigned)
        <span class="kwrd">throw</span> <span class="kwrd">new</span> ArgumentException(<span class="str">&quot;Unassigned cards cannot be drawn.&quot;</span>);

    <span class="kwrd">int</span> cardColumn = card.Value - 1;
    <span class="kwrd">int</span> cardRow = (<span class="kwrd">int</span>)card.Suit - 1;

    <span class="kwrd">int</span> x = cardColumn * MainScreenElements.CARD_WIDTH;
    <span class="kwrd">int</span> y = cardRow * MainScreenElements.CARD_HEIGHT;

    <span class="kwrd">return</span> <span class="kwrd">new</span> Rectangle(x, y, MainScreenElements.CARD_WIDTH, MainScreenElements.CARD_HEIGHT);
}</pre>
<h3>Managing Network Data</h3>
<p>One thing that increases the complexity of this game (in no small way) is the management of network data. First of all, the host's actions are a superset of the peer's actions (a host is also a peer, but it also has to manage the game and network state).
 For example, when a peer decides to bet, it has to send a message to the host saying “I would like to bet,” and then the host will process that message and relay it to the other peers. The host is also responsible for managing whose turn it is and determining
 who the winner is. Theoretically, you could do a lot of this with every peer acting equally but it feels safer to me to have the host responsible for important activities like dealing cards. In fact, the host has to be the only one who can deal cards, because
 if each client maintained its own deck, it would be randomized for every peer when the deck is shuffled.
</p>
<h4>How Data Is Sent And Received</h4>
<p>I will usually create a static class called NetworkMessageSender that is responsible for sending various messages. I keep an enumeration of type byte that holds the possible network messages.
</p>
<p>I always send the byte indicating the message type first, so that when the peer receives a byte, it knows how to respond. For example, if the peer receives a CardDealt message, it can pop off a string and a card from the incoming packets. If the card is
 not intended for the peer, it can simply discard the message. </p>
<p>Data you want to send is written to a packet writer object. When the data is ready to be sent, you call the SendData method of the LocalGamer object. Depending on how important packet receipt is, you can specify the type of transmission. I use ReliableInOrder
 during poker because network data is exchanged relatively infrequently. Although there is only one local network gamer, you can use a foreach loop to ensure this code will work on other platforms.</p>
<p><b>C# <br>
</b></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">void</span> SendData()
{
    <span class="kwrd">foreach</span> (LocalNetworkGamer gamer <span class="kwrd">in</span> NetworkSessionManager.Session.LocalGamers)
        gamer.SendData(NetworkSessionManager.PacketWriter, SendDataOptions.ReliableInOrder);
}</pre>
<p>Specific chunks of data are then sent using various static methods. Each piece of information is written sequentially. The card is serialized into a string format before being sent. The following chunk of code is used to send a card to a player.</p>
<p><b>C# <br>
</b></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> DealCards(HoldemPlayer player)
{
    NetworkSessionManager.PacketWriter.Write((<span class="kwrd">byte</span>)NetworkMessageType.Deal);
    NetworkSessionManager.PacketWriter.Write(player.Name);
    NetworkSessionManager.PacketWriter.Write(player.Pocket.Card1.Serialize());
    NetworkSessionManager.PacketWriter.Write(player.Pocket.Card2.Serialize());
    SendData();
}</pre>
<p>On the other side of that, whenever the screen updates, the game is constantly checking for new network data. The following code is part of a method that is called from the game screen's Update loop.</p>
<p><b>C# <br>
</b></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> UpdateNetworkSession()
{
    NetworkSessionManager.Update();

    <span class="kwrd">foreach</span> (LocalNetworkGamer localGamer <span class="kwrd">in</span> 
        NetworkSessionManager.Session.LocalGamers)
    {
        <span class="kwrd">while</span> (localGamer.IsDataAvailable)
        {
            NetworkGamer sender;
            localGamer.ReceiveData(NetworkSessionManager.PacketReader, 
                <span class="kwrd">out</span> sender);

            <span class="rem">// Interpret the first piece of information, the message.</span>
            NetworkMessageType message = (NetworkMessageType)NetworkSessionManager.PacketReader.ReadByte();

            <span class="rem">// Determine what to read and what to do based on this message type</span>
            <span class="kwrd">switch</span> (message)
            {
                <span class="rem">// major snippage</span>
                <span class="kwrd">case</span> NetworkMessageType.Deal: <span class="rem">// Happens when a card is dealt</span>
                {
                    <span class="kwrd">string</span> playerName = NetworkSessionManager.PacketReader.ReadString();
                    <span class="kwrd">string</span> card1 = NetworkSessionManager.PacketReader.ReadString();
                    <span class="kwrd">string</span> card2 = NetworkSessionManager.PacketReader.ReadString();

                 _gameplayManager.Players[playerName].Pocket.Set(PlayerPocket.FIRST_CARD_INDEX, <span class="kwrd">new</span> 
                    Card(card1));
                 _gameplayManager.Players[playerName].Pocket.Set(PlayerPocket.SECOND_CARD_INDEX, <span class="kwrd">new</span> 
                    Card(card2));
                }
                <span class="kwrd">break</span>;
            }
        }
    }
}</pre>
<p>There is a whole bunch of similar code that underlies how the game executes. When a message needs to be sent, the NetworkMessageSender class is used. To determine what happens when a message is received, we look at that ginormous switch statement that gets
 called in the screen update loop. </p>
<p>Remember that the host is also a peer and it will receive the very same messages it sends (unless you specify otherwise). Be careful not to double-process messages if they are sent by the host. In some cases you will need to check that the current device
 is or is not the host. In the sample download, this is achieved just by checking a Boolean value that is set early on in the game.</p>
<h3>Conclusion</h3>
<p>Building Poker for the Zune, from the ground up, is no small feat! Networked Zune games are far simpler when you have a much more limited set of possible data and messages that could be sent. For example, networked Pong, Battleship or Tetris would be pretty
 easy compared to poker. Turn-based games on the Zune also provide an interesting challenge in terms of what happens when a Zune drops from the network session.</p>
<p>This is just a small dip into networked Zune game development. For a deep dive, check out my book,
<a href="http://www.tinyurl.com/zunebook">Zune Game Development using XNA 3.0</a>, also available on
<a href="http://www.apress.com/book/view/9781430218616">Apress.com as an eBook</a>. The final chapter is a sprawling 120 pages covering how to build Crazy Eights for the Zune from the ground up.</p>
<h3>About The Author</h3>
<p>Dan Waters is an Academic Developer Evangelist at Microsoft, based in Tampa, FL. When he's not out showing the latest and greatest MS technology to students and faculty, he's spending time with his wife and young daughter or rocking out on one of his (far
 too numerous) guitars. Follow Dan on <a href="http://www.twitter.com/danwaters">
Twitter</a> or check out his <a href="http://www.danwaters.com">blog</a>.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/puzzle/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7306567bc89345a897909e7600cc98a2">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Building-Multiplayer-Texas-Holdem-Poker-For-The-Zune</comments>
      <itunes:summary>
Have
 you ever been interested in creating a game that harnesses XNA&#39;s powerful network library to create multiplayer experiences for the Zune device?
The Zune firmware version 3.1 brought us a professionally built incarnation of Texas Holdem that supports network play. Understanding how to send and receive data with the Zune can be a little daunting at first, but once you understand the pattern, it&#39;s
 easy. 
To build out the entire game, you probably need about a week, but you can build some simpler examples in far less time.

This is an earlier project from before the release of my 
Zune game development book. Accordingly, some of the code samples you see in this article may be inconsistent with what you find in the download. The code in the article is the “correct” way to do things. The code in the download is still a work in progress.

The Workflow
Developing multiplayer games for the Zune is interesting because you have to deploy to each device individually. Once you have a build that works for you, it&#39;s helpful to run-deploy (Control&amp;#43;F5) to one device, leave it running there, and then plug in the
 other Zune and debug-deploy (F5) to it. This way you have one debuggable instance of the game running. Make sure to set the appropriate Zune device as the default in the XNA Game Studio Device Center (accessible from the Tools menu).
Starting A Network Session
Because the Zunes connect over an ad-hoc, peer-to-peer connection rather than through an access point, you will have to designate one Zune as the host device. The host is usually determined to be the one that creates a new game. Therefore, all Zunes that
 join the host&#39;s network session are simply peers. The difference between the host and the peers is that the host usually maintains the game state on top of executing the game as well, because the game data has to be centralized somewhere. Keep that in mind,
 because if one Zune is doing substantially more processing, it can lag behind and mess up your net</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Building-Multiplayer-Texas-Holdem-Poker-For-The-Zune</link>
      <pubDate>Tue, 05 May 2009 16:06:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Building-Multiplayer-Texas-Holdem-Poker-For-The-Zune</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9582637_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/9582637_220.jpg" height="165" width="220"/>      
      <dc:creator>Dan Waters</dc:creator>
      <itunes:author>Dan Waters</itunes:author>
      <slash:comments>2</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Building-Multiplayer-Texas-Holdem-Poker-For-The-Zune/RSS</wfw:commentRss>
      <category>Gaming</category>
      <category>Hardware</category>
      <category>puzzle</category>
      <category>card and board games</category>
    </item>
  <item>
      <title>Silverlight Dynamic Video Puzzle</title>
      <description><![CDATA[
<p>My blog title says it all, <a href="http://www.betterthaneveryone.com/">Monkey see, Monkey Build</a>.&nbsp; I saw Microsoft Surface's video puzzle and I needed to build it.&nbsp; I took this opportunity to play with Microsoft's new technology,
<a href="http://silverlight.net/">Silverlight</a> and build my own puzzle game.&nbsp; I couldn't find anything out on the Internet regarding dynamic video creation with Silverlight so I took it upon myself to do this.&nbsp; The screen shots in this demo will be in c#,
 however, everything should hold true for VB.</p>
<p>Clint Rutkas - Academic Developer Evangelist - Microsoft <br>
<a href="http://www.betterthaneveryone.com/">Monkey see, Monkey Build</a></p>
<p><b>Difficulty: </b>Intermediate <br>
<b>Time Required:</b> 6-10 hours <br>
<b>Cost: </b>Free <br>
<b>Software: </b><b><a href="http://www.microsoft.com/express/">Visual Studio Express</a>,
<a href="http://silverlight.net/GetStarted/">Silverlight SDK and Runtime for <strike>
1.1</strike> 2.0 beta2</a></b> <br>
<b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/surfacePuzzleDemo.zip"><strike>Download c#</strike></a><strike> -
</strike><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/surfacePuzzleDemoVB.zip"><strike>Download VB</strike></a> Updated to Silverlight 2.0 Beta -
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/VideoRealTimeBreakUp.zip">
Download c#</a></p>
<p><strong>Updates: </strong></p>
<ul>
<li>Fixed the Silverlight.Js, used the new version that is included with the 1.1 Refresh SDK so the proper installer will prompt now.&nbsp; Downloads are corrected also too.
</li><li>6/20/2008&nbsp;- Verified the solution works with Silverlight 2.0beta2.</li></ul>
<h2>Spec's, Requirements and headaches</h2>
<p>So I had a few mental requirements for the application to &quot;entertain&quot; myself.&nbsp;
</p>
<ol>
<li>Be able to rotate the video blocks </li><li>Be able to translate </li><li>Be able to increase the difficulty of the puzzle on the fly. </li><li>Zero interaction with the keyboard</li></ol>
<p>Simple, right?&nbsp; You want to see a demo too see some awesomeness?&nbsp; No problem, <a href="http://www.betterthaneveryone.com/archive/2008/01/06/silverlight-ms-surface-puzzle-like-demo.aspx">
head over to my site</a> and see it in person.</p>
<p><strong>Microsoft Surface Video Puzzle</strong></p>
<p><img height="180" alt="sl_9[1]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/sl_91.jpg" width="240" border="0"></p>
<p><strong>Clint's Silverlight Video Puzzle</strong></p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image1.png"><img height="219" alt="image[1]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image1_thumb.png" width="240" border="0"></a></p>
<h2>To the Internet Batman!</h2>
<p>To help save time building this, I first when out and attempting to see if anything has been done anything close to this before.&nbsp; I found</p>
<p>Also I need 2 small controls which I found out are in the Silverlight SDK.&nbsp; I needed horizontal slider controls for this app.&nbsp; While I know a text box control would have worked just as well, see requirement 4.</p>
<p>On the Silverlight community site, there is also a very nice demo showing the <a href="http://silverlight.net/samples/1.1/SilverlightSurface/Run/default.html">
photo application in Surface with source code</a>.&nbsp; This is where I learned the majority of what I needed.&nbsp; This application was very close to where I needed to go with mine.&nbsp; However, while it was close, it wasn't perfect.&nbsp; Parts of the photo application code
 are pretty much copied.&nbsp; This isn't the best way of doing this, but it is one way of doing it.</p>
<h2>Toolbelt: check, Keyboard: check, Band-aids: check</h2>
<p>So on to building it.&nbsp; I first started off with a new project and some XAML.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image_6.png"><img height="269" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image.png" width="400" border="0"></a></p>
<p>After clicking &quot;OK&quot;, I get a very nice blank project.</p>
<p>&nbsp;<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image_7.png"><img height="367" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image_3.png" width="400" border="0"></a>
</p>
<p>We'll want to add an additional XAML object for the video blocks.&nbsp; Go to &quot;<strong>Project -&gt; Add New Item</strong>&quot;, select Silverlight Page, name it &quot;VideoBlock.xaml&quot; and click &quot;OK&quot;.</p>
<p>So now we have everything we need for the most part, grab any video you have, if you don't have one, go to a site like
<a href="http://teamxbox.com/">TeamXbox</a> and grab one from there.&nbsp; I used Windows Movie Maker and grabbed a snippet from The Office (best show ever).</p>
<p>In addition to all these files, we need to add in a reference to the Silverlight SDK to get a hold of the Slider controls. Go to &quot;<strong>Project -&gt; Add Reference</strong>&quot;, and add in the
<strong>Silverlight.Samples.Controls.dll</strong>.</p>
<p>While we have a reference in the application, we still need the XAML to know about this also.&nbsp; So we'll add a line to link this in.&nbsp; It is the xmlns line that I bolded, XML name space, real clever, eh?&nbsp; We'll also&nbsp; change the background color to a gray so
 we can see it more easy.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Canvas</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;parentCanvas&quot;</span>
        <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/client/2007&quot;</span> 
        <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span> 
        <span class="attr">Loaded</span><span class="kwrd">=&quot;Page_Loaded&quot;</span> 
        <span class="attr">x:Class</span><span class="kwrd">=&quot;c4f_SilverlightVideoDemo.VideoBlock;assembly=ClientBin/c4f_SilverlightVideoDemo.dll&quot;</span>
        <strong><span class="attr">xmlns:uicontrol</span><span class="kwrd">=&quot;clr-namespace:Silverlight.Samples.Controls;assembly=ClientBin/Silverlight.Samples.Controls.dll&quot;</span></strong>
        <span class="attr">Background</span><span class="kwrd">=&quot;#CCCCCC&quot; <span class="attr">Width</span><span class="kwrd">=&quot;640&quot;</span> <span class="attr">Height</span><span class="kwrd">=&quot;480&quot;</span></span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Canvas</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;
	overflow:auto}
.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>
<h2>Silverlight 101</h2>
<p>So in Silverlight, you have brushes which can &quot;painted&quot; onto objects.&nbsp; One of these brushes is called the VideoBrush which I'll talk about later on.&nbsp; For playing videos, one would use the
<strong>MediaElement</strong>.&nbsp; Lets add this to our canvas.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">MediaElement</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;media&quot;</span> <span class="attr">Source</span><span class="kwrd">=&quot;theOffice.wmv&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>Now if we run the application at this point, we'll get the video playing.&nbsp; Lets sit back with some popcorn and enjoy this victory for a second or two.&nbsp; Now that we have this, lets hide it since this isn't what we want.&nbsp; We do that by adding in an XML attribute
<strong>Opacity</strong> and setting it to 0.</p>
<p>On top of that element, lets add on some TextBlock elements and the sliders.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Canvas</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;parentCanvas&quot;</span>
        <span class="attr">xmlns</span><span class="kwrd">=&quot;http://schemas.microsoft.com/client/2007&quot;</span> 
        <span class="attr">xmlns:x</span><span class="kwrd">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span> 
        <span class="attr">Loaded</span><span class="kwrd">=&quot;Page_Loaded&quot;</span> 
        <span class="attr">x:Class</span><span class="kwrd">=&quot;VideoCreatedObjectTest.Page;assembly=ClientBin/VideoCreatedObjectTest.dll&quot;</span>
        <span class="attr">xmlns:uicontrol</span><span class="kwrd">=&quot;clr-namespace:Silverlight.Samples.Controls;assembly=ClientBin/Silverlight.Samples.Controls.dll&quot;</span> 
        <span class="attr">Background</span><span class="kwrd">=&quot;#CCCCCC&quot;</span> <span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">MediaElement</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;media&quot;</span> <span class="attr">Source</span><span class="kwrd">=&quot;theOffice.wmv&quot;</span> <span class="attr">Opacity</span><span class="kwrd">=&quot;0&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;sliderX&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Top</span><span class="kwrd">=&quot;5&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Left</span><span class="kwrd">=&quot;5&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot;X (01):&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;sliderY&quot;</span>  <span class="attr">Canvas</span>.<span class="attr">Top</span><span class="kwrd">=&quot;21&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Left</span><span class="kwrd">=&quot;5&quot;</span> <span class="attr">Text</span><span class="kwrd">=&quot;Y (01):&quot;</span> <span class="kwrd">/&gt;</span>
    
    <span class="kwrd">&lt;</span><span class="html">uicontrol:Slider</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;hSliderX&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Top</span><span class="kwrd">=&quot;8&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Left</span><span class="kwrd">=&quot;55&quot;</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">uicontrol:Slider</span> <span class="attr">x:Name</span><span class="kwrd">=&quot;hSliderY&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Top</span><span class="kwrd">=&quot;25&quot;</span> <span class="attr">Canvas</span>.<span class="attr">Left</span><span class="kwrd">=&quot;55&quot;</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Canvas</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>So now when we run the application, we get a blank screen but we can hear the audio from the video.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image_8.png"><img height="345" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image_4.png" width="400" border="0"></a>
</p>
<p>Super exciting I know.&nbsp; Now if you resize the browser, you'll notice also the canvas isn't resizing automatically.&nbsp; Lets fix that.</p>
<p>So in the code behind lets add in a new event on the BrowserHost object with the Resize event.&nbsp; We'll attach the Browser_Resize event to it.</p>
<p><strong>C#</strong></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> BrowserHost_Resize(<span class="kwrd">object</span> sender, EventArgs e)
{
    <span class="rem">// Set size to host size</span>
    Width = BrowserHost.ActualWidth;
    Height = BrowserHost.ActualHeight;
}</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><strong>VB.Net</strong></p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> BrowserHost_Resize(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> EventArgs)
    <span class="rem">' Set size to host size</span>
    Width = BrowserHost.ActualWidth
    Height = BrowserHost.ActualHeight
<span class="kwrd">End</span> Sub</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>
<h2>Video as Paint?</h2>
<p>So now that we have that small part done, lets get into more of the nitty gritty with video.&nbsp; As I said earlier, you'll use a
<strong>VideoBrush</strong> to paint on the video.</p>
<p>We'll use the brush as the Fill for the rectangle we'll be using to show off the clip of the video we want.</p>
<h3>Still not moving?&nbsp; Try explosives?</h3>
<p>While doing this project, I discovered an interesting thing when using the VideoBrush and dynamically appending items on.&nbsp; Having items in the XAML rather than programmatically creating everything caused it not to work properly.&nbsp; Nothing would appear.</p>
<h3>Throwback to how UI's use to be done</h3>
<p>The XAML for this is a simplified version of the Surface demo Photo.XAML.&nbsp; You have a 3 Rectangles, 1 for the video, 1 for translation and 1 for rotation.&nbsp; Simple, no?&nbsp; Doing all this by hand gets a bit annoying since you need to nest everything properly.</p>
<p>Here is the more interesting <strong>VideoBrush</strong> code.&nbsp; You need the name from the
<strong>MediaElement </strong>along with the how much of an offset you want the video.&nbsp; Since your moving the &quot;camera&quot; in, this value needs to be negative.</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image_10.png"><img height="395" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/image_5.png" width="654" border="0"></a>
</p>
<p><strong>C#</strong></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">delegate</span> <span class="kwrd">void</span> SetActiveVideo(VideoBlock videoBlock, ActionType actionType, Point photoCenter, Point lastPosition);
<span class="kwrd">public</span> VideoBlock(<span class="kwrd">string</span> mediaName, <span class="kwrd">int</span> offsetX, <span class="kwrd">int</span> offsetY, <span class="kwrd">int</span> rectWidth, <span class="kwrd">int</span> rectHeight, SetActiveVideo functionPointer)
{
    <span class="rem">// additional code here</span>
    Rectangle video = <span class="kwrd">new</span> Rectangle();
    VideoBrush vb = <span class="kwrd">new</span> VideoBrush();
    TranslateTransform videoTransform = <span class="kwrd">new</span> TranslateTransform();
    videoTransform.X = -1 * offsetX;
    videoTransform.Y = -1 * offsetY;

    vb.SourceName = mediaName;
    vb.Transform = videoTransform;
    vb.Stretch = Stretch.None;
    vb.AlignmentX = AlignmentX.Left;
    vb.AlignmentY = AlignmentY.Top;

    video.Width = Width;
    video.Height = Height;
    video.Fill = vb;
    <span class="rem">// additional code here</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><strong>VB.Net</strong></p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Delegate</span> <span class="kwrd">Sub</span> SetActiveVideo(<span class="kwrd">ByVal</span> videoBlock <span class="kwrd">As</span> VideoBlock, <span class="kwrd">ByVal</span> actionType <span class="kwrd">As</span> ActionType, <span class="kwrd">ByVal</span> photoCenter <span class="kwrd">As</span> Point, <span class="kwrd">ByVal</span> lastPosition <span class="kwrd">As</span> Point)
<span class="kwrd">Public</span> <span class="kwrd">Sub</span> VideoBlock(<span class="kwrd">ByVal</span> mediaName <span class="kwrd">As</span> <span class="kwrd">String</span>, <span class="kwrd">ByVal</span> offsetX <span class="kwrd">As</span> <span class="kwrd">Integer</span>, <span class="kwrd">ByVal</span> offsetY <span class="kwrd">As</span> <span class="kwrd">Integer</span>, <span class="kwrd">ByVal</span> rectWidth <span class="kwrd">As</span> <span class="kwrd">Integer</span>, <span class="kwrd">ByVal</span> rectHeight <span class="kwrd">As</span> <span class="kwrd">Integer</span>, <span class="kwrd">ByVal</span> functionPointer <span class="kwrd">As</span> SetActiveVideo)
      <span class="rem">' additional code here</span>
      <span class="kwrd">Dim</span> video <span class="kwrd">As</span> Rectangle = <span class="kwrd">New</span> Rectangle
      <span class="kwrd">Dim</span> vb <span class="kwrd">As</span> VideoBrush = <span class="kwrd">New</span> VideoBrush
      <span class="kwrd">Dim</span> videoTransform <span class="kwrd">As</span> TranslateTransform = <span class="kwrd">New</span> TranslateTransform
      videoTransform.X = ((1 * offsetX)  * -1)
      videoTransform.Y = ((1 * offsetY)  * -1)
      vb.SourceName = mediaName
      vb.Transform = videoTransform
      vb.Stretch = Stretch.None
      vb.AlignmentX = AlignmentX.Left
      vb.AlignmentY = AlignmentY.Top
      video.Width = Width
      video.Height = Height
      video.Fill = vb
      <span class="rem">' additional code here</span>
<span class="kwrd">End</span> Sub</pre>
<h3>There is a mouse on my object!</h3>
<p>So now we have our video block element prepped and ready.&nbsp; There are additional events added in, but they are fairly boiler plate.&nbsp; When looking at this code, you see I pass in a delegate, a function pointer if you will.&nbsp; Why do I do this?&nbsp; This is how the
 mouse position is calculated.&nbsp; I bet this could be redone better, but this is how I did it.&nbsp; The parent element, the canvas, has the mouse position I need to calculate proper translation and rotation, however, mouse events on the VideoBlock object will give
 me the mouse position only on that element.&nbsp; So I may be at point 150, 150 on the screen, on the VideoBlock object, I'm actually at 10,15.</p>
<p>Additionally, this approach allows me to move the VideoBlock to the top of the objects.&nbsp; Once again, this could be done other ways, this is how I chose to do it.</p>
<p>So on all my mouse related all boils down to doing the exact same function.&nbsp; Since events are bubbled, a mouse movement on a VideoBlock is also a mouse movement on the root canvas.</p>
<p>C#</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> root_MouseLeftButtonDown(<span class="kwrd">object</span> sender, MouseEventArgs e)
{
    HandleMouseLeftButtonDown(ActionType.Selecting, e);
}

<span class="kwrd">private</span> <span class="kwrd">void</span> translateControls_MouseLeftButtonDown(<span class="kwrd">object</span> sender, MouseEventArgs e)
{
    HandleMouseLeftButtonDown(ActionType.Moving, e);
}

<span class="kwrd">private</span> <span class="kwrd">void</span> rotateScaleControls_MouseLeftButtonDown(<span class="kwrd">object</span> sender, MouseEventArgs e)
{
    HandleMouseLeftButtonDown(ActionType.RotatingScaling, e);
}

<span class="kwrd">private</span> <span class="kwrd">void</span> HandleMouseLeftButtonDown(ActionType actionType, MouseEventArgs e)
{
    <span class="kwrd">if</span> (functionPointer != <span class="kwrd">null</span>)
        functionPointer(<span class="kwrd">this</span>, actionType,
            <span class="kwrd">new</span> Point(translateTransform.X &#43; rotateTransform.CenterX,
                  translateTransform.Y &#43; rotateTransform.CenterY), e.GetPosition(<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>VB.Net</p>
<pre class="csharpcode">    <span class="kwrd">Private</span> <span class="kwrd">Sub</span> root_MouseLeftButtonDown(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> MouseEventArgs)
        HandleMouseLeftButtonDown(ActionType.Selecting, e)
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
    
    <span class="kwrd">Private</span> <span class="kwrd">Sub</span> translateControls_MouseLeftButtonDown(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> MouseEventArgs)
        HandleMouseLeftButtonDown(ActionType.Moving, e)
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
    
    <span class="kwrd">Private</span> <span class="kwrd">Sub</span> rotateScaleControls_MouseLeftButtonDown(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> MouseEventArgs)
        HandleMouseLeftButtonDown(ActionType.RotatingScaling, e)
    <span class="kwrd">End</span> <span class="kwrd">Sub</span>
    
    <span class="kwrd">Private</span> <span class="kwrd">Sub</span> HandleMouseLeftButtonDown(<span class="kwrd">ByVal</span> actionType <span class="kwrd">As</span> ActionType, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> MouseEventArgs)
        <span class="kwrd">If</span> (<span class="kwrd">Not</span> (functionPointer) <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>) <span class="kwrd">Then</span>
            functionPointer(<span class="kwrd">Me</span>, actionType, <span class="kwrd">New</span> Point((translateTransform.X &#43; rotateTransform.CenterX), <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (translateTransform.Y &#43; rotateTransform.CenterY)), e.GetPosition(<span class="kwrd">Nothing</span>))
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">End</span> Sub</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>
<h2>You built a car out of all these parts?</h2>
<p>So we move back from VideoBlock.xaml.cs to Page.xaml.cs</p>
<p>We've created our primary object for painting video, lets populate it.&nbsp; First, how do we know how big the media file is?&nbsp; With the
<strong>MediaOpened</strong> event!&nbsp; And we'll restart the video with the <strong>
MediaEnded</strong> event.</p>
<p>So here is the full Page_Load event from Page.xaml.cs</p>
<p><strong>C#</strong></p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Page_Loaded(<span class="kwrd">object</span> o, EventArgs e)
{
    <span class="rem">// Required to initialize variables</span>
    InitializeComponent();

    BrowserHost.Resize &#43;=<span class="kwrd">new</span> EventHandler(BrowserHost_Resize);
    media.MediaOpened &#43;= <span class="kwrd">new</span> EventHandler(media_MediaOpened);
    media.MediaEnded &#43;= <span class="kwrd">new</span> EventHandler(media_MediaEnded);
    MouseLeftButtonUp &#43;= Page_MouseLeftButtonUpOrLeave;
    MouseLeave &#43;= Page_MouseLeftButtonUpOrLeave;
    MouseMove &#43;= Page_MouseMove;

    hSliderX.Range = <span class="kwrd">new</span> ValueRange(1, 20);
    hSliderY.Range = <span class="kwrd">new</span> ValueRange(1, 20);
    hSliderX.ValueChanged &#43;= <span class="kwrd">new</span> EventHandler(slider_ValueChanged);
    hSliderY.ValueChanged &#43;= <span class="kwrd">new</span> EventHandler(slider_ValueChanged);

    hSliderX.SetValue(ZIndexProperty, 500);
    hSliderY.SetValue(ZIndexProperty, 500);
    sliderX.SetValue(ZIndexProperty, 500);
    sliderY.SetValue(ZIndexProperty, 500);
}</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><strong>VB.Net</strong></p>
<pre class="csharpcode">    <span class="kwrd">Public</span> <span class="kwrd">Sub</span> Page_Loaded(<span class="kwrd">ByVal</span> o <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> EventArgs)
        <span class="rem">' Required to initialize variables</span>
        InitializeComponent
        <span class="kwrd">AddHandler</span> BrowserHost.Resize, <span class="kwrd">AddressOf</span> <span class="kwrd">Me</span>.BrowserHost_Resize
        <span class="kwrd">AddHandler</span> media.MediaOpened, <span class="kwrd">AddressOf</span> <span class="kwrd">Me</span>.media_MediaOpened
        <span class="kwrd">AddHandler</span> media.MediaEnded, <span class="kwrd">AddressOf</span> <span class="kwrd">Me</span>.media_MediaEnded
        MouseLeftButtonUp = (MouseLeftButtonUp &#43; Page_MouseLeftButtonUpOrLeave)
        MouseLeave = (MouseLeave &#43; Page_MouseLeftButtonUpOrLeave)
        MouseMove = (MouseMove &#43; Page_MouseMove)
        hSliderX.Range = <span class="kwrd">New</span> ValueRange(1, 20)
        hSliderY.Range = <span class="kwrd">New</span> ValueRange(1, 20)
        <span class="kwrd">AddHandler</span> hSliderX.ValueChanged, <span class="kwrd">AddressOf</span> <span class="kwrd">Me</span>.slider_ValueChanged
        <span class="kwrd">AddHandler</span> hSliderY.ValueChanged, <span class="kwrd">AddressOf</span> <span class="kwrd">Me</span>.slider_ValueChanged
        hSliderX.SetValue(ZIndexProperty, 500)
        hSliderY.SetValue(ZIndexProperty, 500)
        sliderX.SetValue(ZIndexProperty, 500)
        sliderY.SetValue(ZIndexProperty, 500)
    <span class="kwrd">End</span> Sub</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>So now that we have the media loaded, we can use the media.NaturalVideoWidth and media.NaturalVideoHeight properties to find out exactly how big the video is!&nbsp; I have a function that is fired off when the page is first loaded or a slider value has changed.&nbsp;
 This is how we chop it up.</p>
<p><img height="180" alt="mince_garlic[1]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/7163484/mince_garlic1.jpg" width="240" border="0">
</p>
<p><strong>C#</strong></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> prepVideoObjects()
{
    <span class="kwrd">int</span> totalPhotosX = (<span class="kwrd">int</span>)hSliderX.Value;
    <span class="kwrd">int</span> totalPhotosY = (<span class="kwrd">int</span>)hSliderY.Value;

    <span class="kwrd">if</span> (lastX != totalPhotosX || lastY != totalPhotosY)
    {
        lastX = totalPhotosX;
        lastY = totalPhotosY;

        sliderX.Text = <span class="kwrd">string</span>.Format(<span class="str">&quot;X ({0}):&quot;</span>, totalPhotosX.ToString(<span class="str">&quot;D2&quot;</span>));
        sliderY.Text = <span class="kwrd">string</span>.Format(<span class="str">&quot;Y ({0}):&quot;</span>, totalPhotosY.ToString(<span class="str">&quot;D2&quot;</span>));

        <span class="kwrd">int</span> rectWidth = (<span class="kwrd">int</span>)Math.Floor(media.NaturalVideoWidth / totalPhotosX);
        <span class="kwrd">int</span> rectHeight = (<span class="kwrd">int</span>)Math.Floor(media.NaturalVideoHeight / totalPhotosY);
        Random random = <span class="kwrd">new</span> Random();

        <span class="rem">// remove all old videoblocks</span>
        <span class="kwrd">for</span> (<span class="kwrd">int</span> i = Children.Count - 1; i &gt; 0; i--)
        {
            <span class="kwrd">if</span> (Children[i].GetType() == <span class="kwrd">typeof</span>(VideoBlock))
                Children.RemoveAt(i);
        }

        <span class="kwrd">for</span> (<span class="kwrd">int</span> x = 0; x &lt; totalPhotosX; x&#43;&#43;)
        {
            <span class="kwrd">for</span> (<span class="kwrd">int</span> y = 0; y &lt; totalPhotosY; y&#43;&#43;)
            {
                VideoBlock vb = <span class="kwrd">new</span> VideoBlock(media.Name, x * rectWidth, y * rectHeight, rectWidth, rectHeight, SetActivePhoto);
                shuffle(vb, random);
                Children.Add(vb);
            }
        }
    }
}</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><strong>VB.Net</strong></p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> prepVideoObjects()
        <span class="kwrd">Dim</span> totalPhotosX <span class="kwrd">As</span> <span class="kwrd">Integer</span> = <span class="kwrd">CType</span>(hSliderX.Value,<span class="kwrd">Integer</span>)
        <span class="kwrd">Dim</span> totalPhotosY <span class="kwrd">As</span> <span class="kwrd">Integer</span> = <span class="kwrd">CType</span>(hSliderY.Value,<span class="kwrd">Integer</span>)
        <span class="kwrd">If</span> ((lastX &lt;&gt; totalPhotosX)  _
                    <span class="kwrd">OrElse</span> (lastY &lt;&gt; totalPhotosY)) <span class="kwrd">Then</span>
            lastX = totalPhotosX
            lastY = totalPhotosY
            sliderX.Text = <span class="kwrd">String</span>.Format(<span class="str">&quot;X ({0}):&quot;</span>, totalPhotosX.ToString(<span class="str">&quot;D2&quot;</span>))
            sliderY.Text = <span class="kwrd">String</span>.Format(<span class="str">&quot;Y ({0}):&quot;</span>, totalPhotosY.ToString(<span class="str">&quot;D2&quot;</span>))
            <span class="kwrd">Dim</span> rectWidth <span class="kwrd">As</span> <span class="kwrd">Integer</span> = <span class="kwrd">CType</span>(Math.Floor((media.NaturalVideoWidth / totalPhotosX)),<span class="kwrd">Integer</span>)
            <span class="kwrd">Dim</span> rectHeight <span class="kwrd">As</span> <span class="kwrd">Integer</span> = <span class="kwrd">CType</span>(Math.Floor((media.NaturalVideoHeight / totalPhotosY)),<span class="kwrd">Integer</span>)
            <span class="kwrd">Dim</span> random <span class="kwrd">As</span> Random = <span class="kwrd">New</span> Random
            <span class="rem">' remove all old videoblocks</span>
            <span class="kwrd">Dim</span> i <span class="kwrd">As</span> <span class="kwrd">Integer</span> = (Children.Count - 1)
            <span class="kwrd">Do</span> <span class="kwrd">While</span> (i &gt; 0)
                <span class="kwrd">If</span> (Children(i).<span class="kwrd">GetType</span> = <span class="kwrd">GetType</span>(VideoBlock)) <span class="kwrd">Then</span>
                    Children.RemoveAt(i)
                <span class="kwrd">End</span> <span class="kwrd">If</span>
                i = (i - 1)
            <span class="kwrd">Loop</span>
            <span class="kwrd">Dim</span> x <span class="kwrd">As</span> <span class="kwrd">Integer</span> = 0
            <span class="kwrd">Do</span> <span class="kwrd">While</span> (x &lt; totalPhotosX)
                <span class="kwrd">Dim</span> y <span class="kwrd">As</span> <span class="kwrd">Integer</span> = 0
                <span class="kwrd">Do</span> <span class="kwrd">While</span> (y &lt; totalPhotosY)
                    <span class="kwrd">Dim</span> vb <span class="kwrd">As</span> VideoBlock = <span class="kwrd">New</span> VideoBlock(media.Name, (x * rectWidth), (y * rectHeight), rectWidth, rectHeight, SetActivePhoto)
                    shuffle(vb, random)
                    Children.Add(vb)
                    y = (y &#43; 1)
                <span class="kwrd">Loop</span>
                x = (x &#43; 1)
            <span class="kwrd">Loop</span>
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">End</span> <span class="kwrd">Sub</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>Last but not least, lets see how the mouse movements are handled on the page.</p>
<p><strong>C#</strong></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> Page_MouseMove(<span class="kwrd">object</span> sender, MouseEventArgs e)
{
    <span class="kwrd">if</span> (<span class="kwrd">null</span> != activeVideoBlock)
    {
        <span class="rem">// Perform the appropriate transform on the active photo</span>
        Point position = e.GetPosition(<span class="kwrd">null</span>);
        <span class="kwrd">switch</span> (currentActionType)
        {
            <span class="kwrd">case</span> VideoBlock.ActionType.Moving:
                <span class="rem">// Move it by the amount of the mouse move</span>
                activeVideoBlock.Translate(position.X - currentLastPosition.X, position.Y - currentLastPosition.Y);
                <span class="kwrd">break</span>;
            <span class="kwrd">case</span> VideoBlock.ActionType.RotatingScaling:
                <span class="rem">// Rotate it according to the angle the mouse moved around the photo's center</span>
                <span class="kwrd">double</span> radiansToDegrees = 360 / (2 * Math.PI);
                <span class="kwrd">double</span> lastAngle = Math.Atan2(currentLastPosition.Y - currentVideoCenter.Y, currentLastPosition.X - currentVideoCenter.X) * radiansToDegrees;
                <span class="kwrd">double</span> currentAngle = Math.Atan2(position.Y - currentVideoCenter.Y, position.X - currentVideoCenter.X) * radiansToDegrees;
                activeVideoBlock.Rotate(currentAngle - lastAngle);

                <span class="kwrd">break</span>;
        }
        currentLastPosition = position;
    }
}</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><strong>VB.Net</strong></p>
<pre class="csharpcode">    <span class="kwrd">Private</span> <span class="kwrd">Sub</span> Page_MouseMove(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> MouseEventArgs)
        <span class="kwrd">If</span> (<span class="kwrd">Not</span> (activeVideoBlock) <span class="kwrd">Is</span> <span class="kwrd">Nothing</span>) <span class="kwrd">Then</span>
            <span class="rem">' Perform the appropriate transform on the active photo</span>
            <span class="kwrd">Dim</span> position <span class="kwrd">As</span> Point = e.GetPosition(<span class="kwrd">Nothing</span>)
            <span class="kwrd">Select</span> <span class="kwrd">Case</span> (currentActionType)
                <span class="kwrd">Case</span> VideoBlock.ActionType.Moving
                    <span class="rem">' Move it by the amount of the mouse move</span>
                    activeVideoBlock.Translate((position.X - currentLastPosition.X), (position.Y - currentLastPosition.Y))
                <span class="kwrd">Case</span> VideoBlock.ActionType.RotatingScaling
                    <span class="rem">' Rotate it according to the angle the mouse moved around the photo's center</span>
                    <span class="kwrd">Dim</span> radiansToDegrees <span class="kwrd">As</span> <span class="kwrd">Double</span> = (360 / (2 * Math.PI))
                    <span class="kwrd">Dim</span> lastAngle <span class="kwrd">As</span> <span class="kwrd">Double</span> = (Math.Atan2((currentLastPosition.Y - currentVideoCenter.Y), (currentLastPosition.X - currentVideoCenter.X)) * radiansToDegrees)
                    <span class="kwrd">Dim</span> currentAngle <span class="kwrd">As</span> <span class="kwrd">Double</span> = (Math.Atan2((position.Y - currentVideoCenter.Y), (position.X - currentVideoCenter.X)) * radiansToDegrees)
                    activeVideoBlock.Rotate((currentAngle - lastAngle))
            <span class="kwrd">End</span> <span class="kwrd">Select</span>
            currentLastPosition = position
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">End</span> Sub</pre>
<h2>Wrapping it up</h2>
<p>So as you can see, Silverlight is pretty powerful once you figure out how to tame it.&nbsp; I used example base code and modified it to suit my own needs to dynamically alter a video in real time.&nbsp; There are a few code tweaks that could happen to improve this
 code and I'm betting with some additional effort, one could remove the delegate.&nbsp; In addition, you could add in edge detection code and a timer to make this into a true video puzzle game.&nbsp; This was a pet project I worked on while I was at the airport.&nbsp; This
 demo can be downgraded to Silverlight 1.0 also.&nbsp; I don't believe anything I did was really Silverlight 1.1 (now 2.0) only.</p>
<p><strong>Clint's Bio:</strong></p>
<p>Clint is an academic developer evangelist for Microsoft.&nbsp; His two primary development languages are C# and JavaScript. He has built a
<a href="http://msdn.microsoft.com/coding4fun/coolapplications/disco/default.aspx">
Disco Dance Floor</a> too! In his off time, he whips up other random weird projects and does twenty something activities with his friends.&nbsp; His next two big projects are an automated bartender and a skateboard segway.&nbsp; Clint's blog is
<a href="http://betterthaneveryone.com/">betterthaneveryone.com</a> and can be emailed at
<a href="mailto:crutkas@microsoft.com">crutkas@microsoft.com</a> if you have any question.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/puzzle/RSS&WT.dl=0&WT.entryid=Entry:RSSView:082345779d1643298e649e7600d07b4d">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Silverlight-Dynamic-Video-Puzzle</comments>
      <itunes:summary>
My blog title says it all, Monkey see, Monkey Build.&amp;nbsp; I saw Microsoft Surface&#39;s video puzzle and I needed to build it.&amp;nbsp; I took this opportunity to play with Microsoft&#39;s new technology,
Silverlight and build my own puzzle game.&amp;nbsp; I couldn&#39;t find anything out on the Internet regarding dynamic video creation with Silverlight so I took it upon myself to do this.&amp;nbsp; The screen shots in this demo will be in c#,
 however, everything should hold true for VB.
Clint Rutkas - Academic Developer Evangelist - Microsoft 
Monkey see, Monkey Build
Difficulty: Intermediate 
Time Required: 6-10 hours 
Cost: Free 
Software: Visual Studio Express,
Silverlight SDK and Runtime for 
1.1 2.0 beta2 
Download: Download c# -
Download VB Updated to Silverlight 2.0 Beta -

Download c#
Updates: 

Fixed the Silverlight.Js, used the new version that is included with the 1.1 Refresh SDK so the proper installer will prompt now.&amp;nbsp; Downloads are corrected also too.
6/20/2008&amp;nbsp;- Verified the solution works with Silverlight 2.0beta2.
Spec&#39;s, Requirements and headaches
So I had a few mental requirements for the application to &amp;quot;entertain&amp;quot; myself.&amp;nbsp;


Be able to rotate the video blocks Be able to translate Be able to increase the difficulty of the puzzle on the fly. Zero interaction with the keyboard
Simple, right?&amp;nbsp; You want to see a demo too see some awesomeness?&amp;nbsp; No problem, 
head over to my site and see it in person.
Microsoft Surface Video Puzzle

Clint&#39;s Silverlight Video Puzzle

To the Internet Batman!
To help save time building this, I first when out and attempting to see if anything has been done anything close to this before.&amp;nbsp; I found
Also I need 2 small controls which I found out are in the Silverlight SDK.&amp;nbsp; I needed horizontal slider controls for this app.&amp;nbsp; While I know a text box control would have worked just as well, see requirement 4.
On the Silverlight community site, there is also a very nice demo showing the 
photo applicati</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Silverlight-Dynamic-Video-Puzzle</link>
      <pubDate>Tue, 22 Jan 2008 16:02:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Silverlight-Dynamic-Video-Puzzle</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/7163484_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/7163484_220.jpg" height="165" width="220"/>      
      <dc:creator>Clint Rutkas </dc:creator>
      <itunes:author>Clint Rutkas </itunes:author>
      <slash:comments>5</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Silverlight-Dynamic-Video-Puzzle/RSS</wfw:commentRss>
      <category>media</category>
      <category>Silverlight</category>
      <category>Web</category>
      <category>puzzle</category>
      <category>Mash Up</category>
      <category>web miscellaneous</category>
    </item>
  <item>
      <title>Zero Gravity: Silverlight based puzzle game</title>
      <description><![CDATA[You've all played these web browser &quot;twitch&quot; games before when you should be actually working- but wait! Well <a href="http://www.ltbennett.com/">Zero Gravity</a>&nbsp;is different. Zero Gravity isn't flashed based, it runs on <a href="http://silverlight.net/">Silverlight</a>. I spoke with the guys from <a href="http://www.terralever.com/">Terralever</a>&nbsp;who set out to prove that Silverlight is certainly a worthy platform for this type of game and talked about some of the difficulties and successes involved in the games development. So, how do you play? Well you put your thinking cap on, try to get Lt. Bennett home via his spaceship and watch this clip for the details. <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/puzzle/RSS&WT.dl=0&WT.entryid=Entry:RSSView:cd1549b8517c4886b2ec9e0f00fdd6fa">]]></description>
      <comments>http://channel9.msdn.com/Blogs/LauraFoy/Zero-Gravity-Silverlight-based-puzzle-game</comments>
      <itunes:summary>You&#39;ve all played these web browser &amp;quot;twitch&amp;quot; games before when you should be actually working- but wait! Well Zero Gravity&amp;nbsp;is different. Zero Gravity isn&#39;t flashed based, it runs on Silverlight. I spoke with the guys from Terralever&amp;nbsp;who set out to prove that Silverlight is certainly a worthy platform for this type of game and talked about some of the difficulties and successes involved in the games development. So, how do you play? Well you put your thinking cap on, try to get Lt. Bennett home via his spaceship and watch this clip for the details.</itunes:summary>
      <itunes:duration>552</itunes:duration>
      <link>http://channel9.msdn.com/Blogs/LauraFoy/Zero-Gravity-Silverlight-based-puzzle-game</link>
      <pubDate>Fri, 06 Jul 2007 16:36:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/Blogs/LauraFoy/Zero-Gravity-Silverlight-based-puzzle-game</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/entries/preview/zerogravity_large_on10.jpg" height="240" width="320"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/content/on10/entries/previewsmall/zerogravity_small_on10.jpg" height="64" width="85"/>
      <media:group>
        <media:content url="http://download.microsoft.com/download/9/4/a/94af1fc8-b84b-4031-83a0-5bc16f360707/zerogravity_2MB_on10.wmv" expression="full" duration="552" fileSize="171704929" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://download.microsoft.com/download/9/4/a/94af1fc8-b84b-4031-83a0-5bc16f360707/zerogravity_on10.mp3" expression="full" duration="552" fileSize="4413568" type="audio/mp3" medium="audio"/>
        <media:content url="http://download.microsoft.com/download/9/4/a/94af1fc8-b84b-4031-83a0-5bc16f360707/zerogravity_on10.wma" expression="full" duration="552" fileSize="4466021" type="audio/x-ms-wma" medium="audio"/>
        <media:content url="http://download.microsoft.com/download/9/4/a/94af1fc8-b84b-4031-83a0-5bc16f360707/zerogravity_on10.wmv" expression="full" duration="552" fileSize="34624248" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://download.microsoft.com/download/9/4/a/94af1fc8-b84b-4031-83a0-5bc16f360707/zerogravity_s_on10.mp4" expression="full" duration="552" fileSize="35787493" type="video/mp4" medium="video"/>
        <media:content url="http://download.microsoft.com/download/9/4/a/94af1fc8-b84b-4031-83a0-5bc16f360707/zerogravity_Zune_on10.wmv" expression="full" duration="552" fileSize="44264836" type="video/x-ms-wmv" medium="video"/>
        <media:content url="http://on10.net/videos/zerogravity_on10.asx" expression="full" duration="552" fileSize="109" type="video/x-ms-wmv" medium="video"/>
      </media:group>      
      <enclosure url="http://download.microsoft.com/download/9/4/a/94af1fc8-b84b-4031-83a0-5bc16f360707/zerogravity_on10.wmv" length="34624248" type="video/x-ms-wmv"/>
      <dc:creator>Laura Foy</dc:creator>
      <itunes:author>Laura Foy</itunes:author>
      <slash:comments>6</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/Blogs/LauraFoy/Zero-Gravity-Silverlight-based-puzzle-game/RSS</wfw:commentRss>
      <category>Games</category>
      <category>Silverlight</category>
      <category>Seattle</category>
      <category>Zero Gravity</category>
      <category>puzzle</category>
    </item>
  <item>
      <title>Creating an ASP.NET Hangman Control</title>
      <description><![CDATA[<span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">In this post, Stephen Walther shows you how to create an ASP.NET Hangman control. This control contains embedded images, sounds, XML, and Javascript.</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Stephen Walther</div>
<div class="entry_company"><a href="http://www.superexpert.com">Steve's Blog</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">
Less than 1 hour</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://msdn.com/express/">Visual Basic or Visual C# Express Editions</a>,<a href="http://msdn.microsoft.com/vstudio/express/">Visual Web Developer Express</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://channel9.msdn.com/ShowPost.aspx?PostID=285841">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>This month, we create an ASP.NET Hangman control. Our control will render all of the necessary images, sounds, and scripts to create a richly interactive hangman game (see Figure 1). Our control will work with the most recent versions of Microsoft Internet
 Explorer, Mozilla Firefox, and Opera. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1756233/Figure16.png"><img height="496" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1756233/Figure1_thumb4.png" width="368" border="0"></a>
</p>
<p>We tackle several advanced features of the ASP.NET 2.0 framework in this article. You learn how to build custom controls that take advantage of Javascript. You also learn how to embed resources such as images, sound, and XML in an assembly. Finally, you
 learn how to write cross-browser compatible Javascript. </p>
<h3>Using the Hangman Control</h3>
<p>If you are anxious to start playing hangman, you can download the ZIP file that accompanies this article. Click the Download link above.&nbsp;The ZIP file contains two projects: the Visual Basic and the C# versions of the Hangman control. If you are interested
 in viewing or modifying the source code for the Hangman control, you can open the Visual Basic version with Microsoft Visual Basic 2005 Express Edition and the C# version with Microsoft C# 2005 Express Edition.
</p>
<p>Here's how you use the Hangman control. Launch Visual Web Developer 2005 Express Edition and create a new website (select the menu option File, New Web Site). Next, add the control to your Toolbox by right-clicking beneath the General tab on your Toolbox
 and selecting the option Choose Items (see Figure 2). You must have a Web Form Page open in order to modify the Toolbox.&nbsp;
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1756233/Figure22.png"><img height="417" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/1756233/Figure2_thumb.png" width="403" border="0"></a>
</p>
<p>Next, under the .NET Framework Components tab, click the Browse button and browse to the Hangman assembly (dll file). There is both a VB.NET and C# version of this file (it doesn't matter which version you use since you can use a control written in C# with
 a VB.NET website and a control written in VB.NET with a C# website). The files are located in the following subfolders:
</p>
<blockquote>
<p>VB\Hangman\bin\Release\Hangman.dll </p>
<p>CS\Hangman\bin\Release\Hangman.dll</p>
</blockquote>
<p>Click OK a couple of times to close the dialog boxes and the Hangman control should now appear on your Toolbox.
</p>
<p>After you have added to the Hangman control to your Toolbox, you can add the control to any page simply by dragging the control onto a Web Form Page in either Design or Source view. That's all there is to adding this control to a page.
</p>
<p>The Hangman control includes a default set of words included in an embedded XML file (these words are intended to be hard). If you prefer, you can associate a custom list of words with the Hangman control by assigning the path of an XML file to the control's
 WordsUrl property. The XML file should have the following format: </p>
<p>&lt;words&gt; </p>
<p>&lt;word&gt;baby&lt;/word&gt; </p>
<p>&lt;word&gt;easy&lt;/word&gt; </p>
<p>&lt;/words&gt; </p>
<p>The file can contain as many words as you please. </p>
<h3>Creating a Custom Web Control</h3>
<p>The Hangman control is implemented as a custom ASP.NET Web Control. In other words, the control is a class that derives from the base System.Web.UI.WebControls.WebControl class. The Hangman class overrides one method of the base class: the OnPreRender()
 method. </p>
<p>The Hangman control's OnPreRender() method loads the XML, Javascript, sound, and image files. All of these resources are loaded by using the Page.ClientScript.GetWebResourceUrl() method to retrieve a valid URL for the embedded resource.
</p>
<h3>Embedding Images, Sounds, XML, and Javascript</h3>
<p>The Hangman control includes embedded image, sound, XML, and Javascript files. These resources are embedded in the same assembly (dll) as the control so that the control can be distributed with a single assembly.
</p>
<p>There are three steps required for embedding a resource in an assembly: </p>
<p>1) Set the Build Action for the resource to the value Embedded Resource. You set the Build Action for a file by selecting the file, opening the Properties Window, and modifying the Build Action property.
</p>
<p>2) Add a WebResource attribute to the AssemblyInfo file for each embedded resource. When working with Microsoft Visual Basic 2005 Express Edition, select the menu option Project, Show All Files and expand the My Project folder in the Solution Explorer Window
 to view the AssemblyInfo file. When working with Microsoft C# 2005 Express Edition, expand the Properties folder to view the AssemblyInfo file. You need to add the following attribute to embed an image resource named MyImage.gif:
</p>
<p>VB.NET </p>
<p>&lt;Assembly: WebResource(&quot;ProjectNamespace.MyImage.gif&quot;, &quot;image/gif&quot;)&gt; </p>
<p>C# </p>
<p>[Assembly: WebResource(&quot;ProjectNamespace.MyImage.gif&quot;, &quot;image/gif&quot;)] </p>
<p>By default, the ProjectNamespace will be the same as your project name. In the case of the Hangman project, the project namespace is Hangman.
</p>
<p>3) Finally, in your code, you can retrieve a URL to an embedded resource by using the Page.ClientScript.GetWebResourceUrl() method. This method accepts two parameters: a type and a parameter name. Typically, you will pass the type of the current class and
 the name of the embedded resource. For example, you would use the following line of code to get the URL to an image named MyImage.gif located in the Hangman project:
</p>
<p>VB.NET </p>
<p>Dim imageUrl As String = Page.ClientScript.GetWebResourceUrl( this.GetType(), “Hangman.MyImage.gif”)
</p>
<p>C# </p>
<p>string imageUrl = Page.ClientScript.GetWebResourceUrl( me.GetType(), “Hangman.MyImage.gif”);
</p>
<p>Be aware that all resource names are case-sensitive -- even in the case of VB.NET. Make sure that you refer to the name of the resource in the same way with the file name, attribute, and GetWebResourceUrl() method.
</p>
<h3>Cross-Browser Javascript</h3>
<p>All of the logic of the Hangman game is implemented in the Hangman.js Javascript file. When the control loads, the Javascript initializeGame() function is called and all of the game elements are created.
</p>
<p>When you click a letter, the selectLetter() function is called. If a matching letter is found, the display of matching letters is updated. If a matching letter is not found, the badGuessCount variable is updated and the image of the hangman is updated as
 well. </p>
<p>If you win a game, the doWin() function is called and if you lose a game the doLose() function is called. Both functions play a sound and both functions display a link that enables you to restart the game.
</p>
<p>All of the Javascript was written in a cross-browser compatible way. The Javascript code works with Microsoft Internet Explorer, Mozilla Firefox, and Opera. Therefore, the Hangman control works with all three browsers.
</p>
<h3>Conclusion</h3>
<p>The biggest hurdle that I encountered while writing this control was getting the embedded resources to work. Once I resolved the namespace issues and got all of the case-sensitivity issues under control, everything worked out. I was very happy that I was
 able to get all of the resource (including the XML file with the list of words) embedded into one control.
</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Tags/puzzle/RSS&WT.dl=0&WT.entryid=Entry:RSSView:a8ea7fac673445e9af149e7600d59cd4">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Creating-an-ASPNET-Hangman-Control</comments>
      <itunes:summary>



&amp;nbsp;
In this post, Stephen Walther shows you how to create an ASP.NET Hangman control. This control contains embedded images, sounds, XML, and Javascript.



Stephen Walther
Steve&#39;s Blog

Difficulty: Easy
Time Required: 
Less than 1 hour
Cost: Free
Software: Visual Basic or Visual C# Express Editions,Visual Web Developer Express,
Hardware: 
Download: Download








This month, we create an ASP.NET Hangman control. Our control will render all of the necessary images, sounds, and scripts to create a richly interactive hangman game (see Figure 1). Our control will work with the most recent versions of Microsoft Internet
 Explorer, Mozilla Firefox, and Opera. 


We tackle several advanced features of the ASP.NET 2.0 framework in this article. You learn how to build custom controls that take advantage of Javascript. You also learn how to embed resources such as images, sound, and XML in an assembly. Finally, you
 learn how to write cross-browser compatible Javascript. 
Using the Hangman Control
If you are anxious to start playing hangman, you can download the ZIP file that accompanies this article. Click the Download link above.&amp;nbsp;The ZIP file contains two projects: the Visual Basic and the C# versions of the Hangman control. If you are interested
 in viewing or modifying the source code for the Hangman control, you can open the Visual Basic version with Microsoft Visual Basic 2005 Express Edition and the C# version with Microsoft C# 2005 Express Edition.

Here&#39;s how you use the Hangman control. Launch Visual Web Developer 2005 Express Edition and create a new website (select the menu option File, New Web Site). Next, add the control to your Toolbox by right-clicking beneath the General tab on your Toolbox
 and selecting the option Choose Items (see Figure 2). You must have a Web Form Page open in order to modify the Toolbox.&amp;nbsp;



Next, under the .NET Framework Components tab, click the Browse button and browse to the Hangman assembly (dll file). There is </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Creating-an-ASPNET-Hangman-Control</link>
      <pubDate>Sun, 25 Feb 2007 04:50:59 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Creating-an-ASPNET-Hangman-Control</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1756233_100.jpg" height="75" width="100"/>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/1756233_220.jpg" height="165" width="220"/>      
      <dc:creator>Stephen Walther</dc:creator>
      <itunes:author>Stephen Walther</itunes:author>
      <slash:comments>18</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Creating-an-ASPNET-Hangman-Control/RSS</wfw:commentRss>
      <category>Web</category>
      <category>puzzle</category>
    </item>
  <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/Tags/puzzle/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 define t</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 url="http://ecn.channel9.msdn.com/o9/c4f/images/1178235_220.jpg" height="165" width="220"/>      
      <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/Tags/puzzle/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 ava</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 url="http://ecn.channel9.msdn.com/o9/c4f/images/1178206_220.jpg" height="165" width="220"/>      
      <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/Tags/puzzle/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;/GeometryDrawing.G</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 url="http://ecn.channel9.msdn.com/o9/c4f/images/1178193_220.jpg" height="165" width="220"/>      
      <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/Tags/puzzle/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 ex</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 url="http://ecn.channel9.msdn.com/o9/c4f/images/999781_220.jpg" height="165" width="220"/>      
      <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/Tags/puzzle/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 Febru</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 url="http://ecn.channel9.msdn.com/o9/c4f/images/999502_220.jpg" height="165" width="220"/>      
      <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>
