SilverlightShow: Silverlight Community http://www.silverlightshow.net/ Silverlight articles, Silverlight tutorials, Silverlight videos, Silverlight samples SilverlightShow.net http://www.rssboard.org/rss-specification Argotic Syndication Framework 2008.0.2.0, http://www.codeplex.com/Argotic en-US estoychev@completit.com (Emil Stoychev) Windows 8 Development + Blendability <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Windows-8-Development-Blendability.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Windows-8-Development-Blendability.aspx" data-count="horizontal" data-text="Reading the video supported article '#Windows8 Development + Blendability' #win8dev" data-url="http://slshow.net/ZzyHfH">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Windows-8-Development-Blendability.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <div style="border: 1px solid #dddddd; background-color: #f3f3f3; margin-top: 5px; margin-left: 150px; padding-left: 10px; padding-top: 10px; width: 400px; text-align: center;"><strong><a href="http://www.silverlightshow.net/Storage/Sources/PuzzleSampleCode.zip">Download the source code for this article</a></strong> <ul> </ul> </div> <h1>Introduction</h1> <p>Expression Blend is a “black unknown tool” for many XAML developers. Many geeks (including myself) tended to say things like “Hey ! I’m happy just coding XAML”, “This is for graphic designers”, “It doesn’t generate clean code”.</p> <p>In this video article we are going to try to demystify this tool for developers, we will learn some basic features that will show us how we can boost our productivity. As a vehicle to explain the concepts and techniques here exposed we are going to write from scratch the following dummy puzzle app:</p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; margin-right: 5px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/video/MVVM-in-Win8-Webinar.aspx" target="_self">Recording of the webinar: MVVM in Windows 8 with Gill Cleeren</a></li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/video/Advanced-WinRT-Webinar-Part-2.aspx">Recording of the webinar: Advanced Windows 8 Metro Part 2</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/win8_future_xaml.aspx" target="_self">Ebook by Gill Cleeren: Windows 8 and the Future of XAML</a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/win8_future_xaml.aspx" target="_self"><img style="width: 70px; height: 99px;" alt="Ebook: Windows 8 and the future of XAML" src="http://www.silverlightshow.net/Storage/ebooks/win8_xaml_cover.png" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <p> </p> <h4>Video: <a href="http://www.silverlightshow.net/video/Win8-Puzzle-App-Intro.aspx">Win8 Puzzle App - Intro</a></h4> <p> </p> <p>Takeaways from this article:</p> <ul> <li>How to create your UI using Expression Blend without having to manually code a single line of XAML. </li> <li>How to assign data binding via properties tab (no more typo-bug when adding a binding). </li> <li>How to display sample data to allow you fine tune your layout without having to run the app to check the visual aspect. </li> <li>How to drop controls and customize them (ListView + GridView). </li> <li>How to visually create and customize controls templates. </li> <li>How to assign Converters via properties. </li> </ul> <p> </p> <h1>Step 1 – Creating the App + Display the list of pieces</h1> <p> </p> <p>In this step we will check how we can apply data binding and display sample data in design mode. We will start by creating the project, and adding a list with the pieces of the puzzle.</p> <p>We are going to follow the next steps:</p> <ol> <li>Create the project (we will use Visual Studio, we are geeks). </li> <li>Create an entity that will identify a puzzle piece. </li> <li>Create a ViewModel that will hold the list of pieces (we will add to it more properties and methods in later steps). </li> <li>Drop a List View. </li> <li>Assign Data Context… plus Design Data Context </li> <li>Apply Data Binding to a control. </li> <li>Modify items template. </li> <li>Apply Data Binding to a control template. </li> <li>Run the app same results as design. </li> </ol> <p> </p> <h4>Video: <a href="http://www.silverlightshow.net/video/Win8-Puzzle-App-CreatingProjectListView.aspx">Win8 Puzzle App - CreatingProjectListView</a></h4> <p> </p> <h1>Step 2 – Adding a canvas to build the puzzle</h1> <p>We are going to learn how to customize a GridView using the properties panel and define custom templates. In order to setup the puzzle canvas, we will drop a GridView control, establish the right size and aspect and setup the data binding.</p> <p>Note: a GridView won’t be the ideal control to be used for a Puzzle Canvas, but I have rather chosen it to get us familiar with this standard control (the goal of the article is to let us learn about Win 8 + Blendability).</p> <p>We are going to follow the next steps:</p> <ol> <li>Add the plumbing in the ViewModel to hold the puzzle canvas info. </li> <li>Drop a GridView. </li> <li>Configure Items container to hold a 2x2 pieces canvas. </li> <li>Configure the Items Template to be binded to a single puzzle slot + binding. </li> </ol> <p> </p> <h4>Video: <a href="http://www.silverlightshow.net/video/Win8-Puzzle-App-PuzzleCanvas.aspx">Win8 Puzzle App - PuzzleCanvas</a></h4> <p> </p> <h1>Step 3 – Drag & Drop Behavior</h1> <p> </p> <p>One cool feature that we get when we develop  a Windows 8 app it’s the “AllowDrop” “CanDragItems” properties that are already included into the controls. In this snippet we will setup the drag & drop operations for different combinations of controls (puzzle list  >> puzzle canvas, puzzle canvas >> puzzle list view, puzzle canvas >> puzzle canvas).</p> <p>We are going to follow the next steps:</p> <ol> <li>Create the ViewModel methods to update the puzzle canvas and pieces bucket. </li> <li>Add Names for the controls (some code in the view going on). </li> <li>Setup Drag & Drop list view. </li> <li>Setup Drag & Drop elements of the GridView. </li> <li>Drag from the Piece’s available list into the puzzle canvas. </li> </ol> <p> </p> <h4>Video: <a href="http://www.silverlightshow.net/video/Win8-Puzzle-App-Drag-and-Drop-1.aspx">Win8 Puzzle App - Drag and Drop #1</a></h4> <p> </p> <p>Dragging and Dropping other cases</p> <blockquote></blockquote> <ol> <li>Drag & Drop puzzle canvas to puzzle canvas. </li> <li>Drag & Drop puzzle canvas to piece’s list view </li> </ol> <p> </p> <h4>Video: <a href="http://www.silverlightshow.net/video/Win8-Puzzle-App-Drag-and-Drop-2.aspx">Win8 Puzzle App - Drag and Drop #2</a></h4> <p> </p> <h1>Step 4 – Notifications, Converters & Blend</h1> <p> </p> <p>In this final step, we will learn how automatically refresh the user interface when a property changes (via INotifyPropertyChange), and how to apply a converter without having to type a single line of code. We will add a boolean property that will notify the user interface when the puzzle has been solved ad we will map the original viewModel property value from bool to visibility (display or hide a textblock).</p> <p>we are going to follow the next steps:</p> <ol> <li>ViewModel, create a function to check if the puzzle is solved and expose it via property. </li> <li>INotify Property Changed plumbing. </li> <li>Adding a Textbox to notify the user… Visibility to Bool? </li> <li>Adding a converter, assigning it via properties. </li> </ol> <p> </p> <h4>Video: <a href="http://www.silverlightshow.net/video/Win8-Puzzle-App-Converters.aspx">Win8 Puzzle App - Converters</a></h4> <p> </p> <h1>Summary</h1> <p> </p> <p>In this article we have learnt how we developers can take benefit of using Expression Blend, letting us design our user interface by dragging and dropping and having available test data in design mode. Most of the topics covered in this article can be applied to the newest Visual Studio 2012 IDE as well.</p> http://www.silverlightshow.net/items/Windows-8-Development-Blendability.aspx editorial@silverlightshow.net (Braulio Diez ) http://www.silverlightshow.net/items/Windows-8-Development-Blendability.aspx#comments http://www.silverlightshow.net/items/Windows-8-Development-Blendability.aspx Thu, 15 Nov 2012 13:50:00 GMT Near Field Communication in Windows 8: Part 2 <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Near-Field-Communication-in-Windows-8-Part-2.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Near-Field-Communication-in-Windows-8-Part-2.aspx" data-count="horizontal" data-text="Reading #SilverlightShow article 'Near Field Communication in #Windows8: Part 2' #win8 #win8dev #nfc" data-url="http://slshow.net/Rf37Or">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Near-Field-Communication-in-Windows-8-Part-2.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p>In the <a href="http://www.silverlightshow.net/items/Near-Field-Communication-in-windows-8-part-1.aspx">first part</a> of this article series we have described the main concepts of Near Field communication and how Microsoft has provided support for this technology in Windows 8. Then we have seen how to set up two Windows 8 virtual machines with a proximity driver, <em>i.e</em> something which allows us to simulate a tap gesture. In this second part we will learn how to use the sample proximity driver and explore the functionalities exposed by the Proximity API.</p> <p> </p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; margin-right: 5px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/news/Free-SilverlightShow-Webinar-on-Oct-16-MVVM-in-Windows-8.aspx">Upcoming Webinar: MVVM in Windows 8</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-1.aspx">The article series: Windows 8 Metro Apps: The 8 Must-Know Tricks</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/datagrid_control.aspx">Ebook by W. Ferrari: Building a DataGrid Control for Silverlight for Windows Phone</a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/datagrid_control.aspx" target="_self"><img alt="Ebook: Building a DataGrid Control for Silverlight for Windows Phone" src="http://www.silverlightshow.net/Storage/Ebooks/datagrid_ebook_thumb.png" style="width: 100px; height: 140px;" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <h3>NetNfpControl: a testing tool to simulate a proximity event</h3> <p>As already described in the first part, we can use a sample proximity driver to simulate a tap gesture. We found the sample <em>netnfp</em> solution in the Windows 8 Driver Samples package. In this solution, together with the driver and the package for the driver projects, there is also a project, <em>NetNfpControl</em>, containing a testing tool to simulate proximity hardware. </p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/clip_image002_2.jpg"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="clip_image002" alt="clip_image002" src="http://www.silverlightshow.net/Storage/Users/walterf/clip_image002_thumb.jpg" width="236" height="244" /></a></p> <p> </p> <p>This project creates a command-line app “NetNfpControl.exe” with three operating modes depending on the command-line parameter used.</p> <p>1) NetNfpControl.exe [<remoteMachine>] <br /> → this operating mode allows us to specify either a remote machine name or an IpV6 address which the local machine can connect with and simulate a proximity event.</p> <p>2) NetNfpControl.exe [/k] <br /> → in this operating mode the app registers a Ctrl-F1 hotkey at the startup. Since there is no remote machine specified, you have to run the app on both the machines you want to be in proximity. The two machines know each other by using a private share where they have written its network name in a file. Since the file lifetime is 2 seconds, you have to press CTRL-F1 more or less at the same time on both machines. The share is hardcoded, as you may see in the code snippet below. This means you have to change it and recompile it in order to use your share.</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet"><span style="color: #0000ff;">void</span> Proximity()<br />{<br /> wprintf(L<span style="color: #006080;">"Checking For Proximate Device\n"</span>);<br /><br /> SYSTEMTIME sysTime = {};<br /> GetLocalTime(&sysTime);<br /><br /> wchar_t szDirectory[MAX_PATH];<br /> StringCchPrintf(szDirectory, MAX_PATH, L<span style="color: #006080;">"\\\\scratch2\\scratch\\travm\\proxrendezvous\\%u%02u%02u-%02u"</span>, <br /> sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour);<br /> <br /> CreateDirectory(szDirectory, NULL);<br /> <br /> wchar_t szLockPath[MAX_PATH];<br /> StringCchPrintf(szLockPath, MAX_PATH, L<span style="color: #006080;">"%s\\lock.txt"</span>, szDirectory);<br /><br /> HANDLE hLock = AcquireFileLock(szLockPath);<br /> <br /> wchar_t szOtherMachine[MAX_PATH] = {};<br /> <span style="color: #0000ff;">if</span> (hLock != INVALID_HANDLE_VALUE)<br /> {<br /> wprintf(L<span style="color: #006080;">"looking for available devices in proximity.\n"</span>);<br /> wchar_t szFindPath[MAX_PATH];<br /> StringCchPrintf(szFindPath, MAX_PATH, L<span style="color: #006080;">"%s\\*.available"</span>, szDirectory);<br /> WIN32_FIND_DATA findData;<br /> HANDLE hFind = FindFirstFile(szFindPath, &findData);<br /> <br /> wchar_t szFilePath[MAX_PATH];<br /> <span style="color: #0000ff;">bool</span> fClient;<br /> <span style="color: #0000ff;">if</span> (hFind != INVALID_HANDLE_VALUE)<br /> {<br /> fClient = <span style="color: #0000ff;">true</span>;<br /> <br /> wprintf(L<span style="color: #006080;">"Proximate device found: "</span>);<br /> StringCchPrintf(szFilePath, MAX_PATH, L<span style="color: #006080;">"%s\\%s"</span>, szDirectory, findData.cFileName);<br /> HANDLE hFile = CreateFile(szFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);<br /> <span style="color: #0000ff;">if</span> (hFile != INVALID_HANDLE_VALUE)<br /> {<br /> DWORD ignore;<br /> (<span style="color: #0000ff;">void</span>)ReadFile(hFile, szOtherMachine, <span style="color: #0000ff;">sizeof</span>(szOtherMachine) - <span style="color: #0000ff;">sizeof</span>(wchar_t), &ignore, NULL);<br /> szOtherMachine[MAX_PATH-1] = L<span style="color: #006080;">'\0'</span>;<br /> CloseHandle(hFile);<br /> }</pre> <br /> </div> <p> </p> <p>3) NetNfpControl.exe [<remoteMachine>] [/k]</p> <p>→ this operating mode allows us to simulate a near-field proximity event with the remote machine specified by pressing CTRL-F1, even if the app is in the background. The proximity is simulated for 1 second, then the app exits proximity.</p> <p> </p> <p>Since these operating modes don’t seem to be very comfortable for my needs I slightly modified the code to allow a fourth operating mode:</p> <p>4) NetNfpControl.exe [<remoteMachine>] [/k]</p> <p>→ this modified operating mode allows us to simulate a near-field proximity event with the remote machine by pressing CTRL-F1, the proximity keeps on until you press CTRl-F1 again. You can re-enter proximity by pressing CTRL-F1 once again. In this way it is very easy to simulate the arrival or departure of a proximity device. The modified solution is available <a href="http://www.snello.it/Samples/Win8_proximity/netnfpprovider.zip">here</a> </p> <p>To recap, if you follow the steps in part 1 of the article you should have two VMs with Windows 8 with the proximity sample driver installed and working on both. The two VMs should be in the same network to allow communication. Having checked this, you can emulate the proximity event by launching NetNfpControl on one of the two VMs as shown below:</p> <p>NetNfpControl.exe <em>remoteVM_name /k</em></p> <p>and press CTRL-F1 when you run your (proximity enabled) Metro app on the other VM (or both VMs if it is the case).</p> <p> </p> <h3>Building Metro apps “proximity enabled”</h3> <p>To enable your Metro app to use proximity classes, simply add the following capability in the Package.appxmanifest file: </p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/manifestProximity_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="manifestProximity" alt="manifestProximity" src="http://www.silverlightshow.net/Storage/Users/walterf/manifestProximity_thumb.png" width="644" height="484" /></a> </p> <p> </p> <p>and add the appropriate <em>using</em> directive in your code files:</p> <p><em>using Windows.Networking.Proximity;</em></p> <p>That’s all: you are now ready to use the Proximity API. In the next paragraphs we will learn how to use the classes in the API by simulating some of the “Tap And Do” scenarios that Microsoft described in its “Windows 8 Near Field Proximity Implementation Specification”.</p> <p><strong></strong></p> <h3>Simulating Tap And Use</h3> <p>In the “Tap And Use” use case (see first part of the article for further details), a user running an app on his PC will be able to trigger collaboration with the same app running on another machine when the two users tap their machines. </p> <p>First of all, what we need is something which notifies us when a device is in proximity. The <em>ProximityDevice</em> class contains all the necessary elements to accomplish that. In the code snippet below we obtain a reference to the default proximity device installed in our machine and we use that reference to create two event handlers for the device arrived and departed events. </p> <p><strong></strong></p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet">proximityDevice = ProximityDevice.GetDefault();<br /><br /><br /><span style="color: #0000ff;">if</span> (proximityDevice != <span style="color: #0000ff;">null</span>)<br />{<br /> proximityDevice.DeviceArrived += ProximityDeviceArrived;<br /> proximityDevice.DeviceDeparted += ProximityDeviceDeparted;<br /><br /> WriteMessageText(<span style="color: #006080;">"Proximity device initialized.\n"</span>);<br />}<br /><span style="color: #0000ff;">else</span><br />{<br /> WriteMessageText(<span style="color: #006080;">"Failed to initialized proximity device.\n"</span>);<br />}</pre> <br /> </div> <p> </p> <p>Since a machine can potentially contain more than one proximity device (<em>i.e.</em> 2 devices positioned on two diagonally opposite corners of a tablet) there are also methods to enumerate the devices but it is not our case since we are using a proximity sample driver. </p> <p>Now that we know how to be notified of devices in close proximity, we need to know when one of the two users initiated a tap gesture. To learn this, we can use the <em>PeerFinder</em> static class which exposes some useful methods and properties. First of all, let’s see which discovery options are available in our machine. The <em>PeerFinder.SupportedDiscoveryTypes()</em> method suits us: it can return <em>None </em>if we don’t have any proximity device installed,<em> Browse</em> if we have a WiFI-Direct enabled device, or <em>Triggered</em> if we have a proximity device on board. In our VM with the proximity sample driver installed this method returns the third option, <em>Triggered</em>. This means that we can use the <em>PeerFinder.TriggeredConnectionStateChanged</em> event to intercept a Tap gesture but we cannot use the <em>PeerFinder.PeerFinder.FindAllPeersAsync()</em> for browsing for Peers in the neighborhood.</p> <p>In the code snippet below we attach the callback handler and start listening for proximate devices.</p> <p> </p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet"><span style="color: #0000ff;">if</span>(PeerFinder.SupportedDiscoveryTypes == PeerDiscoveryTypes.Triggered)<br /> PeerFinder.TriggeredConnectionStateChanged += PeerFinder_TriggeredConnectionStateChanged;<br />PeerFinder.Start();</pre> <br /> </div> <p> </p> <p>In the TriggeredConnectionStateChanged event handler we can check what is going on through the State property of the TriggeredConnectionStateChangedEventArgs object. This property can assume five values: PeerFound, Listening, Connecting, Completed, Failed. The image below shows the progress of a proximity connection when a tap gesture is made on one of the two devices in proximity.</p> <p> </p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/state_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="state" alt="state" src="http://www.silverlightshow.net/Storage/Users/walterf/state_thumb.png" width="256" height="482" /></a></p> <p> </p> <p>When a user makes a tap gesture on one of the two devices in proximity, a first event is triggered and the state property assumes the “PeerFound” value. After this stage it is no longer necessary for the two devices to be in the proximity range since the incoming connection will be established over TCP/IP or Bluetooth. By the way, this is exactly one of the features of NFC, <em>i.e.</em> a technology that can act as an enabler agent for more capable wireless connections. </p> <p>In the following event triggered, the State property can be “Connecting” if the tap gesture occurs on your device or “Listening” otherwise. The final event indicates us whether the connection was established or not. If it is, then we can get a reference to a StreamSocket object to communicate with the other device. </p> <p>That’s all: our app can be a game (for instance, a battleship game) , a chat or whatsoever that requires exchange of information between the two devices. With a StreamSocket we can manage this kind of requirements.</p> <p>Returning to the title of this section, how can we simulate the scenario above using the two virtual machines we have configured in the first part of the article?</p> <p>I prepared an application skeleton which I called “Tap And Do”: it collects four Tap And Do use cases as shown in the image below:</p> <p> </p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/TapAndDo_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="TapAndDo" alt="TapAndDo" src="http://www.silverlightshow.net/Storage/Users/walterf/TapAndDo_thumb.png" width="431" height="480" /></a></p> <p> </p> <p>You can find the source code <a href="http://www.snello.it/Samples/Win8_proximity/tapanddo.zip">here</a>.</p> <p>Follow the steps below to simulate this scenario:</p> <p>1. Run the virtual Machines. For simplicity, let’s suppose that their network name is VM1 and VM2.</p> <p>2. Build the NetNfpControl app using the source code modified as described in the previous section and launch it on one of the two VM, for instance VM1 using the following command-line parameters:</p> <p>NetNfpControl.exe <em>/k VM2</em></p> <p>3. Open the Tap And Do solution on both VMs, compile and launch the app</p> <p>4. Click on “Tap And Use” title on both VM, the apps are ready to communicate</p> <p>5. Press CTRL-F1 on VM1 (remember this is a hotkey registered by NetNfpControl) to simulate a tap gesture from VM2</p> <p>6. If it is all OK, you should see an output similar to the two below for VM1 and VM2:</p> <p> </p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/clip_image002%5B8%5D.jpg"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="clip_image002[8]" alt="clip_image002[8]" src="http://www.silverlightshow.net/Storage/Users/walterf/clip_image002%5B8%5D_thumb.jpg" width="244" height="144" /></a><a href="http://www.silverlightshow.net/Storage/Users/walterf/clip_image002%5B6%5D.jpg"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="clip_image002[6]" alt="clip_image002[6]" src="http://www.silverlightshow.net/Storage/Users/walterf/clip_image002%5B6%5D_thumb.jpg" width="244" height="144" /></a> </p> <p> </p> <p>The log in yellow is particularly interesting because it reveals the temporal sequence of the events. First, the local proximity device is initialized, then the simulated tap gesture is caught by the “device arrived” event handler. In this handler we launch <em>PeerFinder.Start()</em> as we have seen in the previous paragraph. The <em>TriggeredConnectionStateChanged</em> event is then triggered twice, one for “PeerFound” and one for “Listening” or “connecting” depending on which device initiated the gesture. At this stage it is interesting to notice that I pressed CTRL-F1 again to exit proximity and this happened before the connection was fully established. This did not hinder the completion of the connection on both devices, because as we have already seen, after the “PeerFound” message the connection is performed over TCP/IP (or Bluetooth).</p> <h3>Simulating Tap And Launch</h3> <p>In the “Tap And Launch” use case (see first part of the article for further details), the user running an app can invite another user to run the same app by tapping his PC to another device. The second user will be invited to launch the same app. </p> <p>This use case is simpler to simulate than the previous one. The steps are the same as above except for step 4 where you have to start the TapAndDo app just in one of the two VMs. If you do so and PRESS CTRL-F1, you should see an invitation popup asking you to start the TapAndDo app as appears below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/StartingApp_4.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="StartingApp" alt="StartingApp" src="http://www.silverlightshow.net/Storage/Users/walterf/StartingApp_thumb_1.png" width="640" height="346" /></a></p> <p> </p> <p>If you look at the log in yellow on VM1 you notice the “Device arrived” event and then the “PeerFound” and “Listening” states of the <em>TriggeredConnectionStateChanged</em> event. If at this stage you press CTRL-F1 again to exit proximity, you will notice that the connection will not be lost until either a timeout is reached or the user of VM2 clicks on the invitation to launch the app. </p> <p>When the app in VM2 starts, it receives a <em>TriggeredConnectionStateChanged</em> event with a reference to the socket created by the app in VM1. At this stage the two VMs are connected and can start the information exchange. In the yellow log of the image below you can see some details of the streamsocket created on both VMs.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/TapAndLaunchCompleted_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="TapAndLaunchCompleted" alt="TapAndLaunchCompleted" src="http://www.silverlightshow.net/Storage/Users/walterf/TapAndLaunchCompleted_thumb.png" width="640" height="351" /></a></p> <p> </p> <h3>Simulating Tap And Acquire</h3> <p>Tap And Acquire use case regards the case where one user invites a friend to start the same app, but his friend does not have the app installed and he is invited to acquire the app (maybe from the Windows Store). Simulating this is fairly simple with the tools described in the previous paragraphs, therefore it is left to the reader as a challenge (see the dedicated box below). </p> <p><strong></strong></p> <h3>Simulating Tap And Share and Tap And Receive</h3> <p>Tap and Share describes the case when a user taps his device to another device to share content such as the URL of a webpage or a document. Tap And Receive is similar: in this case the user taps his device to another device (such as a PC or phone) or object (such as a tag) to receive its shared content upon user confirmation. In both cases the communication is established by using a publish/subscribe model. When an app publishes a message, it is put at the disposal of other apps in other devices. When these devices enter proximity, they can subscribe to that message and receive it. Both the publisher and the subscriber have to use the same message type. The <a href="http://msdn.microsoft.com/en-us/library/windows/apps/br241212.aspx">ProximityDevice class</a> exposes some methods to use this model such as <em>PublishMessage(..)</em> and <em>SubscribeForMessage(...)</em>.</p> <p>Simulating these scenarios is left to the reader as a challenge (see the dedicated box below). <strong></strong></p> <h3> </h3> <h3>Conclusion</h3> <p>In this second part of the “Windows Near Field Communication in Windows 8” we have learned how to use the proximity sample driver described in part one and we have simulated some scenarios included in the “Tap And Do” Microsoft interpretation. </p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px; text-align: center;"><em><strong>Want to test your understanding of this article? Walter Ferrari challenges you to prove you got it all right! </strong></em><em><strong>Take the two challenges below:  <br />  <br /> <table> <tbody> <tr> <td><a href="http://www.ideedit.com/challenges/Try-to-establish-a-proximity-connection" target="_blank"><img alt="" src="http://www.silverlightshow.net/Storage/deed/img2_virtual.png" /></a> </td> <td style="text-align: center; vertical-align: top;"><a href="http://www.ideedit.com/challenges/Try-to-establish-a-proximity-connection" target="_blank">Establish a proximity connection <br /> between virtual machines</a><br /> </td> <td style="text-align: center; vertical-align: top;">     </td> <td><a href="http://www.ideedit.com/challenges/Simulating-a-Tap-and-Share-scenario-by" target="_blank"><img alt="" src="http://www.silverlightshow.net/Storage/deed/img3_tap.png" /></a> </td> <td style="text-align: center; vertical-align: top;"><a href="http://www.ideedit.com/challenges/Simulating-a-Tap-and-Share-scenario-by" target="_blank">Simulate a "Tap and Share"<br /> scenario</a> </td> </tr> </tbody> </table> <table align="center"> <tbody> <tr> <td style="text-align: center; vertical-align: top;"><span style="font-size: 10px;"><em>Challenges powered by</em></span> <a href="http://www.ideedit.com/" target="_blank"><img alt="" src="http://www.silverlightshow.net/Storage/deed/deed_logo_transparent_40.png" /></a><em><strong><br /> </strong></em></td> </tr> </tbody> </table> <table> <tbody> </tbody> </table> </strong></em></div> http://www.silverlightshow.net/items/Near-Field-Communication-in-Windows-8-Part-2.aspx editorial@silverlightshow.net (Walter Ferrari ) http://www.silverlightshow.net/items/Near-Field-Communication-in-Windows-8-Part-2.aspx#comments http://www.silverlightshow.net/items/Near-Field-Communication-in-Windows-8-Part-2.aspx Wed, 10 Oct 2012 19:33:00 GMT Near Field Communication in Windows 8: Part 1 <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Near-Field-Communication-in-windows-8-part-1.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Near-Field-Communication-in-windows-8-part-1.aspx" data-count="horizontal" data-text="Reading #SilverlightShow article 'Near Field Communication in #Windows8: Part 1' #win8 #win8dev #nfc" data-url="http://slshow.net/SnRMdr">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Near-Field-Communication-in-windows-8-part-1.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p><a href="http://ads.silverlightshow.net/a.aspx?ZoneID=85&Task=Click&Mode=HTML&SiteID=1&PageID=94820" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=85&Task=Get&Mode=HTML&SiteID=1&PageID=94820" width="0" height="0" style="border-width: 0px; border-style: solid;" /></a></p> <p>Near fied communication (NFC) is a breakthrough technology aimed at facilitating communication between two devices in close proximity, within a 4-cm distance. In Windows 8 the support for this technology has been included in a broader application scope that Microsoft named Near Field Proximity. This article will give you a general view of NFC explaining how Microsoft has reinterpreted it, and we will learn how to build an environment by using 2 virtual machines to test the classes contained in the namespace Windows.Networking.Proximity.</p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; margin-right: 5px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/news/Free-SilverlightShow-Webinar-on-Oct-16-MVVM-in-Windows-8.aspx">Upcoming Webinar: MVVM in Windows 8</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-1.aspx">The article series: Windows 8 Metro Apps: The 8 Must-Know Tricks</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/datagrid_control.aspx">Ebook by W. Ferrari: Building a DataGrid Control for Silverlight for Windows Phone</a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/datagrid_control.aspx" target="_self"><img alt="Ebook: Building a DataGrid Control for Silverlight for Windows Phone" src="http://www.silverlightshow.net/Storage/Ebooks/datagrid_ebook_thumb.png" style="width: 100px; height: 140px;" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <h3>What is NFC?</h3> <p>In a nutshell NFC is a short range wireless communication system between two NFC enabled  devices. The communication occurs at a 13.56 Mhz frequency, the same as the Radio Frequency Identification (RFID). As opposed to RFID, NFC works only in conditions of proximity, i.e. few centimeters. <br /> The difference lies in the fact that NFC enabled devices can be mobile phones, tablets, PCs, NFC readers and NFC passive tags. This variety of devices opens the door to various applications and services like identification, access control, e-payment, e-ticketing, health data access and so on. In other words Near fied communication (NFC) is a technology with a potentially major impact on people’s economic and social life. It can be seen as something that simplifies the daily human life.  </p> <p>Let me describe a possible scenario: imagine to wake up in the morning for another workday, take your NFC enabled mobile phone and go to the train station, and to open the turnstile just put your mobile phone close to a NFC reader. To enter your office building you simply use your mobile to punch the clock. In the morning you have a meeting with a new customer: you can swap your business cards by simply approaching your card to his/her NFC-enabled mobile. Then if you wish to offer him/her a coffee from a vending machine, simply approach your phone to the NFC symbol exposed on the machine and you can process the payment </p> <p>One of the primary information source on NFC is the NFC Forum (<a href="http://www.nfc-forum.org/">http://www.nfc-forum.org</a>). </p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/_clip_image002_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="clip_image002" alt="clip_image002" src="http://www.silverlightshow.net/Storage/Users/walterf/_clip_image002_thumb.png" width="144" height="125" /></a>The NFC Forum was established to specify the NFC standards based on ISO/IEC standards and to promote the NFC technology thus providing guidance on the interoperability among devices and services. In the “specifications” section of the forum you can find all the technical documents which describe protocols, data exchange format and so on. </p> <p>Regarding the NFC core capabilities, and consequently the interoperability amongst devices, three methods are foreseen for applications using NFC: <strong></strong></p> <p> </p> <ol> <li><strong>Card emulation Mode</strong> <br /> This mode allows a NFC device to work as a contact-less smart card (i.e. a credit card). This feature can be used in applications for payments, e-ticketing and so on. <br /> <strong></strong></li> <li><strong>Peer-to-Peer Mode</strong> <br /> This mode enables two NFC devices to exchange data using a bidirectional half duplex communication. From the point of view of the users, this mode simplifies information sharing: they just have to tap together their NFC devices with no need for any prior setup.   <br /> <strong></strong></li> <li><strong>Reader/Writer Mode</strong> <br /> This mode allows an active NFC device to read from/write to a passive NFC tag. Typical examples are applications for smart posters. </li> </ol> <p> </p> <p>The image below shows the underlying layers:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/NFC_layers_2.jpg"><img style="display: inline;" title="NFC_layers" alt="NFC_layers" src="http://www.silverlightshow.net/Storage/Users/walterf/NFC_layers_thumb.jpg" width="640" height="382" /></a></p> <h6>(source: <a href="http://www.nfc-forum.org/">http://www.nfc-forum.org</a>)</h6> <p>The question that may come to mind is now: is this technology widely adopted, or will it be? is it worth learning more about this topic from the point of view of a developer? Judging from the list of </p> <p>NFC phones already on the market (<a href="http://www.nfcworld.com/nfc-phones-list/#available">http://www.nfcworld.com/nfc-phones-list/#available</a>) and the list of newer phones coming soon (<a href="http://www.nfcworld.com/nfc-phones-list/#soon">http://www.nfcworld.com/nfc-phones-list/#soon</a>) the answer is yes. Let’s learn how Microsoft is addressing this topic in the next paragraph.</p> <p> </p> <h3>The Microsoft interpretation: “Tap and Do”</h3> <p>According to first rumors Microsoft may be including NFC support in Windows 8 raised in September 2011 as announced by <a href="http://www.nxp.com/news/press-releases/2011/09/nxp-s-nfc-solution-supports-windows-8.html">NXP</a>. Later, in February 2012, Microsoft published a document entitled “Windows 8 Near Field Proximity Implementation Specification”, available <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/hh770524">here</a>. It is mainly intended for system integrators and it provides guidelines and requirements that reveal the “Microsoft vision” on NFC. It is worth giving it a read. In this white paper Microsoft defines the communication between two devices in close proximity using a level of abstraction called “Tap and Do”.</p> <p>Literally the definition of “Tap and Do” is:</p> <p><em>“A gesture that is a natural interaction between people in close proximity used to trigger doing something together between the devices they are holding.”</em></p> <p>It sounds very similar to the general concept of NFC but in the vision of Microsoft it is something more general. It stands on a system called Near Field Proximity (NFP) provider model. This NFP provider model is a common surface for all the NFP scenarios and use cases, and hides the underlying technology which could be NFC, WI-Direct, Bluetooth or something else. the image below shows the three layers:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/NFP_model_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="NFP_model" alt="NFP_model" src="http://www.silverlightshow.net/Storage/Users/walterf/NFP_model_thumb.png" width="430" height="225" /></a></p> <p> </p> <p>The NFP scenarios taken into consideration are the “Ad-Hoch interaction in the Real World” and the “peripheral Wireless Device Setup”. The first fills a gap of Windows and provides an easy way to make two devices communicate together. The second one regards the user experience while installing wireless peripheral devices in Windows. With “Tap and Do” it is stated that this has been extremely simplified.</p> <p>What about the use cases? “Tap and Do” gesture is the “compendium” of the case uses in the table below:</p> <p> </p> <table border="0" cellspacing="0" cellpadding="2" width="705"> <tbody> <tr> <td valign="top" style="width: 201px;"><strong>Use case</strong></td> <td valign="top" style="width: 502px;"><strong>Description</strong></td> </tr> <tr> <td valign="top" style="width: 201px;">Tap and Setup</td> <td valign="top" style="width: 502px;">Tap and pair and set up a peripheral wireless device with Windows</td> </tr> <tr> <td valign="top" style="width: 201px;">Tap and Reconnect </td> <td valign="top" style="width: 502px;">Tap and reconnect a previously paired and set-up device with Windows</td> </tr> <tr> <td valign="top" style="width: 201px;">Tap and Use </td> <td valign="top" style="width: 502px;">Tap and connect your app with one running on another machine</td> </tr> <tr> <td valign="top" style="width: 201px;">Tap and Launch </td> <td valign="top" style="width: 502px;">Tap and invite a user on another machine to launch an app you’re running</td> </tr> <tr> <td valign="top" style="width: 201px;">Tap and Acquire </td> <td valign="top" style="width: 502px;">Tap and invite a user on another machine to obtain an app you’re running</td> </tr> <tr> <td valign="top" style="width: 201px;">Tap and Share </td> <td valign="top" style="width: 502px;">Tap and share content you have selected to another device</td> </tr> <tr> <td valign="top" style="width: 201px;">Tap and Receive </td> <td valign="top" style="width: 502px;">Tap and receive content from another device or poster</td> </tr> </tbody> </table> <p> </p> <p>Here is a short description of each of these:</p> <p><strong>Tap and Setup e Tab and Reconnect -> </strong>two use cases for installation and unidirectional pairing of wireless peripherals; placing a peripheral (a wireless keyboard or headphone etc) near a PC triggers the device setup or reconnection.</p> <p><strong>Tap and Use</strong> -> it occurs when for instance two users are running the same app (say a battleship game) and tap their PCs toghether; this action triggers an event that can be handled by the two apps to communicate toghether. <strong></strong></p> <p><strong>Tap and Launch</strong> -> this case is particularly intriguing because, when in proximity, one app running on one PC can invite the user of the other PC to start the same app, if installed.<strong></strong></p> <p><strong>Tap and Acquire</strong> -> similar to the previous case but here the second user does not have the app installed and so he is invited to acquire and install the app.<strong></strong></p> <p><strong>Tap and Share</strong> -> imagine you are visiting a website and want to share it with your friend; just tap your PC to the PC (or phone or tablet) of your friend and he will receive a confirmation request to accept the shared </p> <p>URL.<strong></strong></p> <p><strong>Tap and Receive</strong> -> with this user case a user can tap his PC to another device (a PC, phone or even a passive tag) which is exposing content, and he is invited to receive that content.</p> <p> </p> <h3>The Windows.Networking.Proximity namespace</h3> <p>In the previous paragraph we have seen that a unique Near Field proximity (NFP) provider model is expected for all the underlying wireless technology used. For developers this means good news: there is a common API set to deal with all these technologies (including NFC) and it is available in all the languages that can use WinRT, currently C#, C++ and JS.</p> <p><a href="http://msdn.microsoft.com/library/windows/apps/BR241212">Windows.Network.Proximity namespace</a> includes six classes that we can use to realize the use cases described above:</p> <ul> <li>ProximityDevice </li> <li>ProximityMessage </li> <li>PeerFinder </li> <li>PeerInformation </li> <li>ConnectionRequestedEventArgs </li> </ul> <p>In the second part of this article we will give a close look at the proximity API and we will provide some examples. But before that we need to build a test environment, and this is what the next paragraph is about.</p> <p> </p> <h3>A simulation environment to test Proximity API</h3> <p>At the time of writing this article there is just one device, to my knowledge, available on the market with NFC enabled: <a href="http://www.samsung.com/global/buildpc/index.html">Samsung slate PC</a>. Does that mean that we should buy two of these devices for trialling the Proximity API? Fortunately not, there is another way to get a kick out of it. We can use a proximity driver sample included in Windows Driver Kit (WDK) to simulate a tap gesture over a network connection. To do this we can use two virtual machines with Windows 8 onboard and install the driver on both machines. In the following pages you find all the necessary steps to realize that. But before that let's take a look at the recipe needed to build the environment:</p> <ul> <li>Windows 8 Release Preview build <br /> → I suggest a 64-bit version, you can download it <a href="http://windows.microsoft.com/is-IS/windows-8/iso">here</a> </li> <li>Virtualization software capable of running the above build <br /> → I used VirtualBox 4.1.8 available <a href="https://www.virtualbox.org/wiki/Downloads">here</a> </li> <li>Visual Studio 2012 RC <br /> → available <a href="http://www.microsoft.com/en-us/download/details.aspx?id=30682">here</a> </li> <li>Windows Driver Kit 8.0 (WDK) <br /> → available <a href="http://msdn.microsoft.com/en-US/windows/hardware/hh852362">here</a> </li> <li>Windows 8 Driver samples <br /> → download the full package (C# & C++) from <a href="http://code.msdn.microsoft.com/windowshardware/Windows-8-Driver-Samples-5e1aa62e">here</a> </li> <li>Windows Driver Frameworks (WDF) Co-Installers <br /> → download from <a href="http://msdn.microsoft.com/en-US/windows/hardware/br259104">here</a> </li> </ul> <p> </p> <p><strong>1. Setup of virtual machines</strong></p> <p>Using VirtualBox is fairly easy to set up a virtual machine. Just pay attention to name the two VM differently and to choose network settings that allow the VM to communicate together. I used “Bridged adapter” as network adapter as in figure:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/NetworkVirtualBox_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="NetworkVirtualBox" alt="NetworkVirtualBox" src="http://www.silverlightshow.net/Storage/Users/walterf/NetworkVirtualBox_thumb.png" width="244" height="180" /></a></p> <p>Then install Windows 8 and proceed with the installation of Visual Studio 2012, Windows Driver Kit 8.0 and the WDF coinstallers on both VM.</p> <p>The Windows 8 Driver samples includes a sample called NetNfpProvider which contains the proximity driver. In <a href="http://code.msdn.microsoft.com/windowshardware/NetNfpProvider-4ad80340#content">sample description page</a> there is some guidance for installing and using the proximity driver but the installation is a bit tricky because some steps are skipped. To bring it to a successful conclusion I suggest you follow the steps below.</p> <p> </p> <p><strong>2. Extract NetNfpProvider sample package</strong></p> <p>Unzip Windows 8 Driver Samples package in a directory and explore it to locate “NetNfpControl” subdirectory. Open the “netnfp” solution that you will find in the “C++” subdirectory. The solution contains 3 projects:</p> <p>- <strong>NetNfpProvider</strong> that contains the driver</p> <p>- <strong>NetNfpControl</strong> that contains a command-line executable to interact with the driver</p> <p>- <strong>Package</strong> contains driver package</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/1A_solution_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="1A_solution" alt="1A_solution" src="http://www.silverlightshow.net/Storage/Users/walterf/1A_solution_thumb.png" width="236" height="244" /></a></p> <p> </p> <p>In the Solution Explorer window, right-click Solution 'netnfp' and choose Configuration Manager: make sure that all the projects are configured for x64 platform, as in figure below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/1_ConfigurationManger_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="1_ConfigurationManger" alt="1_ConfigurationManger" src="http://www.silverlightshow.net/Storage/Users/walterf/1_ConfigurationManger_thumb.png" width="244" height="157" /></a></p> <p> </p> <p><strong>3. Sign the driver</strong></p> <p>To install a driver on a 64-bit version of Windows, you must sign the driver package. The following procedure helps you to test signing the driver, which is a simplified procedure useful for testing purposes. </p> <p>Right-click the driver package project, and choose Properties as in figure below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/2_PropertiesPackage_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="2_PropertiesPackage" alt="2_PropertiesPackage" src="http://www.silverlightshow.net/Storage/Users/walterf/2_PropertiesPackage_thumb.png" width="214" height="244" /></a></p> <p> </p> <p>In the Properties window expand the “Configuration Properties” branch in the tree on the left, click on “Driver Signing” and select Test Sign in the Sign Mode drop-down list as below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/3_DriverSigningProp_4.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="3_DriverSigningProp" alt="3_DriverSigningProp" src="http://www.silverlightshow.net/Storage/Users/walterf/3_DriverSigningProp_thumb_1.png" width="244" height="175" /></a></p> <p> </p> <p>Then click on Inf2Cat > General. In the Run Inf2Cat drop-down list, select Yes as below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/4_infCatProp_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="4_infCatProp" alt="4_infCatProp" src="http://www.silverlightshow.net/Storage/Users/walterf/4_infCatProp_thumb.png" width="244" height="174" /></a></p> <p> </p> <p>If we now try to build the solution, a catalog file (.CER) will be created. </p> <p> </p> <p><strong>4. Export the certificate</strong></p> <p>Now we have to share our signing certificate. Still in Properties, for the package select Configuration Properties > Driver Signing > General and in the Test Certificate choose Select From Store as below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/5_SelectfromStore_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="5_SelectfromStore" alt="5_SelectfromStore" src="http://www.silverlightshow.net/Storage/Users/walterf/5_SelectfromStore_thumb.png" width="244" height="175" /></a></p> <p> </p> <p>In the Select Certificate dialog box, select the certificate named “WDKTestCert<em>yourUserName</em>” as in figure below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/6_wdkcert_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="6_wdkcert" alt="6_wdkcert" src="http://www.silverlightshow.net/Storage/Users/walterf/6_wdkcert_thumb.png" width="244" height="234" /></a></p> <p> </p> <p>Click on Properties of the certificate selected and from the “Details” tab click “Copy to File” as in figure below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/7_copyToFileCert_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="7_copyToFileCert" alt="7_copyToFileCert" src="http://www.silverlightshow.net/Storage/Users/walterf/7_copyToFileCert_thumb.png" width="196" height="244" /></a></p> <p> </p> <p>An export wizard will open to guide you to export a .pbx file :</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/8_exportCert_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="8_exportCert" alt="8_exportCert" src="http://www.silverlightshow.net/Storage/Users/walterf/8_exportCert_thumb.png" width="244" height="239" /></a></p> <p> </p> <p>Click on Next to proceed; then you will be asked to choose the export format of the file; choose .PFX as in figure below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/9_exportCert2_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="9_exportCert2" alt="9_exportCert2" src="http://www.silverlightshow.net/Storage/Users/walterf/9_exportCert2_thumb.png" width="244" height="239" /></a></p> <p> </p> <p>Click Next and protect your private key with a password. Don’t forget your password since you will need it when you import the certificate into your local machine:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/10_exportCertPassword_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="10_exportCertPassword" alt="10_exportCertPassword" src="http://www.silverlightshow.net/Storage/Users/walterf/10_exportCertPassword_thumb.png" width="244" height="241" /></a></p> <p> </p> <p>Click Next and name the file to be exported as below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/12_exportFileCert_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="12_exportFileCert" alt="12_exportFileCert" src="http://www.silverlightshow.net/Storage/Users/walterf/12_exportFileCert_thumb.png" width="244" height="132" /></a></p> <p> </p> <p>click Save to get the final summary view:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/13_exportFinish_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="13_exportFinish" alt="13_exportFinish" src="http://www.silverlightshow.net/Storage/Users/walterf/13_exportFinish_thumb.png" width="244" height="240" /></a></p> <p> </p> <p><strong>5. Import the certificate into your local machine</strong></p> <p>Obviously the local machine is one of the 2 VM. Go to the directory where you exported your pfx file and right-click the file; the contextual menu should look like in figure below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/14_installPFX_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="14_installPFX" alt="14_installPFX" src="http://www.silverlightshow.net/Storage/Users/walterf/14_installPFX_thumb.png" width="244" height="185" /></a></p> <p> </p> <p>Click <strong>Install PFX</strong> and in the “certificate Import wizard” dialog box select “Local Machine” as Store location as below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/15_installPFX_Local%20Machine%20_4.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="15_installPFX_Local Machine " alt="15_installPFX_Local Machine " src="http://www.silverlightshow.net/Storage/Users/walterf/15_installPFX_Local%20Machine%20_thumb_1.png" width="244" height="240" /></a></p> <p> </p> <p>Click Next and in the next screen , browse for the .pbx file you previously created:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/16_FileToImportlPFX%20_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="16_FileToImportlPFX " alt="16_FileToImportlPFX " src="http://www.silverlightshow.net/Storage/Users/walterf/16_FileToImportlPFX%20_thumb.png" width="244" height="240" /></a></p> <p> </p> <p>Click Next and type in the password you previously set for your private key:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/17_FileToImportlPassword_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="17_FileToImportlPassword" alt="17_FileToImportlPassword" src="http://www.silverlightshow.net/Storage/Users/walterf/17_FileToImportlPassword_thumb.png" width="244" height="241" /></a></p> <p> </p> <p>Click on “Browse” to specify a location for the certificate:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/18_FileToImportCertStore_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="18_FileToImportCertStore" alt="18_FileToImportCertStore" src="http://www.silverlightshow.net/Storage/Users/walterf/18_FileToImportCertStore_thumb.png" width="244" height="239" /></a></p> <p> </p> <p>Click on “Show physical stores” check box as in figure below then select “Trusted Root Certification Authorities\Registry” and click OK.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/19_SelectCertificat_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="19_SelectCertificat" alt="19_SelectCertificat" src="http://www.silverlightshow.net/Storage/Users/walterf/19_SelectCertificat_thumb.png" width="244" height="240" /></a></p> <p> </p> <p>Finally, click the Finish button to complete the import:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/20_SelectCertificat_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="20_SelectCertificat" alt="20_SelectCertificat" src="http://www.silverlightshow.net/Storage/Users/walterf/20_SelectCertificat_thumb.png" width="244" height="240" /></a></p> <p> </p> <p><strong>5. Install the driver</strong></p> <p>To sum up, we have test signed the driver, exported the certificate and imported it into the local VM. Now we can install the driver. Create a directory (for instance <a href="file:///C:/Users/Administrator/AppData/Local/Microsoft/Windows/NetNfpprovider">c:\NetNfpprovider</a>) and copy the following files from the output directory of the VS solution ( i.e. : ..\NetNfpProvider\C++\Package\x64\Win8Release\Package):</p> <ul> <li>driver binary and inf: NetNfpProvider.dll, NetNfpProvider.inf </li> <li>coinstaller: WdfCoinstaller01011.dll </li> <li>wdfupdate: WudfUpdate_01011.dll </li> </ul> <p>since you have to run the device console devcon.exe, copy it from \Program Files (x86)\Windows Kits\8.0\Tools\x64 or add the path to the environment variables.</p> <p>Disable the Windows Firewall or, as suggested by the <a href="http://code.msdn.microsoft.com/windowshardware/NetNfpProvider-4ad80340#content">official guide</a> create an inbound rule to allow incoming requests to NetNfpProvider to the port 9929.</p> <p>Open a command-line windows as Administrator in the directory in which you copied the files and launch the following command:</p> <p><em>“devcon.exe install NetNfpProvider.inf WUDF\NetNfpProvider”</em></p> <p>If everything is OK you should be notified that the driver has been succesfully installed as in figure below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/walterf/23_DriverDevCon%20Successfully_2.png"><img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-style: solid;" title="23_DriverDevCon Successfully" alt="23_DriverDevCon Successfully" src="http://www.silverlightshow.net/Storage/Users/walterf/23_DriverDevCon%20Successfully_thumb.png" width="244" height="114" /></a></p> <p> </p> <p>You can now install the driver onto the second virtual machine by importing the certificate driver, copy the directory you created above and launch devcon.exe with the same parameters as above.</p> <p>In the second part we will learn how to use the driver.</p> <p> </p> <h3>Summary</h3> <p>We have introduced Near field Communication technology highlighting how it could be applied to the everyday life. We have then seen the Microsoft concept of Proximity intended as something more general. With “Tap and Do” Microsoft has summed up with a slogan the communication between two devices in close proximity. In this first part we have minutely described how to install a sample driver onto two virtual machines in order to simulate a tap gesture over the network and have the possibility to test the Proximity API. In the second part we will see how to use the driver and how easy it is to use the Proximity API.</p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px; text-align: center;"><em><strong>Want to test your understanding of this article? Walter Ferrari challenges you to prove you got it all right! </strong></em><em><strong>Take the challenge below:  <br />  <br /> </strong></em><center><em><strong> <table> <tbody> <tr> <td><a href="http://www.ideedit.com/challenges/As-described-in-the-article-Near-Field" target="_blank"><img alt="" src="http://www.silverlightshow.net/Storage/deed/img1_machines.png" style="width: 120px; height: 72px;" /></a> </td> <td style="text-align: center; vertical-align: top;"><a href="http://www.ideedit.com/challenges/As-described-in-the-article-Near-Field" target="_blank">Create Two Virtual Machines with Windows 8</a><br /> </td> </tr> </tbody> </table>     <br /> <table align="center"> <tbody> <tr> <td style="text-align: center; vertical-align: top;"><span style="font-size: 10px;"><em>Challenges powered by</em></span> <a href="http://www.ideedit.com/" target="_blank"><img alt="" src="http://www.silverlightshow.net/Storage/deed/deed_logo_transparent_40.png" /></a><em><strong><br /> </strong></em></td> </tr> </tbody> </table> <table> <tbody> </tbody> </table> </strong></em></center></div> http://www.silverlightshow.net/items/Near-Field-Communication-in-windows-8-part-1.aspx editorial@silverlightshow.net (Walter Ferrari ) http://www.silverlightshow.net/items/Near-Field-Communication-in-windows-8-part-1.aspx#comments http://www.silverlightshow.net/items/Near-Field-Communication-in-windows-8-part-1.aspx Thu, 27 Sep 2012 17:03:00 GMT Windows 8 Metro Apps: The 8 Must-Know Tricks! Day 2 <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-2.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-2.aspx" data-count="horizontal" data-text="Reading @samidip's article '#Windows8 Metro Apps: The 8 Must-Know Tricks! Day 2' #win8 #win8dev" data-url="http://slshow.net/PY5Lec">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-2.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p>This is Day # 2 in the Windows 8 development article series on common tips & tricks towards developing real-world Metro apps.  Over the next several weeks, you’ll see 8 articles talk about some must-do things for Windows 8 Metro app developers. Simple & to the point, with some code examples on XAML/C# stack. Here’s the indexed list for the series:</p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; margin-right: 5px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; font-size: 12px;"> <li><!-- Begin Ban Man Pro Text Link Code --> <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=0&BannerID=117&AdvertiserID=10&CampaignID=97&Task=Click&SiteID=1&RandomNumber=482522" target="_Blank">Join the latest challenge in SilverlightShow challenge channel!</a><img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=0&BannerID=117&AdvertiserID=10&CampaignID=97&Task=Get&Mode=TEXT&SiteID=1&RandomNumber=482522" width="1" height="1" style="border-width: 0px; border-style: solid;" /> <!-- End Ban Man Pro Text Link Code --></li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/webinars.aspx" target="_self">Recordings of SilverlightShow Windows 8 webinars</a></li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Windows-8-and-the-future-of-XAML-Part-1-An-overview-of-the-Windows-8-platform.aspx">The article series: Windows 8 and the future of XAML</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/win8_metro_1.aspx" target="_self">Ebook by A. Boschin: Introduction to Windows 8 Metro part 1</a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/win8_metro_1.aspx" target="_self"><img style="width: 70px; height: 99px;" alt="Ebook: Introduction to Windows 8 Metro part 1" src="http://www.silverlightshow.net/Storage/Ebooks/Win8_Part1.png" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <p><a href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-1.aspx" target="_blank">Day 1: Know the ecosystem; Start</a><br /> <strong>Day 2: Layout, Navigation & Visual States</strong> <br /> <a href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-3.aspx">Day 3: Semantic Zoom</a> <br /> <a href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-4.aspx">Day 4: Controls & Styling</a> <br /> <a href="http://www.silverlightshow.net/items/Windows-8-Apps-The-8-Must-Know-Tricks-Day-5.aspx">Day 5: Search, Share & Settings Contracts</a> <br /> <a href="http://www.silverlightshow.net/items/Windows-8-Apps-The-8-Must-Know-Tricks-Day-6.aspx">Day 6: Data Persistence & Application Life-Cycle Management</a> <br /> <a href="http://www.silverlightshow.net/items/Windows-8-Apps-The-8-Must-Know-Tricks-Day-7.aspx">Day 7: Use of OData or Web Services</a> <br /> <a href="http://www.silverlightshow.net/items/Windows-8-Apps-The-8-Must-Know-Tricks-Day-8.aspx">Day 8: Live Services integration</a><br /> <br /> </p> <h4>Day 2: Layout, Navigation & Visual States</h4> <p><span style="font-size: 16px;">App Layout:</span></p> <p>So, you have the next big app idea. The real question is – will it delight the user? All Windows 8 Metro apps should and it is critically important to plan towards it. One curse for us developers is how easy it is to get started with an idea and go File->New Project in Visual Studio. As the Metro design principles stated again & again, let’s sweat the details. Pen & paper can be a wonderful companion to plan out the overall application layout. How will you slice & dice your content? Is the app content going to laid out in an information hierarchy or in a flat system? How would the app support Metro design principles & integrate with the rest of the OS?</p> <p>There are two places I personally start out at. One would be OS features or other applications, to be inspired by how others have done it & then give my app it’s own brand. If on Release Preview, the Windows 8 Store is starting to get a lot of very well designed apps that should inspire. Second, are the VS project templates. Although not a good idea to start a project right away, take a peek at the templates; this tells us what some common page layouts are and helps us plan the breakdown of information in our app. Some example layouts below: </p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Template1.png"><img title="Template1" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="Template1" src="http://www.silverlightshow.net/Storage/Users/samidip/Template1_thumb.png" width="604" height="364" /></a></p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Template2.png"><img title="Template2" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="Template2" src="http://www.silverlightshow.net/Storage/Users/samidip/Template2_thumb.png" width="604" height="366" /></a></p> <p><span style="font-size: 18px;"></span><a href="http://www.silverlightshow.net/Storage/Users/samidip/Template3.png"><img title="Template3" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="Template3" src="http://www.silverlightshow.net/Storage/Users/samidip/Template3_thumb.png" width="604" height="364" /></a> </p> <p>The above page templates help us see through the planning of our app: Is it going to a Hub & spoke model with Hub, Section & Detail pages? Or a Flat system of content pages with linear navigation? Your call, but chose well.</p> <p><img title="Hierarchical system of navigation in a Metro stye spp" alt="Hierarchical system of navigation in a Metro stye spp" src="http://i.msdn.microsoft.com/dynimg/IC561748.png" />  <img title="Flat navigation system in a Metro style app" alt="Flat navigation system in a Metro style app" src="http://i.msdn.microsoft.com/dynimg/IC561750.png" /></p> <p><span style="font-size: 16px;"></span></p> <p><span style="font-size: 16px;">Page Layout:</span></p> <p>Similar to Windows Phone, Windows 8 Metro apps in XAML/C# stack are made up of multiple pages. These pages are hosted inside of an <em>Application Frame</em>, and constitute the canvas on which we lay out the content of our Metro style apps.  When a Metro app is in full mode (taking up the whole screen), edge-to-edge of the display is filled by the current application page, thus immersing the user in content. The real estate is yours to shine in or mess up <img class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/____wlEmoticon-smile_2.png" />.</p> <p>The three basic ways to lay out content in a XAML page still stay the same using the generic container Panel controls – <em>Grid</em>, <em>StackPanel</em> & <em>Canvas</em>.  The goal is to make this container support a flexible layout system so that our app looks great in varying screen resolutions, pixel densities & orientations. So, you can see why <em>Dynamic</em> layout system using Grid/StackPanel is more flexible than the <em>Absolute</em> X-Y positioning in a Canvas. </p> <p>Canvas has a distinct place & use, when we need to absolute-position controls using <em>Canvas.Left</em> & <em>Canvas.Top</em>. If there is a genuine need for absolute positioning, you may consider different pages for supporting various screen resolutions or opt for scaling. </p> <p>In the dynamic layout containers, we specify child elements in terms of relative position & how they should wrap inside their parent controls. The use of <em>auto or star sizing</em> in control height/width inside the container is the most flexible way to auto-adjust control layout as the size of the parent container changes. Just as in any XAML UI, we lay out our controls in a Grid using <em>RowDefinition</em> & <em>ColumnDefinition</em>; while StackPanel stacks controls horizontally or vertically using the <em>Orientation</em> property. </p> <p> </p> <p><span style="font-size: 16px;">Control Layout:</span></p> <p>So, by now you have your application & page structures laid down roughly. Congratulations! Pat yourself on the back & indulge a little, since you have done the hard part. Now, what comes next isn’t hard; just take meticulous patience. What do we need to remember as we plant controls on a page inside their containers?</p> <p>Turns out, basic Metro principles help. The key is to be consistent across the application; nothing should be jarring to the user. So, we’ll try to stick to a consistent Metro-inspired pattern of control margins, page headers, app bars, gutter widths and other elements to achieve unity in the app silhouette. Absolutely positively stick to the Grid, in terms of laying out text & controls: </p> <p><img title="Illustration of the grid system" alt="Illustration of the grid system" src="http://i.msdn.microsoft.com/dynimg/IC576255.png" width="400" height="294" /></p> <p>Invest in making a common <em>Page header</em> or <em>App/Nav Bar</em> user control that can be leveraged all across the app, if applicable. Content region on every page needs to strive for consistency in margin & padding of child controls. </p> <p><span style="font-size: 16px;">Navigation:</span></p> <p>Once the application ‘information architecture’ has been laid out in full, navigation between parts of the app should be natural. Content is king; so let us allow the user to use content to manipulate the view presented to him/her. This form of direct manipulation demands that navigation mechanisms be available through the content canvas itself.</p> <p>Check out this little piece of code from the <em>OnLaunched</em> event handler in <em>App.xaml.cs</em>. It shows how the root <em>Frame</em> of the application is loaded up by the OS on app launch, followed by navigating to the first page:</p> <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; line-height: 12pt; overflow: auto; font-family: 'courier new', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4; text-align: left;"> <div id="codeSnippet" style="padding: 0px; width: 100%; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4; text-align: left;"> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnLaunched(LaunchActivatedEventArgs args)</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span> {</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #008000;">// Do not repeat app initialization when already running, just ensure that the window is active.</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span> <span style="color: #0000ff;">if</span> (args.PreviousExecutionState == ApplicationExecutionState.Running)</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span> {</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span> Window.Current.Activate();</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span> }</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span> <span style="color: #008000;">// Create a Frame to act as the navigation context and associate it with a SuspensionManager key.</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span> var rootFrame = <span style="color: #0000ff;">new</span> Frame();</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span> SuspensionManager.RegisterFrame(rootFrame, <span style="color: #006080;">"AppFrame"</span>);</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum13" style="color: #606060;"> 13:</span> </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum14" style="color: #606060;"> 14:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum15" style="color: #606060;"> 15:</span> <span style="color: #0000ff;">if</span> (rootFrame.Content == <span style="color: #0000ff;">null</span>)</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum16" style="color: #606060;"> 16:</span> {</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum17" style="color: #606060;"> 17:</span> <span style="color: #0000ff;">if</span> (!rootFrame.Navigate(<span style="color: #0000ff;">typeof</span>(FirstPageClassName)))</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum18" style="color: #606060;"> 18:</span> {</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum19" style="color: #606060;"> 19:</span> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> Exception(<span style="color: #006080;">"Failed to create initial page"</span>);</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum20" style="color: #606060;"> 20:</span> }</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum21" style="color: #606060;"> 21:</span> }</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum22" style="color: #606060;"> 22:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum23" style="color: #606060;"> 23:</span> <span style="color: #008000;">// Place the frame in the current Window and ensure that it is active.</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum24" style="color: #606060;"> 24:</span> Window.Current.Content = rootFrame;</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum25" style="color: #606060;"> 25:</span> Window.Current.Activate();</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum26" style="color: #606060;"> 26:</span> }</pre> <!--CRLF--></div> </div> <p>Navigation between pages in the application frame can be very simply done like this:</p> <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; line-height: 12pt; overflow: auto; font-family: 'courier new', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4; text-align: left;"> <div id="codeSnippet" style="padding: 0px; width: 100%; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4; text-align: left;"> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">this</span>.Frame.Navigate(<span style="color: #0000ff;">typeof</span>(SecondPageClassName), CustomParameters);</pre> <!--CRLF--></div> </div> <p>As you can see, it is easy to carry any custom object or information from one page to another. One caveat would be that if you find yourself doing a lot of this, may be it’s time to consider using some global variables (defined in <em>App.xaml.cs</em>) to have consistent access to the same data across multiple pages.</p> <p>There is one deviation to creating navigation elements on canvas. And that is around not recreating the wheel and integrating our app with the rest of the Windows 8 OS. The user is already used to using the <em>App Bar</em> & <em>Charms bar</em>; so why give them another way of doing the same thing?</p> <p><img title="Hh465304.surface_app_bar(en-us,WIN.10).png" alt="Hh465304.surface_app_bar(en-us,WIN.10).png" src="http://i.msdn.microsoft.com/dynimg/IC563406.png" width="350" height="202" /><img title="Hh465304.surface_charm(en-us,WIN.10).png" style="display: inline; float: right;" alt="Hh465304.surface_charm(en-us,WIN.10).png" src="http://i.msdn.microsoft.com/dynimg/IC563407.png" width="300" height="216" /></p> <p>App Bar is perfect for providing context sensitive commands on a given page.  It stays tucked away until the user needs to manipulate the view that he/she is on. And application features like Search, Share & Settings should absolutely utilize the app-to-app Contracts in Windows 8 through the Charms – clear, consistent & easily available on right edge swipe. <em>Flyout</em> & <em>Context</em> menus are also a great way to provide navigation hints without inadvertently acting on the user’s touch interaction.</p> <p> </p> <p><span style="font-size: 16px;">Visual States:</span></p> <p>While Windows 8 is meant for all types of form factors, heavy usage of touch-based Metro apps will be from tablets/slates.  And that means, we app developers need to be understanding and supporting the various <em>orientation</em> & <em>visual state changes</em> for our app. Supporting orientation changes should be relatively easy if using flexible design layouts of Grid/StackPanel. If your page isn’t too busy, simply allow the controls to flip & support the new orientation; with auto sizing on, the content should flow/wrap as needed. You can select your supported orientations from the application manifest UI editor as below:   </p> <p><img title="Orientation" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="Orientation" src="http://www.silverlightshow.net/Storage/Users/samidip/Orientation_1.png" width="504" height="98" />  </p> <p>Now, as for the Visual State changes, Windows 8 has this wonderful feature of being able to run two Metro applications side by side. This is NOT an optional feature to support since Metro app users will always be able to do this; and not supporting it means we would provide a crappy UX when our app runs side by side with another application.</p> <p>There are three simple visual state for a Metro application – <em>Full, Filled & Snapped</em>. While the names are explanatory, the image below explains the states even better. Left to right, are Full, Filled & Snapped Visual States of any given application: </p> <p><img title="Full screen view state" alt="Full screen view state" src="http://i.msdn.microsoft.com/dynimg/IC587752.png" />         <img title="Fill view state" alt="Fill view state" src="http://i.msdn.microsoft.com/dynimg/IC587754.png" />        <img title="Snap view state" alt="Snap view state" src="http://i.msdn.microsoft.com/dynimg/IC587753.png" /></p> <p> </p> <p>If you are using a flexible design layout & data binding through standard controls, supporting this change of visual state is not very difficult at all. And there is plenty of help from the VS generic project templates. Let’s say we were building a Windows 8 Metro app for perusing SilverlightShow article content. A listing of latest articles in Full, Filled & Snapped mode could look something like this (we would walk through the building this sample later in the series):</p> <p> </p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/SLShowArticleListFull_2.png"><img title="SLShowArticleListFull" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="SLShowArticleListFull" src="http://www.silverlightshow.net/Storage/Users/samidip/SLShowArticleListFull_thumb.png" width="604" height="342" /></a> <br /> <a href="http://www.silverlightshow.net/Storage/Users/samidip/SLShowArticleListFilled_2.png"><img title="SLShowArticleListFilled" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="SLShowArticleListFilled" src="http://www.silverlightshow.net/Storage/Users/samidip/SLShowArticleListFilled_thumb.png" width="604" height="342" /></a></p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/SLShowArticleListSnappedLeft_2.png"><img title="SLShowArticleListSnappedLeft" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="SLShowArticleListSnappedLeft" src="http://www.silverlightshow.net/Storage/Users/samidip/SLShowArticleListSnappedLeft_thumb.png" width="604" height="342" /></a></p> <p>The beauty of supporting the change in Visual State is the fact that the page could retain it’s state and be bound to the same collection or object behind the scene. We only switch out the UI element that is bound to the data, to fit the much smaller width of the snapped state. The easiest way to get this done is by using one of the default project templates in Visual Studio 2012 for Metro apps. It drops a file called <em>LayoutAwarePage</em> in the Common folder. Inherit your pages off this & voila – you have ready-made hooks into the system events as to when the visual states change. The whole switch can be done purely in XAML using <em>Visual State Manager</em>. Watch how seamlessly we switch the display from a GridView to a Listview , both bound to the same list of article objects:</p> <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; line-height: 12pt; overflow: auto; font-family: 'courier new', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4; text-align: left;"> <div id="codeSnippet" style="padding: 0px; width: 100%; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4; text-align: left;"> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <VisualStateManager.VisualStateGroups></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span> <!-- Visual states reflect the page's view state --></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> <VisualStateGroup></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span> <VisualState x:Name=<span style="color: #006080;">"FullScreenLandscape"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span> <VisualState x:Name=<span style="color: #006080;">"Filled"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span> <VisualState x:Name=<span style="color: #006080;">"Snapped"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span> <Storyboard></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span> <ObjectAnimationUsingKeyFrames Storyboard.TargetName=<span style="color: #006080;">"itemListScrollViewer"</span> Storyboard.TargetProperty=<span style="color: #006080;">"Visibility"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span> <DiscreteObjectKeyFrame KeyTime=<span style="color: #006080;">"0"</span> Value=<span style="color: #006080;">"Visible"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span> </ObjectAnimationUsingKeyFrames></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span> <ObjectAnimationUsingKeyFrames Storyboard.TargetName=<span style="color: #006080;">"itemGridScrollViewer"</span> Storyboard.TargetProperty=<span style="color: #006080;">"Visibility"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum13" style="color: #606060;"> 13:</span> <DiscreteObjectKeyFrame KeyTime=<span style="color: #006080;">"0"</span> Value=<span style="color: #006080;">"Collapsed"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum14" style="color: #606060;"> 14:</span> </ObjectAnimationUsingKeyFrames></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum15" style="color: #606060;"> 15:</span> <ObjectAnimationUsingKeyFrames Storyboard.TargetName=<span style="color: #006080;">"snappedHeader"</span> Storyboard.TargetProperty=<span style="color: #006080;">"Visibility"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum16" style="color: #606060;"> 16:</span> <DiscreteObjectKeyFrame KeyTime=<span style="color: #006080;">"0"</span> Value=<span style="color: #006080;">"Visible"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum17" style="color: #606060;"> 17:</span> </ObjectAnimationUsingKeyFrames></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum18" style="color: #606060;"> 18:</span> <ObjectAnimationUsingKeyFrames Storyboard.TargetName=<span style="color: #006080;">"regularHeader"</span> Storyboard.TargetProperty=<span style="color: #006080;">"Visibility"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum19" style="color: #606060;"> 19:</span> <DiscreteObjectKeyFrame KeyTime=<span style="color: #006080;">"0"</span> Value=<span style="color: #006080;">"Collapsed"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum20" style="color: #606060;"> 20:</span> </ObjectAnimationUsingKeyFrames></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum21" style="color: #606060;"> 21:</span> </Storyboard></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum22" style="color: #606060;"> 22:</span> </VisualState></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum23" style="color: #606060;"> 23:</span> </VisualStateGroup></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum24" style="color: #606060;"> 24:</span> </VisualStateManager.VisualStateGroups></pre> <!--CRLF--></div> </div> <p> </p> <p>In the code above, you’ll see very quickly how named Visual States define the state of the UI. My Full & Filled Visual States are the same; you can choose however your application needs. The Snapped state however, defines a <em>StoryBoard</em>, containing several animations. This is where the simple magic lies – we toggle the visibility of UI elements to adjust to the shorter width of the Snapped state. You’ll notice that the view changes from using a GridView to a ListView and we adjust the page header section to fit. The built-in Frame animations ensure that the whole translation is not jarring; but UI elements ease into place.</p> <p>We’ll discuss the GridView display in Full mode in the next article; let’s talk about the ListView which is displaying the list of grouped SilverlightShow articles in Snapped mode. Here’s the XAML for it:</p> <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; line-height: 12pt; overflow: auto; font-family: 'courier new', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4; text-align: left;"> <div id="codeSnippet" style="padding: 0px; width: 100%; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4; text-align: left;"> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <!-- Vertical scrolling list only used when snapped --></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span> <ScrollViewer</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> x:Name=<span style="color: #006080;">"itemListScrollViewer"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span> AutomationProperties.AutomationId=<span style="color: #006080;">"ItemListScrollViewer"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span> Grid.Row=<span style="color: #006080;">"1"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span> Visibility=<span style="color: #006080;">"Collapsed"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span> Style=<span style="color: #006080;">"{StaticResource VerticalScrollViewerStyle}"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span> <ListView</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span> x:Name=<span style="color: #006080;">"itemListView"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span> AutomationProperties.AutomationId=<span style="color: #006080;">"ItemListView"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span> AutomationProperties.Name=<span style="color: #006080;">"Grouped Items"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum13" style="color: #606060;"> 13:</span> Margin=<span style="color: #006080;">"10,-10,0,10"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum14" style="color: #606060;"> 14:</span> ItemsSource=<span style="color: #006080;">"{Binding Source={StaticResource groupedItemsViewSource}}"</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum15" style="color: #606060;"> 15:</span> ItemTemplate=<span style="color: #006080;">"{StaticResource SLShowSnappedArticleTemplate}"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum16" style="color: #606060;"> 16:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum17" style="color: #606060;"> 17:</span> <ListView.GroupStyle></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum18" style="color: #606060;"> 18:</span> <GroupStyle></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum19" style="color: #606060;"> 19:</span> <GroupStyle.HeaderTemplate></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum20" style="color: #606060;"> 20:</span> <DataTemplate></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum21" style="color: #606060;"> 21:</span> <Grid Margin=<span style="color: #006080;">"7,7,0,0"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum22" style="color: #606060;"> 22:</span> <Button AutomationProperties.Name=<span style="color: #006080;">"Group Title"</span> Content=<span style="color: #006080;">"{Binding SLShowArticleGroupName}"</span> Style=<span style="color: #006080;">"{StaticResource SLShowTextButtonStyle}"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum23" style="color: #606060;"> 23:</span> </Grid></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum24" style="color: #606060;"> 24:</span> </DataTemplate></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum25" style="color: #606060;"> 25:</span> </GroupStyle.HeaderTemplate></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum26" style="color: #606060;"> 26:</span> </GroupStyle></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum27" style="color: #606060;"> 27:</span> </ListView.GroupStyle></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum28" style="color: #606060;"> 28:</span> </ListView></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum29" style="color: #606060;"> 29:</span> </ScrollViewer> </pre> <!--CRLF--></div> </div> <p> </p> <p>This ListView is fed it’s data in the code-behind. Notice the <em>ItemTemplate</em>? To keep the XAML clean, this is actually defined separately as a style in the <em>StandardStyles.xaml </em>file in the project Common folder. Take a good look at this file to see how the VS templates use all of the styles defined in various layouts & visual states. If you need to customize, it is highly recommended that you make a copy of the built-in style & make it your own, rather than risking the styles used in the generic page templates. Here’s our data template feeding the ListView in snapped mode:</p> <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; line-height: 12pt; overflow: auto; font-family: 'courier new', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4; text-align: left;"> <div id="codeSnippet" style="padding: 0px; width: 100%; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4; text-align: left;"> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <!-- Snapped mode list of Grouped Articles --></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span> <DataTemplate x:Key=<span style="color: #006080;">"SLShowSnappedArticleTemplate"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> <Grid Margin=<span style="color: #006080;">"6"</span> Width=<span style="color: #006080;">"320"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span> <Border Background=<span style="color: #006080;">"#99FFDD"</span> Opacity=<span style="color: #006080;">"1"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span> <StackPanel Margin=<span style="color: #006080;">"10,0,0,0"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span> <TextBlock Text=<span style="color: #006080;">"{Binding ArticleName}"</span> Foreground=<span style="color: #006080;">"#6655FF"</span> TextWrapping=<span style="color: #006080;">"Wrap"</span> FontSize=<span style="color: #006080;">"16"</span> Width=<span style="color: #006080;">"250"</span> Margin=<span style="color: #006080;">"-55,0,0,0"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span> <StackPanel Orientation=<span style="color: #006080;">"Horizontal"</span>></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span> <TextBlock Text=<span style="color: #006080;">"{Binding AuthorName}"</span> Foreground=<span style="color: #006080;">"Orange"</span> FontWeight=<span style="color: #006080;">"SemiBold"</span> TextWrapping=<span style="color: #006080;">"NoWrap"</span> Margin=<span style="color: #006080;">"0,10,0,0"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span> <TextBlock Text=<span style="color: #006080;">"{Binding DisplayablePublishDate}"</span> Foreground=<span style="color: #006080;">"Black"</span> TextWrapping=<span style="color: #006080;">"NoWrap"</span> Margin=<span style="color: #006080;">"10,10,0,0"</span>/></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span> </StackPanel></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span> </StackPanel></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span> </Border></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum13" style="color: #606060;"> 13:</span> </Grid></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum14" style="color: #606060;"> 14:</span> </DataTemplate></pre> <!--CRLF--></div> </div> <p> </p> <p>Now, one other thing: What if you had an App Bar or Nav Bar on the Full view of a  page? Would you like to change the appearance if either Bar or do some custom manipulation? Can you listen in on the Visual State changing events yourself? Absolutely. That is exactly what the <em>LayoutAwarePage</em> does; we only need event-handlers to listen in. Here’s some code:</p> <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; line-height: 12pt; overflow: auto; font-family: 'courier new', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4; text-align: left;"> <div id="codeSnippet" style="padding: 0px; width: 100%; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4; text-align: left;"> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">using</span> Windows.UI.ViewManagement;</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #008000;">// Do this in the Page Constructor.</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span> Window.Current.SizeChanged += VisualStateChanged;</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> VisualStateChanged(<span style="color: #0000ff;">object</span> sender, WindowSizeChangedEventArgs e)</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span> {</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span> <span style="color: #0000ff;">string</span> visualState = DetermineVisualState(ApplicationView.Value);</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span>  </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span> <span style="color: #0000ff;">if</span> (visualState == <span style="color: #006080;">"Snapped"</span>)</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span> { </pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span> <span style="color: #008000;">// Custom logic.</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum13" style="color: #606060;"> 13:</span> }</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum14" style="color: #606060;"> 14:</span> <span style="color: #0000ff;">else</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum15" style="color: #606060;"> 15:</span> {</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum16" style="color: #606060;"> 16:</span> <span style="color: #008000;">// Return to normal UI.</span></pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum17" style="color: #606060;"> 17:</span> }</pre> <!--CRLF--> <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'courier new', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum18" style="color: #606060;"> 18:</span> }</pre> <!--CRLF--></div> </div> <p>So, nothing to fear – just a few moving pieces to keep in mind to support Layout, Navigation & varying Visual States in our Windows 8 Metro applications.</p> <p>PS: Several imagery used courtesy of MSDN Documentation starting @ <a href="http://msdn.microsoft.com/library/windows/apps/hh465424">http://msdn.microsoft.com/library/windows/apps/hh465424</a>.</p> <p> </p> <h4>Conclusion</h4> <p>That’s it for today. The crux of this article was to talk about all the different Layout options for Windows 8 Metro apps and how to navigate between parts of a well-laid out application. We ended with ways to support various orientations & Visual States that Metro applications may need to go through for a enjoyable UX for the user. </p> <p>See you next time as we dive into some real-world Semantic Zooming in Windows 8 Metro apps. Thanks for reading!</p> <h4>About Author</h4> <p><img style="margin: 0px 15px 0px 0px; float: left; display: inline;" alt="ActualPic" src="http://www.silverlightshow.net/Storage/Users/samidip/ActualPic_1.jpg" />Samidip Basu (<a href="https://twitter.com/samidip">@samidip</a>) is a technologist, gadget-lover and MSFT Mobility Solutions Lead for Sogeti USA working out of Columbus OH. With a strong developer background in Microsoft technology stack, he now spends much of his time in spreading the word to discover the full potential of Windows Phone/Windows 8 platforms & cloud-supported mobile solutions in general. He passionately helps run the Metro Developer User Group (<a href="http://www.meetup.com/metrodevug/">http://themetrodeveloperusergroup.com/</a>), labors in M3 Conf (<a href="http://m3conf.com/">http://m3conf.com/</a>) organization and can be found with at-least a couple of hobbyist projects at any time. His spare times call for travel and culinary adventures with the wife. Find out more at <a href="http://samidipbasu.com/">http://samidipbasu.com</a>. </p> http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-2.aspx editorial@silverlightshow.net (Samidip Basu ) http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-2.aspx#comments http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-2.aspx Mon, 16 Jul 2012 21:57:00 GMT Metro style applications – designing for the user <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Metro-style-applications-designing-for-the-user.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Metro-style-applications-designing-for-the-user.aspx" data-count="horizontal" data-text="Reading SilverlightShow article 'Metro style apps – designing for the user' #win8dev #win8" data-url="http://slshow.net/KMMYzQ">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Metro-style-applications-designing-for-the-user.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p>It has been months since Windows 8 is available for developers and the need for new applications is growing in a fast pace. </p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; margin-right: 5px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Webinars.aspx">Recordings of SilverlightShow Win 8 webinars</a></li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Windows-8-and-the-future-of-XAML-Part-1-An-overview-of-the-Windows-8-platform.aspx">The article series: Windows 8 and the future of XAML</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/win8_odata.aspx">Ebook: Windows 8 XAML Metro Apps with OData</a> </li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/win8_odata.aspx" target="_self"><img style="width: 107px; height: 150px;" alt="Ebook: Windows 8 XAML Metro Apps with OData" src="http://www.silverlightshow.net/Storage/Ebooks/win8_odata.png" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> And nothing is more exacting than a computer user in 21<sup>st</sup> century. It’s quite difficult to build the <em>right</em> application, moreover – it’s even more difficult to stay on top and not to be, metaphorically, stepped over by the big players. They always know what exactly the user wants and have the resources to provide it to him. But that’s not always what has to happen after all.<br /> <p> You have the power to build what the user wants and even build it so that s/he would feel it so natural to use your Metro application. That is to design the application in a way that using the fingers on the display seems to be a pleasure, but not a challenge. <br />  </p> <h2>Okay, let’s make our Metro applications look great!</h2> <p>Designing the Metro application is different from designing the common and straightforward desktop application. Obviously, using fingers on touch instead of mouse cursor is a big difference. And the Metro style applications will soon become the mainstream. </p> <p><a href="http://msdn.microsoft.com/en-gb/library/windows/apps/hh700403">Here</a> you can find design assets for creating great Metro application mock-ups. The download contains layered PhotoShop files representing common controls and components, project layouts and templates. </p> <p>In the download you will find lots of .psd files that you can use to build a sketch or mocked prototype of your application. It seems that everything you would ever need is in:</p> <ul> <li><strong>Common controls.</strong> A variety of styles of all controls in dark and light Metro themes.</li> <li><strong>Common components.</strong> Tiles with the 1x1 and 2x1 ratio, contracts – the charms bar, search, share and settings side menus and more, and the keyboard.</li> <li><strong>Base layouts.</strong> For fill, full, portrait and snap views.</li> <li><strong>Project templates.</strong> For light and dark themes.</li> </ul> <p>Microsoft provides you with all you could need, but you are, of course, not limited only to the list. All files are layered and fully editable to stick with your mock-up design needs.</p> <h2>User experience design patterns</h2> <p>Here come the UX design patterns. They encapsulate the most important principles in Windows 8 Metro applications and guide you to the ultimate design. Using the patterns helps you in finding answers to questions related to content organization in pages, placing buttons and commands and the touch gestures and interactions.</p> <h3>Navigation design</h3> <p>The navigation design patters guide developers in organizing application content in pages, subpages, sections and categories so the users feel it comfortable and intuitively to switch between application screens and navigate through different views. It focuses mainly on two types of navigation.</p> <p> </p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/lnikolov/MetroAppsDesign/hub.png" style="float: left; margin-right: 15px; border-width: 0px; border-style: solid;" /></p> <p>The <em>Hub</em> design pattern, or hierarchical system of navigation, is the most commonly used in the consumers preview. It is appropriate when the application consists of large amount of data that also varies a lot. The content is organized in levels and each level is responsible for a specific context. The top-most page – the Hub page, also referred as initial page, is where the content is presented in different sections with different contexts. The Hub page usually provides very different categories of content and less functionality. Its main focus is the content presentation. Each section of the Hub page is associated with a Section page that is more specific in its content presentation. It often contains a number of data items. Each item is then presented in details in the Details page – the third and last level of content.<!--</p--> </p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/lnikolov/MetroAppsDesign/flat.png" style="float: left; margin-right: 15px;" />The Flat design system is used mostly in applications that have a single purpose and clear interaction and process flow. Such an application is document creation tool that has small number of pages that have to be executed all in a specific order.</p> <p><br /> </p> <p>On the navigation design documentation page <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh761500.aspx">here</a> you can also find guidelines and basic navigation concepts for Metro applications.</p> <h3>Commanding design</h3> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/lnikolov/MetroAppsDesign/communication.png" style="float: left; margin-right: 15px;" />The commanding design guidelines that you can find <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh761499.aspx">here</a> describe the best practices in Metro applications for placing and using command buttons in all possible ways. The focus is on what the user should be able to do and how this should happen. When possible you must allow manipulating items and executing commands directly from the canvas and not by the charms and the application bar. The command buttons have to be consistently used in all application views so it is the same and intuitively for users to execute commands from everywhere. To avoid complexity limit the number of commands and always consider the placement of the button – this could improve the speed a command can be acted upon.</p> <h3>Touch interaction design</h3> <p>On the Microsoft Build conference last year Jensen Harris of the Windows User Experience team announced the results from usability research conducted from Microsoft in their dedicated labs for the comfortable zones of interaction and behavior when using a touch screen device like the Metro tablet. Everyone uses the touch device in a slightly different way in different postures – on the knee, on tables, with two hands on the side, etc. The last turned to be the most common posture. </p> The touch interaction guidelines (that you can find in details <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465415.aspx">here</a>) describe how to provide good touch interaction experience with your application partly relying on researches among users.<br /> <p><strong>Interaction comfortable area:</strong> Because the Windows 8 tablets are most often held along the side, the bottom corners and sides are ideal locations to put your interaction elements. To comfortably reach the center of the screen it takes you a posture change – put the important interaction interface close to the edges in the user’s comfortable zone.</p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/lnikolov/MetroAppsDesign/touch_interaction.png" /></p> <p><strong>Reading comfortable area:</strong> Content in the top half of the screen is easier to read than content in bottom half or the middle because it is often partly covered by your fingers.</p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/lnikolov/MetroAppsDesign/reading_comf.png" /></p> <p>Windows 8 has several standard touch interactions, which effects shouldn’t change when the display is touched with more fingers than expected. </p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/lnikolov/MetroAppsDesign/Windows-8-Touch-Interactions.png" style="width: 450px; height: 258px;" /></p> <p>Elements from your interface that could be moved around should follow the finger direction while the display is touched. Just like in real world – the pen is in your hand while you don’t put it on the desk. All interactions should be observed, i.e. user should feel or see a feedback from his actions. It’s not acceptable to press a button with your finger and don’t see any flash or any kind of feedback. You could be misled that your touch hasn’t been registered from the device.  And last but definitely not least – always consider the size of the things. The error rate increases with the size getting smaller. The recommended minimum size for a touch target is 7x7 mm (40x40 pixels) with at least 2 mm padding. Of course, when the accuracy matters, the size gets bigger.</p> <p> Touch interactions are important. Think if the interactions as the language that your application uses to communicate with the user. You need this language fluent!</p> <h2>Conclusion</h2> Designing your application in a way that you put yourself in the user shoes is a key factor for the vitality of a future product. In a world where the user is ruling and defines the standards, the design and feel of your application is also the packaging. And the bad pack is even not considered as an option. This article is about attracting users with nice and intuitive user experience in Windows 8 Metro applications. To keep a user, though, you need also the content and value. Harnessing the power of the navigation, commands and touch interactions guidelines and patterns parallel with the content may be the key of your success! http://www.silverlightshow.net/items/Metro-style-applications-designing-for-the-user.aspx editorial@silverlightshow.net (Lazar Nikolov ) http://www.silverlightshow.net/items/Metro-style-applications-designing-for-the-user.aspx#comments http://www.silverlightshow.net/items/Metro-style-applications-designing-for-the-user.aspx Wed, 02 May 2012 12:21:00 GMT Windows 8 Metro: Create your apps with simplicity in mind <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Windows-8-Metro-Create-your-apps-with-simplicity-in-mind.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Windows-8-Metro-Create-your-apps-with-simplicity-in-mind.aspx" data-count="horizontal" data-text="Read @aboschin's article '#Windows8 Metro: Create your apps w/ simplicity in mind' #win8 #win8dev" data-url="http://slshow.net/HdHYOX">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Windows-8-Metro-Create-your-apps-with-simplicity-in-mind.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p style="text-align: justify;">In the recent days an epocal change is becoming evident. If you tried to download the new Windows 8 Consumer Preview, available for free on Microsoft website, you know what I mean. The change, that is greatly focused on a new user experience, is driven by the growing power of portable devices that are becoming prevalent on common desktop and laptops. Up to the day before today, tablet PCs, smartphones, and generically speaking touch-enabled devices was expensive and not effective, but they are now something that common people start to take in serious consideration from the effectiveness perspective and also from the economical point of view.</p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; margin-right: 5px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/news/Upcoming-SilverlightShow-Webinar-Advanced-Windows-8-Metro.aspx">Our two-part Win 8 webinar on July 18 and 25</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Windows-8-and-the-future-of-XAML-Part-1-An-overview-of-the-Windows-8-platform.aspx">The article series: Windows 8 and the future of XAML</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/win8_metro_1.aspx">Ebook by A. Boschin: Introduction to Windows 8 Metro Part 1</a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/win8_metro_1.aspx" target="_self"><img alt="Ebook: Introduction to Windows 8 Metro Part 1" src="http://www.silverlightshow.net/Storage/Ebooks/Win8_Part1.png" style="width: 100px; height: 140px;" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <p style="text-align: justify;">As said, this change is mostly focused on a new user experience due to the fact that there is a shift of the attention from the business software to the consumer market. Never like today the wide availability of consumer application have been important and this, joined with the new touch paradigm requires a completely new set of rules to design the experience and the interaction of the user with your software.</p> <p style="text-align: justify;">Starting with this article, I aim to begin a new series based on my evolving experience with the new Windows 8 Metro Applications. As few people knows I have a graphical background that lives side by side with my programmer soul. During this series I would like to discover most of the wonderful tools behind Metro applications but in this article I would like to briefly switch off my programmer side to take in serious consideration the design aspects behind Metro.</p> <h3>The art of remove instead of add</h3> <p style="text-align: justify;"><img style="background-image: none; margin: 7px 0px 0px 20px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; float: right; border-width: 0px; border-style: solid;" title="Antoine de Saint-Exupéry" alt="Antoine de Saint-Exupéry" src="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/20080925_saintexupery_3.jpg" width="139" height="167" /><a href="http://en.wikipedia.org/wiki/Antoine_de_Saint-Exup%C3%A9ry" target="_blank">Antoine de Saint-Exupéry</a>, a french writer and aviator lived in early 1900, one day pronounced a famous sentence: "<em>Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.</em>". There is a deep truth behind these words and I know very few people that is able to embrace this concept when he is working on a project, no matter if he is drawing a furniture item or designing the user interface of the latest application.</p> <p style="text-align: justify;">Focusing on the software industry, what commonly happens is that a series of features are put togheter, they becomes a software with a complex user interface and most of the times the end-user is unable to use all these powerful features because they are hidden by the complexity or in the worst case they are simply unuseful. Have you ever asked yourself if all the features of your software are fully understand and used by your customers? I did this exercise and the result is mostly disappointing.</p> <p style="text-align: justify;">So, probably the "art of remove instead of add" is something you have to carefully evaluate. Generally speaking this does not apply only to the user interface of your next application, but it has to deeply permeate it with a careful evaluation on each single feature to understand if it is really useful and if it can be part of the whole. The question you have to ask yourself is simple: is it really useful? And the hard part is being brave considering unuseful something that people usually think as required.</p> <p style="text-align: justify;">As an example, think at an advanced search form, with lot of fields each one dedicated to the filtering of a specific property. You can search for the title, the abstract, the creation date and (why not?) for the deletion date, for the author, for the contributors, for the collection to which the item is part, etc... Omitting that a similar form can't be subject of an effective functional test, I guess that probably the end-user, after a moment of confusion, will write a word in the title field and then, pressing "Search", he will be unable to find what is searching for. </p> <p style="text-align: justify;">Google embraced simplicity and converted this complex form in a single field. Behind this field there is a complex syntax and logic, made of operators and of algorithms to effectively search, but people usually write one or two words in the textbox and it find what they need in the first ten results. Simple but not trivial. Embracing simplicity does not mean being trivial. It only mean to have the ability of hide the complication. </p> <p style="text-align: justify;">Watching to the consumer market, the simplicity become a must. The reason is that if your customer is a business company he will patiently call your helpline to ask you a question, but if the customer is a consumer he will simply delete your app to select another that does exactly what he need. To me, this is the main reason because, with the proposal of Windows Phone 7 and now with Windows 8, Microsoft worked on a series of guidelines that aim to become the standard of a new user experience language, a language that prefers the simplicity. Behind the "Metro Guidelines" there are a number of"pillars" that easily explain the way to the zen of the usability.</p> <h3>The pillars of Metro Style</h3> <p style="text-align: justify;">Embracing a new style in designing an applications may be very hard, primarily because we are used to write our code leaving the aspect of the user interface to a set of "standard" components that leverage an user experience coming from ages ago. Few years ago Microsoft already tried to introduce a new way to design interfaces without a clear success, with WPF and Silverlight. I still remember the moan from people that just discovered the absence of a datagrid control in the Windows Presentation Foundation.</p> <p style="text-align: justify;">The proposition in leaving controls like the datagrid out of the games was a clear indication to people to search for a completely new user experience but unfortunately this call falled on a dry ground. The reason is to search in the absence of a proper guideline able to drive people to seamless change the feel about user experience.</p> <p style="text-align: justify;">With Windows Phone and now with Windows 8, Microsoft changes the strategy, proposing a slim set of rules called "Metro Design Principles". These guidelines are based on five pillars that can easily drive in embracing the change. Here is these pillars in my personal order of priority:</p> <h4>Be authentically digital</h4> <p style="text-align: justify;"><a href="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/image_10.png"><img style="border: 0px; background-image: none; margin: 0px 14px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; float: left;" title="image" alt="image" src="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/image_thumb_4.png" width="290" height="232" /></a>The first, and to me most significative pillar of Metro, is to be Authentically Digital. To understand the meaning of this sentence you have to recall the look and feel of applications in Windows, and of a number of websites still existing on the net. The problem is that you have to finally recognize the digital nature of the screen surface and this must only drive to the removal of every type of <a href="http://medialoot.com/blog/skeuomorphic-design/" target="_blank">skeuomorphic design</a>. Under this strange term is hidden a number of tecniques used to render the feel of materials, embossing, light effect and whatever else that imitate the real world. iOS devices like the iPad make a deep use of skeuomorphism and this pose them on the very opposite side of the Metro guidelines. The direction instead it to remove every kind of chrome in favor of content to valorize is together with the empty space between parts. Just remember the sentence from <a href="http://en.wikipedia.org/wiki/Antoine_de_Saint-Exup%C3%A9ry" target="_blank">Antoine de Saint-Exupéry</a> an recognize the emptiness as a value that isolate and point out your content.</p> <h4>Do more with less</h4> <p style="text-align: justify;"><a href="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/image_6.png"><img style="border: 0px; background-image: none; margin: 5px 0px 0px 15px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; float: right;" title="image" alt="image" src="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/image_thumb_2.png" width="266" height="213" /></a>If being digital is the most important pillar, doing more with less is probably the most difficult to achieve, and nothing more that removing instead of add may be the way to this pillar. I think it is important to stop yourself every time you decide to add something to your application and, instead, brainstorming to understand if the same feature cannot be added slightly changing something that still exists. This is to me the essence of doing more with less, having the ability of regroup your features in a way that remove the need of additional graphic elements. But please avoid to add strange semantic to the gestures of the user, just for the reason of omitting an element in the interface.</p> <h5 style="text-align: justify;"><a href="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/image_8.png"><img style="border: 0px; background-image: none; margin: 0px 14px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; float: left;" title="image" alt="image" src="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/image_thumb_3.png" width="161" height="471" /></a></h5> <h4>Be fast and fluid</h4> <p style="text-align: justify;">Often, the key to make more with less is being fast. Having a number of elements on the screen, can be easily exchanged with having few elements if you can navigate through the application fastly and fluidly. Being fast make your screen larger and Metro offers a number of controls that leverage the use of fingers to improve fluidity without neglect the use of mouse. Thanks to these control it is really easy to create amazing interfaces, expand the size of the screen and adapt your content to the target resolution. Also you can use a set of transitions that helps to join together fluidly the various parts of your application.</p> <h4>Show pride in craftsmanship</h4> <p style="text-align: justify;">I admit it take long to really understand what this means, but finally I've got the point. It simply states that your app must be polished and complete in every single feature. Complete does not only mean "working" but you have to care about details. The right margin, a perfect size for your fonts, a polished palette, a subtle animation to give the right feedback to the user. Every single aspect of the user interface contributes to the overall quality. </p> <h4>Win as one.</h4> <p style="text-align: justify;">And finally, you have to be aware that your app live into an ecosystem. Thanks to a number of interfaces, a Metro application can easily share, search and pick, taking advantage of other applications and providing services to others. It is important you implement these interfaces to give an additional gear to your work.</p> <h4>Don't be afraid of emptiness</h4> <p>I know, lot of people when is about to create a user interface ask himself: what can I do to fill this hole? The problem isn't the hole per se, but probably its positions, the disposition of elements on the screen. Make things bigger, use the right color and positions and the hole easily becomes space. Your eye needs it at a degree you may be surprised.</p> <p>I hope I've touched you curiosity with this long article and now you can experiment the new Metro principles by yourself. From the next time I will return to my programmer role to explore the beautiful features behind Metro.</p> http://www.silverlightshow.net/items/Windows-8-Metro-Create-your-apps-with-simplicity-in-mind.aspx editorial@silverlightshow.net (Andrea Boschin ) http://www.silverlightshow.net/items/Windows-8-Metro-Create-your-apps-with-simplicity-in-mind.aspx#comments http://www.silverlightshow.net/items/Windows-8-Metro-Create-your-apps-with-simplicity-in-mind.aspx Wed, 04 Apr 2012 01:30:13 GMT Working with Prism 4 Part 4: Region Navigation <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-4-Region-Navigation.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-4-Region-Navigation.aspx" data-count="horizontal" data-text="Reading the article 'Working with #Prism 4: Region Navigation' by @briannoyes" data-url="http://slshow.net/x6v7VK">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-4-Region-Navigation.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p>This is part 4 in the series Working with Prism 4.</p> <h3>Introduction</h3> <p>At Microsoft <a href="http://asp.net/" target="_blank">ASP.NET</a> <a href="http://devconnections.com/" target="_blank">Connections</a> March 26- 29 2012 I’ll be presenting a session on Prism development that includes the capabilities covered in this article – the URI-based navigation capabilities of Prism.  </p> <div style="border:1px solid #dddddd;border-image: initial; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;"> <h3>More resources...</h3> <ul style="list-style-type: circle; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Webinars.aspx">Upcoming SilverlightShow <strong>Webinars</strong></a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/video/WCF-RIA-Services-Webinar-4.aspx">Recordings of the Webinar Series: <strong>WCF RIA Services</strong></a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/prism4.aspx">The Prism 4 Series is also available as an Ebook:</a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/prism4.aspx"><img style="border:0px solid; border-image: initial; width: 121px; height: 170px;" alt="Working with Prism 4 - ebook by Brian Noyes" src="http://www.silverlightshow.net/Storage/Ebooks/prism.png" usemap="#rade_img_map_1291385581316" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> In this article I am going to right some wrongs in the code from the past couple articles that I put there to keep things simple and focused on other things for the first few articles. When using the MVVM pattern, one of the major goals is to maintain loose coupling and separation of concerns between views and their view models. But even more important is that different view models should not be coupled to each other unless it is a parent-child kind of relationship, and view models should not be coupled to other views or their own view either. When I set up the code in the previous article to load and switch CustomerEditView instances and their view models, I did it all from the CustomerListViewModel. That code involved using the Prism RegionManager to do the view loading and switching, but it required me to create instances of CustomerEditView and CustomerEditViewModel in the code of CustomerListViewModel. That is a violation of the decoupling goals of MVVM. <p>To fix this I am going to leverage one of the other features of Prism 4 – view switching navigation. In the previous articles, you have seen two parts of the API of the RegionManager service. One involved the Add and Activate methods of the IRegionManager interface. These allow you to explicitly add a view to a region and activate (or show) it at the appropriate times. You also saw in the last article that the AddToRegion method simplifies the process of adding a view if it will be the only. However, these approaches require you to have a view instance available to pass to the methods. That means the code that makes those calls is inherently coupled to the view instances. If you also need to initialize some state of the view model at the point where you are adding the views, that means you might also be coupled to the view model class in that same code. This is the code I placed in the CustomerListViewModel that really should not have been there.</p> <p>The sample code for this article builds on the code from the last article. You can download the <a href="http://www.silverlightshow.net/Storage/Sources/Prism4CompositeCommandAndEventsSample.zip" target="_self">completed code from Part 3</a> here. You can <a href="http://www.silverlightshow.net/Storage/Sources/Prism4ViewNavigationSample.zip" target="_self">download the completed code for this article here</a>.</p> <h3>View Switching Navigation</h3> <p>In Prism 4 the capability was added to have a more implicit and loosely coupled form of view switching that mimics the URI-based navigation of the web. If you think about what a user is doing when they navigate to a particular page on  a web site by putting in an address, they are not really requesting a specific implementation of a page, they are requesting a named view that is the relative portion of the URI (minus the site address at the root). Through mechanisms like the ASP.NET Routing Service, that URI could map to any kind of implementation behind the scenes, and the requester need not know what or where it is. They just need to know the logical name of the view they are trying to get to in the form of a URI. Additionally, the web addressing scheme allows you to pass additional information as part of the URI, including parameters to be passed to the receiver of the request.</p> <p>If a view model or other code is going to cause views to switch out in the user interface, it would be nice if that code had the same degree of decoupling from the implementation of the target views as well as a similar logical addressing mechanism. Prism added a great capability that mimics this to load and switch views within a region based on an extension method that was added to the IRegionManager interface, called RequestNavigate. This method has several overloads, but they all take two key parameters: the region name in which you want navigation to happen (similar to the site root address in the web browser analogy) and the logical name of the view you want to navigate to. The caller of the method does not have to know what view type or instance the request for navigation maps to, it just knows there is a logical view out there that is wants to see.</p> <p>This capability includes more than just the ability to load a view into a region. You can pass parameters to its view or view model as part of the navigation request, and the view or view model can use that information to initialize itself or to refresh its state. The view or view model can participate in the decision of whether to create a whole new view or to reuse one that has been shown before. The view can also participate in deciding if and when the navigation can be completed, so that it could for example prompt the user to save changes or to allow the view switching. I’ll be showing you how to leverage all of this in this article.</p> <h3>Step 1: Export the views by logical name</h3> <p>The first modification to make is to declare the logical name of the view as it will be requested by a piece of code wanting to navigate to it. The way this is done with MEF is by using the [Export] attribute with a contract name. When a view is first requested within a region, Prism will create a new instance of it, add it to the region, and activate it. Subsequent requests to navigate to that view type will either get a new instance or will reuse the existing instance, base on some interfaces I’ll discuss a little later in the article.</p> <p>The modifications to the views look like this:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> [Export(<span class="str">"CustomerListView"</span>)]</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> [PartCreationPolicy(CreationPolicy.NonShared)]</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> CustomerListView : UserControl</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> ...</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> }</pre> <!--CRLF--></div> </div> <p>Notice the association of the logical name with the class. In this case, they happen to be the same. But there is no requirement for them to match. The PartCreationPolicy is required because by default, MEF creates singleton instances of any class it exports unless you change the CreationPolicy to NonShared as shown. This allows us to have multiple instances of the view if desired.</p> <p>Do the same for the CustomerEditView:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> [Export(<span class="str">"CustomerEditView"</span>)]</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> [PartCreationPolicy(CreationPolicy.NonShared)]</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> CustomerEditView : UserControl</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd">public</span> CustomerEditView()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> InitializeComponent();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> }</pre> <!--CRLF--></div> </div> <h3>Step 2: Switch to “View First” construction of the CustomerEditViewModel</h3> <p>In the previous article’s code, the CustomerEditViewModel and CustomerEditView were being constructed and married together by code in the CustomerListViewModel. That is part of what we are trying to fix. It is much easier and better from a development tools perspective (Visual Studio and Blend designers – aka “Blendability”) and code simplicity perspective if the view creates the view model declaratively in the XAML. The CustomerListView and OrdersView were already doing this, but I needed to switch the CustomerEditViewModel so that it is structured the same so that when the view gets constructed (which will happen in the Prism framework with the navigation features we are looking at), the view model is also created and wired up as the view’s DataContext.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd"><</span><span class="html">UserControl</span> <span class="attr">x:Class</span><span class="kwrd">="Prism101.Modules.Core.CustomerEditView"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="attr">xmlns:local</span><span class="kwrd">="clr-namespace:Prism101.Modules.Core"</span></pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> ...<span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd"><</span><span class="html">UserControl.DataContext</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd"><</span><span class="html">local:CustomerEditViewModel</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd"></</span><span class="html">UserControl.DataContext</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> <span class="kwrd"></</span><span class="html">UserControl</span><span class="kwrd">></span></pre> <!--CRLF--></div> </div> <h3>Step 3: Request navigation to the CustomerListView on initial load</h3> <p>This step is not explicitly required, but just want to show an alternative to the initial adding of the CustomerListView to the main region. In the previous few articles, the Core module’s IModule.Initialize code looked like this:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">void</span> Initialize()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> var view = <span class="kwrd">new</span> CustomerListView();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> RegionManager.AddToRegion(<span class="str">"MainContent"</span>, view);</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> }</pre> <!--CRLF--></div> </div> <p>Instead, using the navigation features, we could do this:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">void</span> Initialize()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> RegionManager.RequestNavigate(<span class="str">"MainContent"</span>, <span class="str">"CustomerListView"</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> }</pre> <!--CRLF--></div> </div> <p>Not a huge savings there, but at least this code no longer has to be coupled to the CustomerListView type and worry about its instance lifetime. In the next few steps you will see how it can really start to shine in other areas.</p> <h3>Step 4: Remove the view model coupled code</h3> <p>In the last article, I had the following code invoked when the Edit button was pressed in the CustomerListViewModel:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnEditCustomer()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> IRegion secondaryContentRegion = RegionManager.Regions[<span class="str">"SecondaryContent"</span>];</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">bool</span> alreadyExists = <span class="kwrd">false</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd">foreach</span> (var view <span class="kwrd">in</span> secondaryContentRegion.Views)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> var custView = view <span class="kwrd">as</span> CustomerEditView;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> var custViewModel = custView.DataContext <span class="kwrd">as</span> CustomerEditViewModel;</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> <span class="kwrd">if</span> (custViewModel.Customer == SelectedCustomer)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> secondaryContentRegion.Activate(view);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> alreadyExists = <span class="kwrd">true</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum13" class="lnum"> 13:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum15" class="lnum"> 15:</span> <span class="kwrd">if</span> (!alreadyExists)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum17" class="lnum"> 17:</span> CustomerEditView editView = <span class="kwrd">new</span> CustomerEditView();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> CustomerEditViewModel viewModel = <span class="kwrd">new</span> CustomerEditViewModel { Customer = SelectedCustomer };</pre> <!--CRLF--> <pre class="alt"><span id="lnum19" class="lnum"> 19:</span> editView.DataContext = viewModel;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> secondaryContentRegion.Add(editView);</pre> <!--CRLF--> <pre class="alt"><span id="lnum21" class="lnum"> 21:</span> secondaryContentRegion.Activate(editView);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum23" class="lnum"> 23:</span> }</pre> <!--CRLF--></div> </div> <p>This is the code that not only has coupling to the CustomerEditView and CustomerEditViewModel types, it is also doing instance management of those objects, which is really just wrong. Remove all the code in this method.</p> <h3>Step 5: Request navigation to the CustomerEditView for the right customer</h3> <p>Replace the code that was handling editing with the following code:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnEditCustomer()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> var uriQuery = <span class="kwrd">new</span> UriQuery();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">if</span> (SelectedCustomer != <span class="kwrd">null</span>)</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> uriQuery.Add(<span class="str">"customerId"</span>, SelectedCustomer.CustomerID);</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> var uri = <span class="kwrd">new</span> Uri(<span class="str">"CustomerEditView"</span> + uriQuery.ToString(), UriKind.Relative);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> RegionManager.RequestNavigate(<span class="str">"SecondaryContent"</span>, uri);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> }</pre> <!--CRLF--></div> </div> <p>Not only is this code much simpler, you can see that there is no type coupling in there at all. The first part of the method uses a helper object from Prism called UriQuery to formulate a query string with a name of customerId and the value from the selected customer. It then concatenates this with the logical view name it wants to request navigation to, and then calls the RegionManager.RequestNavigate extension method, identifying in which region it wants the view to be shown (SecondaryContent in this case). Could not be simpler, right?</p> <p>Because SecondaryContent happens to be a tab control, it means that each time navigation happens, it could do one of several things:</p> <ul> <li>Add a new tab to the control on every navigation, regardless of what customer is selected </li> <li>Add only one tab and replace its content with the information for the customer identified in the query string (in which case there would not be much point in having a tab control) </li> <li>Add a new tab when the customer identified does not already have an active tab, and if it does just activate it </li> </ul> <p>The last option is the one that will be most intuitive for the user, so that is the one we will go with here. But just realize with the mechanisms I’ll be showing shortly, you could do any of these with the exact same RequestNavigate call.</p> <h3>Step 6: Let the CustomerEditViewModel control its own initialization and instancing</h3> <p>In the code that I stripped out of the CustomerListViewModel, the code was not only managing the instancing of the edit view and view model, it was also initializing the state of the view model by setting the Customer property to the SelectedCustomer. Now that Prism is going to take care of creating the view (and implicitly the view model with the view-first construction), you still need a way to initialize the state of the view model. This can easily be done with an interface defined in Prism called INavigationAware. This interface has three members which allow your view or view model to</p> <ul> <li>Known when it has been navigated to and get access to the query string parameters to initialize state </li> <li>Known when it is being navigated away from (to do something like persist its state to a cache, service, or DB) </li> <li>Influence whether the view is the target of the navigation or should be reused for navigating to that view type but with different contents </li> </ul> <p>When RequestNavigate is called for a region, the navigation service that does the handling will check the views that are currently contained by that region. If one matches the URI for the view being requested, it will invoke the IsNavigationTarget method to allow that instance to decide whether it should be activated for the navigation to complete. If the view or view model returns true from that, it will be activated if its URI path matches the one being requested. If it returns false, Prism will create a new instance of the view type and place it in the region and activate it. The method is passed a NavigationContext object that contains the URI and parameters for the request to help guide it in its decision to answer the question “are you the one?”</p> <p>To accommodate the MVVM pattern but not force you to adopt it, whenever Prism looks for an interface implementation on a view, it also checks to see if the DataContext of the view (which should be the view model if doing MVVM) implements it. This allows you to put the logic that supports the interface only on the view model and leave the view as just the structural definition of the visual aspects of the view.</p> <p>After IsNavigationTarget is called, if it returns true, then the OnNavigatedTo method is called  with the same NavigationContext object. This is the chance for the view or view model to initialize itself (possibly based on URI parameters).</p> <p>The implementation of the INavigationAware interface in the CustomerEditViewModel looks like this:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">bool</span> INavigationAware.IsNavigationTarget(NavigationContext navigationContext)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">string</span> custId = navigationContext.Parameters[<span class="str">"customerId"</span>];</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">if</span> (!<span class="kwrd">string</span>.IsNullOrWhiteSpace(custId) && Customer != <span class="kwrd">null</span> && Customer.CustomerID == custId)</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd">return</span> <span class="kwrd">true</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd">return</span> <span class="kwrd">false</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> <span class="kwrd">void</span> INavigationAware.OnNavigatedTo(NavigationContext navigationContext)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> <span class="rem">// Choosing to not refresh the customer every time the view is loaded</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> <span class="kwrd">if</span> (Customer != <span class="kwrd">null</span>) <span class="kwrd">return</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum13" class="lnum"> 13:</span> <span class="rem">// Initial load - Load customer based on ID passed in</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> <span class="kwrd">string</span> custId = navigationContext.Parameters[<span class="str">"customerId"</span>];</pre> <!--CRLF--> <pre class="alt"><span id="lnum15" class="lnum"> 15:</span> <span class="kwrd">if</span> (<span class="kwrd">string</span>.IsNullOrWhiteSpace(custId)) <span class="kwrd">return</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> CustomersDomainContext context = <span class="kwrd">new</span> CustomersDomainContext();</pre> <!--CRLF--> <pre class="alt"><span id="lnum17" class="lnum"> 17:</span> EntityQuery<Customer> custQuery = context.GetCustomersQuery().Where(c => c.CustomerID == custId);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> context.Load(custQuery, OnCustomerLoadCompleted, <span class="kwrd">null</span>);</pre> <!--CRLF--> <pre class="alt"><span id="lnum19" class="lnum"> 19:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum21" class="lnum"> 21:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnCustomerLoadCompleted(LoadOperation<Customer> obj)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum23" class="lnum"> 23:</span> <span class="kwrd">if</span> (obj.HasError)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum24" class="lnum"> 24:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum25" class="lnum"> 25:</span> MessageBox.Show(<span class="str">"Error loading customer: "</span> + obj.Error.Message);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum26" class="lnum"> 26:</span> obj.MarkErrorAsHandled();</pre> <!--CRLF--> <pre class="alt"><span id="lnum27" class="lnum"> 27:</span> <span class="kwrd">return</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum28" class="lnum"> 28:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum29" class="lnum"> 29:</span> Customer = obj.Entities.FirstOrDefault();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum30" class="lnum"> 30:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum31" class="lnum"> 31:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum32" class="lnum"> 32:</span> <span class="kwrd">void</span> INavigationAware.OnNavigatedFrom(NavigationContext navigationContext)</pre> <!--CRLF--> <pre class="alt"><span id="lnum33" class="lnum"> 33:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum34" class="lnum"> 34:</span> }</pre> <!--CRLF--></div> </div> <p>You can see that the logic for IsNavigationTarget checks to see if the query string parameter customerId matches the CustomerID property of the Customer that the view model is managing. If you simply wanted to reuse the view and view model instance and only have one instance of that view type (for containment in a ContentControl for example), you could just hardcode a true return value from the IsNavigationTarget. But in our case we are going to have multiple instances of this view type in a tab control, so we want to use the IsNavigationTarget to drive the logic that if the navigation request is for a customer for which there is already a view, just activate that view. If not, create a new instance of that view type and initialize it based on the customerId.</p> <p>So the OnNavigatedTo method checks to see if the Customer is already set, this view would not be navigated to unless the IsNavigationTarget had found that the Customer matched the request, so there is no initialization needed (unless you wanted to always refresh the customer data from the back end for example). But if the Customer is null, it is the first time activating this view for a given CustomerId, so the code uses RIA Services to load a Customer from the back end. This approach has the additional advantage that the views are more self-deterministic – instead of requiring some other code to know how to get a Customer and shove the right one into the view, the view (or better yet its view model) knows how to go get the right state based on nothing more than a state identifier of some sort that is placed in the query string. This allows you to move the views around within the app, change who their parent view/view model is, and not have to change anything about how the view gets initialized.</p> <p>If you are concerned that this pattern will make you make more round trips to the back end, all you need to do is adopt <a href="http://www.martinfowler.com/eaaCatalog/repository.html" target="_blank">the Repository pattern</a> and have your view models call the repository with their state identifiers, and have the Repository cache the data client side and encapsulate what the cache invalidation scheme is so the views don’t have to worry about it and can just request their current state at any time.</p> <p>Finally, in this case, we have no logic to perform in the OnNavigatedFrom method so we can just leave that one blank.</p> <h3>Step 7: Let the view decide when navigation happens</h3> <p>There is a very important but subtle point in the way the RequestNavigate method is named. It is a request for something to happen, but it doesn’t say when it should happen or make the implication that navigation will be complete when the method returns. Navigation needs to be a non-blocking request because the view that is currently presented might need to do something (such as prompt the user to save) before allowing the navigation to complete. That is inherently a non-deterministic and potentially long-running block (the user might be distracted tweeting in another window for example). Additionally, a view needs to be able to reject navigation because it may be in the middle of an operation it cannot cancel immediately or you may want to let the user decide whether to dismiss a view for example.</p> <p>So the RequestNavigate method is a non-blocking asynchronous call. If the caller needs to know when navigation is complete, there is an overload that takes a callback reference that will be invoked by the Prism navigation service once the navigation happens or is rejected. If the view does want to decide if and when navigation should occur, it (or its view model) implements an interface called IConfirmNavigationRequest. This interface has one method, ConfirmNavigationRequest, which is passed a NavigationContext like the INavigationAware methods, and a callback for the method to invoke when it has decided to either allow the view to be deactivated (navigated away from) or to reject the navigation.</p> <p>In the same application, I chose to demonstrate this by using the IsDirty state of the edit views (the same one that is enabling and disabling Save commands as <a href="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-3-Composite-Command-and-Pub-Sub-Events.aspx" target="_blank">discussed in the last article</a>). If the view state IsDirty, then the view model will prompt the user with a message box to let them confirm or deny navigation with an OK/Cancel action. </p> <p>The implementation of this interface is shown below. You can see that is IsDirty is true, it prompts the user. If they press OK, the callback is invoked with a true argument, meaning navigation can proceed. If Cancel, then it gets invoked with false. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">void</span> IConfirmNavigationRequest.ConfirmNavigationRequest(NavigationContext navigationContext, </pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> Action<<span class="kwrd">bool</span>> continuationCallback)</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">if</span> (IsDirty)</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd">string</span> prompt = <span class="str">"The view's state has changed and has not been saved, do you want to allow view switching?"</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> var result = MessageBox.Show(prompt,<span class="str">"Confirmation"</span>,MessageBoxButton.OKCancel);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> <span class="kwrd">if</span> (result == MessageBoxResult.OK)</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> continuationCallback(<span class="kwrd">true</span>);</pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> <span class="kwrd">return</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum13" class="lnum"> 13:</span> <span class="kwrd">else</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum15" class="lnum"> 15:</span> continuationCallback(<span class="kwrd">false</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> <span class="kwrd">return</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum17" class="lnum"> 17:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum19" class="lnum"> 19:</span> continuationCallback(<span class="kwrd">true</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> }</pre> <!--CRLF--></div> </div> <p>Now the one hitch in the sample application is that because these views are presented in a tab control, the user can click on a tab header at any time and cause view switching to occur and the Prism navigation service would not be involved at all, so your view implementations of the INavigationAware and IConfirmNavigationRequest interfaces would not be called. To intercept and prevent tab switching would require a lot lower interception of events on the tab control. So this mechanism for preventing navigation is better suited for containment in a ContentControl where the user does not have a direct user interface mechanism to cause views to swap. But as long as the changing occurs through the navigation controls you put in place that call RequestNavigate, life will be good.</p> <h3>Summary</h3> <p>In this article, you learned how to leverage the navigation capabilities of Prism in a more loosely coupled and flexible way with the IRegionManager.RequestNavigate method, INavigationAware and IConfirmNavigationRequest interfaces. These capabilities allow you to compose a much more loosely coupled application where no code is explicitly tied to view or view model types. The view models can be designed to operate independently of their containers and the code that causes navigation or view switching to happen does not have to be coupled to what the specific implementation of the view is or how it needs to be initialized. This approach still gives you control over when views are created and added to regions and activated, but puts the control in the hands of the views themselves instead of the code that triggers the navigation.</p> <p>This capability can also be mixed in with the Silverlight navigation framework as shown in <a href="http://blogs.msdn.com/b/kashiffl/archive/2010/10/05/integrating-prism-v4-region-navigation-with-silverlight-frame-navigation.aspx" target="_blank">this article by Karl Shifflet</a>.</p> <p>You can <a href="http://www.silverlightshow.net/Storage/Sources/Prism4ViewNavigationSample.zip" target="_blank">download the completed code for this article here</a>.</p> <h3>About the Author</h3> <p>Brian Noyes is Chief Architect of <a href="http://www.idesign.net/">IDesign</a>, a Microsoft Regional Director, and Silverlight MVP. He is a frequent top rated speaker at conferences worldwide including Microsoft TechEd, DevConnections, VSLive!, DevTeach, and others. Brian worked directly on the Prism team with Microsoft patterns and practices and co-authored the book Developers Guide to Microsoft Prism 4. He is also the author of Developing Applications with Windows Workflow Foundation, Smart Client Deployment with ClickOnce, and Data Binding in Windows Forms 2.0. Brian got started programming as a hobby while flying F-14 Tomcats in the U.S. Navy, later turning his passion for code into his current career. You can contact Brian through his blog at <a href="http://briannoyes.net/">http://briannoyes.net/</a> or on Twitter @briannoyes.</p> http://www.silverlightshow.net/items/Working-with-Prism-4-Part-4-Region-Navigation.aspx editorial@silverlightshow.net (Brian Noyes ) http://www.silverlightshow.net/items/Working-with-Prism-4-Part-4-Region-Navigation.aspx#comments http://www.silverlightshow.net/items/Working-with-Prism-4-Part-4-Region-Navigation.aspx Thu, 16 Feb 2012 16:02:00 GMT Working with Prism 4 Part 3: Composite Command and Pub/Sub Events <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-3-Composite-Command-and-Pub-Sub-Events.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-3-Composite-Command-and-Pub-Sub-Events.aspx" data-count="horizontal" data-text="Reading the article 'Working w/ #Prism 4: Composite Command and Pub/Sub Events' by @briannoyes" data-url="http://slshow.net/wvd1do">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-3-Composite-Command-and-Pub-Sub-Events.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p>This is part 3 in the series Working with Prism 4.</p> <h3>Introduction</h3> <p>In the last article, I showed how to structure your Prism application to use the MVVM pattern and use DelegateCommands to communicate between the view and view model. Additionally, I showed how to pull some data in using WCF RIA Services and display it in the view, as well as using Prism Regions and the ability to add and activate different views in a region to accomplish simple navigation for the user (view switching).</p> <div style="border:1px solid #dddddd;border-image: initial; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;"> <h3>More resources...</h3> <ul style="list-style-type: circle; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Webinars.aspx">Upcoming SilverlightShow Webinars</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/video/WCF-RIA-Services-Webinar-4.aspx">Recordings of the Webinar Series: WCF RIA Services</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/prism4.aspx">The Prism 4 Series is also available as an Ebook:</a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/prism4.aspx"><img style="border:0px solid; border-image: initial; width: 121px; height: 170px;" alt="Working with Prism 4 - ebook by Brian Noyes" src="http://www.silverlightshow.net/Storage/Ebooks/prism.png" usemap="#rade_img_map_1291385581316" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <p>In this article, I’ll extend that sample application a little farther and show you how to leverage two other loosely coupled communication features of Prism 4: CompositeCommands and Prism CompositePresentationEvents (aka pub/sub events). The code presented in this article builds on what was the completed code from the last article.</p> <p>You can <a href="http://www.silverlightshow.net/Storage/Sources/Prism4MVVMAndCommandsSamplePart2.zip" target="_blank">download the complete code from the last article that acts as the starting point here</a>. You can <a href="http://www.silverlightshow.net/Storage/Sources/Prism4CompositeCommandAndEventsSample.zip">download the completed code for this article here</a>.</p> <p>Note: Now that Silverlight 5 has released, the code for this article uses an updated version of the Prism 4 code recompiled to Silverlight 5 as a target. That code can be downloaded from <a href="http://prism.codeplex.com/" target="_blank">prism.codeplex.com</a> and is included in the completed code sample for this article.</p> <h3>CompositeCommands</h3> <p>CompositeCommands are another implementation of the ICommand interface defined by Silverlight and WPF. There are several differences about the CompositeCommand implementation and the DelegateCommand implementation. The first is that the CompositeCommand is an aggregation of other commands – a list of ICommand references internally. It allows you to hook up multiple command targets to a single root command that itself can be hooked up to a command source such as a button or menu item. Figure 1 shows this relationship. The CompositeCommand can hold references to any ICommand object, but typically you will use it in conjunction with DelegateCommands. When the CompositeCommand.Execute method is invoked, it will invoke the Execute method on each of the child commands. When CompositeCommand.CanExecute is called to determine whether the command is enabled, it polls its child commands for their result from CanExecute.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/brian.noyes/___Figure1_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;border-style: solid;" title="Figure1" alt="Figure1" src="http://www.silverlightshow.net/Storage/Users/brian.noyes/___Figure1_thumb.png" width="362" height="271" /></a></p> <p><strong>Figure 1: CompositeCommands contain other commands</strong></p> <p>Child commands register themselves with the composite command and can also unregister if appropriate. In this way, it is very similar to a subscribe/unsubscribe of an event, but with the additional functionality of commands to enable and disable the commands based on custom logic.</p> <p>Another thing different about CompositeCommands is that they can be hooked up to a source control ahead of time, before any child commands have registered. DelegateCommands have to be pointed to their target methods through a delegate at the point where they are constructed. As a result, CompositeCommands allow an extra layer of separation between the source (i.e. toolbar button or menu item) and the target (handling method) – decoupled in lifetime. Because they can target multiple child commands, they also work well for distributed logic such as a Save All command that needs to be dispatched to multiple open documents, each of which has their own handling logic in their view model.</p> <p>You will see both of these aspects at work in the sample code for this article – separated hook up of the command, and multiple handlers for command execution.</p> <h3>Pub/Sub Events</h3> <p>Another form of loosely coupled communications offered by Prism are pub/sub events. Normal events in .NET are fairly tightly coupled – both the publisher and subscriber objects have to be alive at the same time, the subscriber needs explicit type information and a reference to the publisher to hook up their event handler, and once subscribed, the publisher maintains a reference back to the subscriber through the delegate.</p> <p>Pub/sub events are designed to break that tight coupling. The idea is that you really want publishers and subscribers to not need either type information or coupled lifetimes. They should be able to come and go independently, and different types of subscribers and publishers should be able to participate in the same event scenario. The event is what is important, not the specific parties who raise or handle the events. To achieve this, you need a middleman or mediator between the publishers and subscribers. The <a href="http://www.martinfowler.com/eaaDev/EventAggregator.html" target="_blank">Event Aggregator</a> pattern is a means of achieving this. Prism provides an implementation of the Event Aggregator pattern that is easy to use and that provides several options including strong or weak references for subscribers, thread dispatching, and event filtering. </p> <p>Figure 2 shows the basic architecture of using the EventAggregator service in Prism. Publishers and Subscribers make calls directly against the EventAggregator to obtain references to event class instances. The EventAggregator is really nothing more than a <a href="http://martinfowler.com/eaaCatalog/registry.html" target="_blank">Registry</a> for event types. Publishers then use those event classes to publish an event with a strongly typed payload and subscribers hook up a listener through a delegate to a method that will accept the payload and handle the event for that subscriber. The event classes are derived from CompositePresentationEvent and do not need any implementation themselves, the class declaration is really just a way to tie together a base class reference with the strongly typed payload through the generic type definition. The CompositePresentationEvent base class provides all the infrastructure to maintain the list of subscribers, dispatch the calls on the appropriate thread, maintain weak or strong references, and filter the calls if desired.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/brian.noyes/Figure2_4.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;border-style: solid;" title="Figure2" alt="Figure2" src="http://www.silverlightshow.net/Storage/Users/brian.noyes/Figure2_thumb_1.png" width="669" height="301" /></a></p> <p><strong>Figure 2: Event Aggregator Architecture</strong></p> <h3></h3> <h3>Step 1: Add the Prism Libraries and Recompile for Silverlight 5</h3> <p>The first step for this article is that I downloaded a recently added source code release of Prism 4 from the <a href="http://compositewpf.codeplex.com/SourceControl/list/changesets" target="_blank">CodePlex site</a> and added the projects to the solution, as well as changing their compilation target to Silverlight 5. This is because there were a few incompatibilities discovered in using the Silverlight 4 versions of the libraries with Silverlight 5. And I actually stumbled upon one of those incompatibilities in putting together the sample for this article.</p> <h3>Step 2: Modify the application to present multiple edit views </h3> <p>To demonstrate the use of CompositeCommands, I wanted to have a reasonably realistic scenario of where you might use them. As mentioned earlier, CompositeCommands let you separate the hook up of the invoker from the hookup of the receiver in terms of the <a href="http://en.wikipedia.org/wiki/Command_pattern" target="_blank">Command pattern</a>. They also let you have multiple handlers for a given command, to address a Save All kind of scenario, which is what I will be putting together in this article.</p> <p>To do this, I need more than one thing open at a time to save. I added a TabControl to the MainPage shell view and made it a Prism Region so that multiple CustomerEditView instances could be opened in tabs there instead of swapping out the MainContent region view as was done in the last article.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd"><</span><span class="html">sdk:TabControl</span> <span class="attr">prism:RegionManager</span>.<span class="attr">RegionName</span><span class="kwrd">="SecondaryContent"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="2"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd"><</span><span class="html">prism:TabControlRegionAdapter.ItemContainerStyle</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd"><</span><span class="html">Style</span> <span class="attr">TargetType</span><span class="kwrd">="sdk:TabItem"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd"><</span><span class="html">Setter</span> <span class="attr">Property</span><span class="kwrd">="HeaderTemplate"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd"><</span><span class="html">Setter.Value</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> <span class="kwrd"><</span><span class="html">DataTemplate</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> <span class="kwrd"><</span><span class="html">StackPanel</span> <span class="attr">Orientation</span><span class="kwrd">="Horizontal"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> <span class="kwrd"><</span><span class="html">TextBlock</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> <span class="attr">Margin</span><span class="kwrd">="3"</span></pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> <span class="attr">Text</span><span class="kwrd">="{Binding Title}"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> <span class="kwrd"><</span><span class="html">Button</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span></pre> <!--CRLF--> <pre class="alt"><span id="lnum13" class="lnum"> 13:</span> <span class="attr">Margin</span><span class="kwrd">="3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> <span class="attr">Content</span><span class="kwrd">="X"</span></pre> <!--CRLF--> <pre class="alt"><span id="lnum15" class="lnum"> 15:</span> <span class="attr">Command</span><span class="kwrd">="{Binding CloseCommand}"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> <span class="kwrd"></</span><span class="html">StackPanel</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum17" class="lnum"> 17:</span> <span class="kwrd"></</span><span class="html">DataTemplate</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> <span class="kwrd"></</span><span class="html">Setter.Value</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum19" class="lnum"> 19:</span> <span class="kwrd"></</span><span class="html">Setter</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> <span class="kwrd"></</span><span class="html">Style</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum21" class="lnum"> 21:</span> <span class="kwrd"></</span><span class="html">prism:TabControlRegionAdapter.ItemContainerStyle</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> <span class="kwrd"></</span><span class="html">sdk:TabControl</span><span class="kwrd">></span></pre> <!--CRLF--></div> </div> <p>Note the attached property to indicate that this is a Prism Region as discussed in the last two articles, as well as a Style to modify the HeaderTemplate of the TabItems in the TabControl to contain a TextBlock and an X Button to be able to close them. This style gets attached through a custom attached property provided by Prism called TabControlRegionAdapter.ItemContainerStyle. This is needed because the TabControlRegionAdapter is the thing in the Prism toolkit that generates the TabItems as views are added to the region. Also note that the template expects the DataContext to have a Title property for the text in the tab header, as well as a CloseCommand for the button Command. Those will be present on the view models for the individual views which are set as the DataContext based on the MVVM pattern.</p> <p>To populate the tabs, the EditCommand handling code in the CustomerListViewModel changed to the following:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnEditCustomer()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> IRegion secondaryContentRegion = RegionManager.Regions[<span class="str">"SecondaryContent"</span>];</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">bool</span> alreadyExists = <span class="kwrd">false</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd">foreach</span> (var view <span class="kwrd">in</span> secondaryContentRegion.Views)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> var custView = view <span class="kwrd">as</span> CustomerEditView;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> var custViewModel = custView.DataContext <span class="kwrd">as</span> CustomerEditViewModel;</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> <span class="kwrd">if</span> (custViewModel.Customer == SelectedCustomer)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> secondaryContentRegion.Activate(view);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> alreadyExists = <span class="kwrd">true</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum13" class="lnum"> 13:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum15" class="lnum"> 15:</span> <span class="kwrd">if</span> (!alreadyExists)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum17" class="lnum"> 17:</span> CustomerEditView editView = <span class="kwrd">new</span> CustomerEditView();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> CustomerEditViewModel viewModel = <span class="kwrd">new</span> CustomerEditViewModel { Customer = SelectedCustomer };</pre> <!--CRLF--> <pre class="alt"><span id="lnum19" class="lnum"> 19:</span> editView.DataContext = viewModel;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> secondaryContentRegion.Add(editView);</pre> <!--CRLF--> <pre class="alt"><span id="lnum21" class="lnum"> 21:</span> secondaryContentRegion.Activate(editView);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum23" class="lnum"> 23:</span> }</pre> <!--CRLF--></div> </div> <p>This code is very similar to what was discussed in the last article – it determines if there is a view already being presented within the “SecondaryContent” region for the selected customer. If so, it activates it. If not, it adds one. The main difference here is that the code is now targeting the SecondaryContent region, which is the tab control, and it allows more than one view to be created at a time.</p> <p>The structure of the CustomerEditView itself did not change at all, but the CustomerEditViewModel had to change quite a bit. First, it needed to have the Title and CloseCommand properties expected by the tab item headers.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">string</span> Title { get { <span class="kwrd">return</span> _Customer != <span class="kwrd">null</span> ? _Customer.CustomerID : <span class="str">"Empty"</span>; } }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">public</span> DelegateCommand CloseCommand { get; <span class="kwrd">private</span> set; }</pre> <!--CRLF--></div> </div> <p>Second, the CloseCommand handling needs to simply remove its view from the region, not swap views as the SaveCommand handling did from the last article:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnClose()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> IRegion secondaryContentRegion = RegionManager.Regions[<span class="str">"SecondaryContent"</span>];</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">foreach</span> (var view <span class="kwrd">in</span> secondaryContentRegion.Views)</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd">if</span> (view <span class="kwrd">is</span> CustomerEditView && ((FrameworkElement)view).DataContext == <span class="kwrd">this</span>)</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> secondaryContentRegion.Remove(view);</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> <span class="kwrd">break</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> }</pre> <!--CRLF--></div> </div> <p>Third, it needed the SaveCommand logic to not swap views but to just manage the “saved” state of the view. In this case, for demo purposes, that meant just modifying the view model to support an IsDirty flag. That flag gets set when the customer is modified (one of its properties change). The flag gets cleared when the SaveCommand fires. Additionally, the SaveCommand was modified to have a CanExecute handler that checks that IsDirty flag. If the view’s state is not dirty, there is no reason to invoke the SaveCommand so its invoker should be disabled.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> Customer _Customer;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="kwrd">bool</span> _IsDirty = <span class="kwrd">false</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">public</span> CustomerEditViewModel()</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> SaveCommand = <span class="kwrd">new</span> DelegateCommand(OnSave, CanSave);</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> ...</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> <span class="kwrd">public</span> DelegateCommand SaveCommand { get; <span class="kwrd">private</span> set; }</pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> <span class="kwrd">public</span> Customer Customer</pre> <!--CRLF--> <pre class="alt"><span id="lnum13" class="lnum"> 13:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> get { <span class="kwrd">return</span> _Customer; }</pre> <!--CRLF--> <pre class="alt"><span id="lnum15" class="lnum"> 15:</span> set</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum17" class="lnum"> 17:</span> <span class="kwrd">if</span> (_Customer != <span class="kwrd">value</span>)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum19" class="lnum"> 19:</span> <span class="kwrd">if</span> (_Customer != <span class="kwrd">null</span>) _Customer.PropertyChanged -= OnCustomerChanged;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> _Customer = <span class="kwrd">value</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum21" class="lnum"> 21:</span> <span class="kwrd">if</span> (_Customer != <span class="kwrd">null</span>) _Customer.PropertyChanged += OnCustomerChanged;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> RaisePropertyChanged(() => Customer);</pre> <!--CRLF--> <pre class="alt"><span id="lnum23" class="lnum"> 23:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum24" class="lnum"> 24:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum25" class="lnum"> 25:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum26" class="lnum"> 26:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum27" class="lnum"> 27:</span> <span class="kwrd">public</span> <span class="kwrd">bool</span> IsDirty</pre> <!--CRLF--> <pre class="alteven"><span id="lnum28" class="lnum"> 28:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum29" class="lnum"> 29:</span> get</pre> <!--CRLF--> <pre class="alteven"><span id="lnum30" class="lnum"> 30:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum31" class="lnum"> 31:</span> <span class="kwrd">return</span> _IsDirty;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum32" class="lnum"> 32:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum33" class="lnum"> 33:</span> set</pre> <!--CRLF--> <pre class="alteven"><span id="lnum34" class="lnum"> 34:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum35" class="lnum"> 35:</span> _IsDirty = <span class="kwrd">value</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum36" class="lnum"> 36:</span> SaveCommand.RaiseCanExecuteChanged();</pre> <!--CRLF--> <pre class="alt"><span id="lnum37" class="lnum"> 37:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum38" class="lnum"> 38:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum39" class="lnum"> 39:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum40" class="lnum"> 40:</span> <span class="kwrd">private</span> <span class="kwrd">bool</span> CanSave()</pre> <!--CRLF--> <pre class="alt"><span id="lnum41" class="lnum"> 41:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum42" class="lnum"> 42:</span> <span class="kwrd">return</span> IsDirty;</pre> <!--CRLF--> <pre class="alt"><span id="lnum43" class="lnum"> 43:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum44" class="lnum"> 44:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum45" class="lnum"> 45:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnSave()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum46" class="lnum"> 46:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum47" class="lnum"> 47:</span> IsDirty = <span class="kwrd">false</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum48" class="lnum"> 48:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum49" class="lnum"> 49:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum50" class="lnum"> 50:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnCustomerChanged(<span class="kwrd">object</span> sender, PropertyChangedEventArgs e)</pre> <!--CRLF--> <pre class="alt"><span id="lnum51" class="lnum"> 51:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum52" class="lnum"> 52:</span> IsDirty = <span class="kwrd">true</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum53" class="lnum"> 53:</span> }</pre> <!--CRLF--></div> </div> <p>Notice that the CanSave handler just returns the flag. But since the enablement of the command depends on that flag, that means whenever that flag changes, the command should raise the CanExecuteChanged event. The best way to do that is to encapsulate the call to the DelegateCommand.RaiseCanExecuteChanged method in the setter for the IsDirty property and use that property internally throughout the view model instead of the member variable.</p> <p>At this point I have the setup to be able to edit multiple customer views at the same time in individual tabs. Next I want to be able to add a “Save All” command invoker at a shell level and have it invoke the SaveCommand on the individual open edit views as shown in Figure 3.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/brian.noyes/__Figure3_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;border-style: solid;" title="Figure3" alt="Figure3" src="http://www.silverlightshow.net/Storage/Users/brian.noyes/__Figure3_thumb.png" width="693" height="497" /></a></p> <p><strong>Figure 3: Multiple edit views active in the tab region</strong></p> <h3>Step 3: Add a CompositeCommand for the Save All command</h3> <p>A common way to define a CompositeCommand is similar to how WPF defines the built-in routed commands – as a public static readonly singleton instance of the command. In order for the invoker to be in one module and the handlers to be in different modules, they all need to be able to get to that definition of that command to hook up to it. So you will need to have a common or shared assembly that all the parts of your solution can reference to hold shared types like CompositeCommands and Pub/Sub events.</p> <p>The sample solution has a Silverlight Class Library project added with a Commands class to contain the CompositeCommand instances you want to define – in this case the SaveAllCommand.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">class</span> Commands</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> CompositeCommand SaveAllCommand = <span class="kwrd">new</span> CompositeCommand();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> }</pre> <!--CRLF--></div> </div> <h3> </h3> <h3>Step 4: Hook up the CompositeCommand Invoker</h3> <p>The invoker is simply a button in the MainPage.xaml:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd"><</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">="Save All"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="attr">Command</span><span class="kwrd">="{Binding SaveAllCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"</span> <span class="kwrd">/></span></pre> <!--CRLF--></div> </div> <p>If you are using CompositeCommands in WPF, you can refer directly to the static instance with the {x:Static} markup extension. Because Silverlight does not have that markup extension in the framework, you will have to bind to a property exposed to your XAML. In this case to keep it simple, I expose that property from the code behind of the MainPage view itself and use a RelativeSource binding to get to the root element that corresponds to the code behind class. Then in the code behind I expose the static command variable via the property that the XAML is binding to. Alternatively I could have just hooked up the command in the code behind with a reference to the button.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> ICommand SaveAllCommand { get { <span class="kwrd">return</span> Commands.SaveAllCommand; } }</pre> <!--CRLF--></div> </div> <p>At this point the invoker is ready to invoke the command, but the button will be disabled because the CompositeCommand, as a container for command instances, is empty. The default logic of CompositeCommand is to be disabled unless <strong>all </strong>of its child commands are enabled. If there are no child commands, it is disabled because there is nothing to invoke. If you find you want different logic, such as enabling the command if <strong>any one</strong> of its child commands is enabled, all you need to do is derive a class from CompositeCommand and override the CanExecute method.</p> <h3>Step 5: Hook up the child command instances</h3> <p>As mentioned earlier, CompositeCommand exposes a Register/Unregister API for adding and removing child commands. To add a child command, simply call Register, passing an ICommand reference. Because the CustomerEditViewModel already has a SaveCommand that I want invoked when Save All is invoked, I just need to pass a reference to that in the constructor for the view model:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> Commands.SaveAllCommand.RegisterCommand(SaveCommand);</pre> <!--CRLF--></div> </div> <p>Likewise, when the view is going away (in the CloseCommand handler), you should unregister the command, otherwise the CompositeCommand will keep it, and be indirection, your view model, alive.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnClose()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> IRegion secondaryContentRegion = RegionManager.Regions[<span class="str">"SecondaryContent"</span>];</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">foreach</span> (var view <span class="kwrd">in</span> secondaryContentRegion.Views)</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd">if</span> (view <span class="kwrd">is</span> CustomerEditView && ((FrameworkElement)view).DataContext == <span class="kwrd">this</span>)</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> secondaryContentRegion.Remove(view);</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> Commands.SaveAllCommand.UnregisterCommand(SaveCommand);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> <span class="kwrd">break</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum13" class="lnum"> 13:</span> }</pre> <!--CRLF--></div> </div> <p>At this point you should be able to run the application and open several edit views as shown in Figure 3. Initially all of the Save buttons in the edit views as well as the Save All button will be disabled because none of the views are dirty. Go make an edit to each one of the views, and you will see their individual Save button become enabled. With the default CanExecute logic of the CompositeCommand, not until all of the child commands becomes enabled is the CompositeCommand itself enabled. So at the point where you have each of the child views Save enabled through an edit, the Save All button will become enabled. Clicking it invokes the SaveCommand handler in each instance of the CustomerEditViewModel, setting its IsDirty flag to false and raising the CanExecuteChanged handler for that command, which the CompositeCommand will monitor to refresh its own command enabled state.</p> <h3>Step 6: Add an Orders Module</h3> <p>A common usage of pub/sub events is to communicate between loosely coupled module components, particularly from one view model to another, especially if those view models are defined in separate modules. To demonstrate this, I want to add the capability to display the last 10 products ordered by a customer in a side panel whenever a customer is selected. I want this functionality to be decoupled from the customer listing and editing capabilities in the Core module, possibly developed by a separate team or added as a separate pluggable feature of the application.</p> <p>To do this, I added a new Orders module to the solution following the procedures outlined in the first article for defining a Prism module:</p> <ol> <li>Add a Silverlight Application project</li> <li>Delete MainPage.xaml and App.xaml</li> <li>Set the Startup Object in the project settings to Not Set.</li> <li>Add Prism references, setting the Copy Local property on  the references to false so that you don’t get multiple copies of the Prism libraries loaded when the module loads.</li> <li>Defined an OrdersModule class with a ModuleExport attribute and an implementation of the IModule interface.</li> <li>Added the Orders module to the Silverlight hosting settings of the Web project so that it is available for download by the module manager in Prism.</li> <li>Added module information to the ModuleCatalog.xaml in the shell project.</li> </ol> <p>Additionally, since now both the Core module and the Orders module will need to use WCF RIA Services to retrieve data from the back end, it makes sense to move the client WCF RIA Services code out to a shared library so that there is just one definition of the entity types and the DomainContext that lets the client code talk to the server. As a result, I also did the following in the solution:</p> <ol> <li>Removed the RIA Services link from all the client projects.</li> <li>Added a NorthwindRIAClientLibrary Silverlight Class Library project with the RIA Services link in the project properties set to the hosting web project where the domain services live.</li> <li>Added a reference to NorthwindRIAClientLibrary to each of the projects, with them all set to Copy Local = false except the reference in the shell application.</li> </ol> <h3> </h3> <h3>Step 7: Add another region for the view to plug into</h3> <p>In MainPage.xaml in the shell application, I added another region named SidePanel to the right of the listing of customers for the order summary to plug into.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd"><</span><span class="html">Grid</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="1"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="kwrd"><</span><span class="html">Grid.ColumnDefinitions</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd"><</span><span class="html">ColumnDefinition</span> <span class="attr">Width</span><span class="kwrd">="*"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd"><</span><span class="html">ColumnDefinition</span> <span class="attr">Width</span><span class="kwrd">="Auto"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd"></</span><span class="html">Grid.ColumnDefinitions</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd"><</span><span class="html">ContentControl</span> <span class="attr">prism:RegionManager</span>.<span class="attr">RegionName</span><span class="kwrd">="MainContent"</span></pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="0"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> <span class="attr">Margin</span><span class="kwrd">="5"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> <span class="kwrd"><</span><span class="html">ContentControl</span> <span class="attr">prism:RegionManager</span>.<span class="attr">RegionName</span><span class="kwrd">="SidePanel"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="1"</span></pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> <span class="attr">Margin</span><span class="kwrd">="5"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> <span class="kwrd"></</span><span class="html">Grid</span><span class="kwrd">></span></pre> <!--CRLF--></div> </div> <h3> </h3> <h3>Step 8: Add a View and ViewModel to present the order summary</h3> <p>The view simply contains a DataGrid with three columns: Order date, product name, and quantity. The view model uses WCF RIA Services to retrieve the order information for a given customer and populate a collection of OrderItem data structures to populate the DataGrid with the three columns.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">class</span> OrdersViewModel : INotifyPropertyChanged</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> CustomersDomainContext _Context;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">public</span> OrdersViewModel()</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd">if</span> (!DesignerProperties.IsInDesignTool)</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> _Context = <span class="kwrd">new</span> CustomersDomainContext();</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> ObservableCollection<OrderItem> _Orders = <span class="kwrd">new</span> ObservableCollection<OrderItem>();</pre> <!--CRLF--> <pre class="alt"><span id="lnum13" class="lnum"> 13:</span> <span class="kwrd">public</span> ObservableCollection<OrderItem> Orders</pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum15" class="lnum"> 15:</span> get { <span class="kwrd">return</span> _Orders; }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> set</pre> <!--CRLF--> <pre class="alt"><span id="lnum17" class="lnum"> 17:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> <span class="kwrd">if</span> (_Orders != <span class="kwrd">value</span>)</pre> <!--CRLF--> <pre class="alt"><span id="lnum19" class="lnum"> 19:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> _Orders = <span class="kwrd">value</span>;</pre> <!--CRLF--> <pre class="alt"><span id="lnum21" class="lnum"> 21:</span> PropertyChanged(<span class="kwrd">this</span>, <span class="kwrd">new</span> PropertyChangedEventArgs(<span class="str">"Orders"</span>));</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum23" class="lnum"> 23:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum24" class="lnum"> 24:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum25" class="lnum"> 25:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum26" class="lnum"> 26:</span> <span class="kwrd">public</span> <span class="kwrd">void</span> OnCustomerSelected(Customer cust)</pre> <!--CRLF--> <pre class="alt"><span id="lnum27" class="lnum"> 27:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum28" class="lnum"> 28:</span> Orders = <span class="kwrd">new</span> ObservableCollection<OrderItem>();</pre> <!--CRLF--> <pre class="alt"><span id="lnum29" class="lnum"> 29:</span> <span class="kwrd">if</span> (_Context == <span class="kwrd">null</span> || cust == <span class="kwrd">null</span>)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum30" class="lnum"> 30:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum31" class="lnum"> 31:</span> <span class="kwrd">return</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum32" class="lnum"> 32:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum33" class="lnum"> 33:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum34" class="lnum"> 34:</span> EntityQuery<Order_Detail> detailQuery = _Context.GetOrder_DetailsQuery();</pre> <!--CRLF--> <pre class="alt"><span id="lnum35" class="lnum"> 35:</span> _Context.Load(detailQuery.Where(</pre> <!--CRLF--> <pre class="alteven"><span id="lnum36" class="lnum"> 36:</span> det => det.Order.Customer.CustomerID == cust.CustomerID).OrderByDescending(</pre> <!--CRLF--> <pre class="alt"><span id="lnum37" class="lnum"> 37:</span> det => det.Order.OrderDate).Take(10), OnDetailsLoaded, <span class="kwrd">null</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum38" class="lnum"> 38:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum39" class="lnum"> 39:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum40" class="lnum"> 40:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum41" class="lnum"> 41:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnDetailsLoaded(LoadOperation<Order_Detail> loadOp)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum42" class="lnum"> 42:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum43" class="lnum"> 43:</span> var details = loadOp.Entities;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum44" class="lnum"> 44:</span> <span class="kwrd">if</span> (details != <span class="kwrd">null</span>)</pre> <!--CRLF--> <pre class="alt"><span id="lnum45" class="lnum"> 45:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum46" class="lnum"> 46:</span> var detailsList = details.ToList();</pre> <!--CRLF--> <pre class="alt"><span id="lnum47" class="lnum"> 47:</span> detailsList.ForEach(det => Orders.Add(</pre> <!--CRLF--> <pre class="alteven"><span id="lnum48" class="lnum"> 48:</span> <span class="kwrd">new</span> OrderItem</pre> <!--CRLF--> <pre class="alt"><span id="lnum49" class="lnum"> 49:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum50" class="lnum"> 50:</span> ProductName = det.Product.ProductName,</pre> <!--CRLF--> <pre class="alt"><span id="lnum51" class="lnum"> 51:</span> Quantity = det.Quantity,</pre> <!--CRLF--> <pre class="alteven"><span id="lnum52" class="lnum"> 52:</span> OrderDate = det.Order.OrderDate.Value</pre> <!--CRLF--> <pre class="alt"><span id="lnum53" class="lnum"> 53:</span> }));</pre> <!--CRLF--> <pre class="alteven"><span id="lnum54" class="lnum"> 54:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum55" class="lnum"> 55:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum56" class="lnum"> 56:</span> }</pre> <!--CRLF--></div> </div> <p>Now the only thing left to do is call the OnCustomerSelected method whenever a Customer is selected in the main listing. But that code lives in a totally separate module that you are trying to keep decoupled. Prism events to the rescue.</p> <h3>Step 9: Add a Prism Event</h3> <p>When working with Prism events, the first thing to do is to declare the event type. You do this by deriving a type from CompositePresentationEvent as described earlier, and indicating through the generic type argument what the payload type will be:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">class</span> CustomerSelectedEvent : CompositePresentationEvent<Customer> { }</pre> <!--CRLF--></div> </div> <p>Like the CompositeCommand, this type will need to be referenced by both sides of the communication, even though those two sides need to be decoupled from each other. So this is another one of those types you will want to declare in a shared library that any modules in the solution can reference.</p> <h3>Step 10: Hook up the subscriber</h3> <p>To hook up a subscriber, the subscribing code first needs access to the EventAggregator service in Prism. This is a singleton service like the RegionManager that you can simply obtain by using dependency injection and importing it through the container. Add the following code to the OrdersViewModel:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> OrdersViewModel()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">if</span> (!DesignerProperties.IsInDesignTool)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> {</pre> <!--CRLF--> <pre class="alt"><span id="lnum5" class="lnum"> 5:</span> CompositionInitializer.SatisfyImports(<span class="kwrd">this</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> EventAggregator.GetEvent<CustomerSelectedEvent>().Subscribe(OnCustomerSelected);</pre> <!--CRLF--> <pre class="alt"><span id="lnum7" class="lnum"> 7:</span> _Context = <span class="kwrd">new</span> CustomersDomainContext();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> }</pre> <!--CRLF--> <pre class="alt"><span id="lnum9" class="lnum"> 9:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span>  </pre> <!--CRLF--> <pre class="alt"><span id="lnum11" class="lnum"> 11:</span> [Import]</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> <span class="kwrd">public</span> IEventAggregator EventAggregator { get; set; }</pre> <!--CRLF--></div> </div> <p>Because the view model will be constructed in the XAML of the view, the container will not be involved in its construction. To get the container to satisfy the imports in the class, which in this case includes the event aggregator, the CompositionInitializer class can be used. It is put in a guard condition as discussed in a previous article so that the designer does not break since it should not execute that code in the designer.</p> <p>After the SatisfyImports call, the Import property will be set by the container. So the next line of code can then use that IEventAggregator reference to subscribe. That involves calling the GetEvent<T>() method to get a reference to the event, then calling subscribe on the returned event, which can be done in a single line of code as shown. The Subscribe method just takes an Action<T> delegate, where T is the payload type defined by the event class. The OnCustomerSelected method was shown earlier. </p> <p>By default, Prism events maintain weak references to the subscribing class method. That means that if all other references to the object go away, the event reference will not keep it alive. This solves a lot of memory leak issues where you either forget or it is difficult to know where in the code to do the Unsubscribe call. If you want the event subscription to keep the object alive, there is an overload to the Subscribe method with a keepSubscriberReferenceAlive bool parameter.</p> <p>Additionally, by default the event publication will happen synchronously using the publisher’s thread. If you want control over what thread is used to call the target method pointed to by the Subscribe call, you can use another overload that takes a ThreadOption with three choices: use the Publisher’s thread (the default), use the UI thread, or use a background thread from the thread pool.</p> <p>Finally, there is an overload that also allows you to pass a Predicate<T> delegate for filtering purposes. This allows you to pass a lambda expression or point to a method that returns a boolean. The method or lambda will be passed the payload object of the event. It can use that to decide whether to return true or false. True means to call the subscription method, false means don’t.</p> <h3>Step 11: Publish the event</h3> <p>To publish a Prism event, it is just as simple as subscribing. you first need a reference to the EventAggregator service, which you get through dependency injection as shown earlier. Then you publish at the appropriate point in your code calling the Publish method on the event returned from the same GetEvent<T>() method shown earlier:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alt"><span id="lnum1" class="lnum"> 1:</span> EventAggregator.GetEvent<CustomerSelectedEvent>().Publish(_SelectedCustomer);</pre> <!--CRLF--></div> </div> <h3>Summary</h3> <p>In this article, you saw how to define multiple modules that can communicate with each other through a combination of CompositeCommands and Prism events. CompositeCommands let you have handlers registered or unregistered in a loosely coupled fashion, and allows you to have multiple handlers (child commands) that will be used by the CompositeCommand. Prism events are for situations that are not necessarily an action->reaction kind of set up where enablement and disablement is needed. You simply define the event type with its strongly typed payload and then subscribe or publish by obtaining the event reference through the EventAggregator. Both of these mechanisms give you a really powerful combination for having loosely coupled communications between composite parts of your application.</p> <p>You can <a href="http://www.silverlightshow.net/Storage/Sources/Prism4CompositeCommandAndEventsSample.zip">download the finished code from this article here</a>.</p> <h3>About the Author</h3> <p>Brian Noyes is Chief Architect of <a href="http://www.idesign.net/" target="_blank">IDesign</a>, a Microsoft Regional Director, and Silverlight MVP. He is a frequent top rated speaker at conferences worldwide including Microsoft TechEd, DevConnections, VSLive!, DevTeach, and others. Brian worked directly on the Prism team with Microsoft patterns and practices and co-authored the book Developers Guide to Microsoft Prism 4. He is also the author of Developing Applications with Windows Workflow Foundation, Smart Client Deployment with ClickOnce, and Data Binding in Windows Forms 2.0. Brian got started programming as a hobby while flying F-14 Tomcats in the U.S. Navy, later turning his passion for code into his current career. You can contact Brian through his blog at <a href="http://briannoyes.net/">http://briannoyes.net/</a> or on Twitter @briannoyes.</p> http://www.silverlightshow.net/items/Working-with-Prism-4-Part-3-Composite-Command-and-Pub-Sub-Events.aspx editorial@silverlightshow.net (Brian Noyes ) http://www.silverlightshow.net/items/Working-with-Prism-4-Part-3-Composite-Command-and-Pub-Sub-Events.aspx#comments http://www.silverlightshow.net/items/Working-with-Prism-4-Part-3-Composite-Command-and-Pub-Sub-Events.aspx Tue, 24 Jan 2012 10:10:00 GMT Windows 8 XAML Metro Apps with OData - Part 2 <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData-Part-2.aspx" data-font="segoe ui" data-layout="button_count"></div> </td> <td><a href="https://twitter.com/share" class="twitter-share-button" data-via="silverlightshow" data-counturl="http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData-Part-2.aspx" data-count="horizontal" data-text="Reading the article 'Win8 XAML Metro Apps with OData - Part 2' by @samidip" data-url="http://slshow.net/vbeH7T">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData-Part-2.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p>So, you have heard the buzz about the brave new world of <em>Windows 8</em> from MSFT’s <em>BUILD</em> Conference! </p> <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; margin-right: 5px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/video/Recording-of-Webinar-Introduction-to-XAML-Development-on-Windows-8-by-Gill-Cleeren.aspx">Webinar recording: Introduction to XAML Development on Windows 8</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Producing-and-Consuming-OData-in-a-Silverlight-and-Windows-Phone-7-application.aspx">Article series: Producing and Consuming OData in a Silverlight and WP7 application</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/odata_cloud.aspx">Samisip's Ebook 'OData & Cloud Augmentation of Windows Phone Apps':</a> </li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/odata_cloud.aspx"><img style="width: 107px; height: 150px;" alt="Producing and Consuming OData in a Silverlight and WP7 App Ebook" src="http://www.silverlightshow.net/Storage/Ebooks/odata_cloud.png" /></a></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> May be you even attended the wonderful SilverlightShow webinar about “<a href="http://www.silverlightshow.net/video/Recording-of-Webinar-Introduction-to-XAML-Development-on-Windows-8-by-Gill-Cleeren.aspx" target="_blank">Getting Started with XAML Development in Windows 8</a>” by <a href="https://twitter.com/#!/gillcleeren" target="_blank">Gill Cleeren</a>. Ready to get your hands muddy? In this short 2-part article series, we talk about how to get started towards writing data-driven (specifically OData) Windows 8 Metro apps with XAML & C#. Here’s what we’ll cover: <ul> <li><strong></strong><a href="http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData.aspx" target="_self"><strong>Part 1</strong> – Handling of OData from our XAML Metro App [Consumption & Updates to OData source]</a></li> <li><strong>Part 2 – How to make your XAML App a well-behaved Windows 8 citizen [Artwork, Snapped Views, Contracts, Application Bar etc]</strong></li> </ul> <p> As always, the demo solution, along with all code samples is available for download through the link below:<br />  </p> <h4><a href="http://www.silverlightshow.net/Storage/Sources/TeamMetro.zip" target="_self">Download Source Code</a></h4> <h2> </h2> <h2>Introduction</h2> <p>At the BUILD Conference in August 2011, Microsoft launched Windows 8 .. the next iteration of Windows. It isn’t a forked world between desktop & mobile/tablet Operating Systems; rather “One OS to rule them all..” which runs on variety of form factors with touch-based interaction being a first-class citizen. We could obviously talk a lot about Windows 8; but for the sake of the length of this post, let me refer you to 2 valuable resources:</p> <ol> <li><em>BUILD</em> Website @ <a title="http://www.buildwindows.com/" href="http://www.buildwindows.com/">http://www.buildwindows.com/</a>. Great place to start would be the 5 Keynotes, followed by tons of recorded Session content. </li> <li><em>Windows 8 Developer Home</em> @ <a title="http://msdn.microsoft.com/en-us/windows/home" href="http://msdn.microsoft.com/en-us/windows/home">http://msdn.microsoft.com/en-us/windows/home</a>. On this site is a link to download the Windows 8 Developer Preview – the latest Windows 8 bits along with Development tools. Also, as you get into serious Windows 8 Metro development, the <a href="http://code.msdn.microsoft.com/windowsapps/" target="_blank">samples</a> from Microsoft & contributions from our fabulous community should be very valuable. </li> </ol> <p>In <a href="http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData.aspx">Part 1 of this article series</a>, we talked about how to get started with building a Windows 8 Metro App with XAML/C# and how to consume OData in our application. While we might have a functional data-driven application, we developers should strive to make our native applications feel at home in the target operating system. Windows 8 is Windows re-imagined with Metro UI, and as such, introduces some new paradigms that most Metro applications should adhere by. In this post, we talk about how to ensure our application does not produce a jarring UX for the Windows 8 user; in essence, how to make our application a well-behaved citizen in Window 8.</p> <h2>Prerequisites</h2> <p>To follow along or to try the Demo or build something similar yourself, you need the following:</p> <ol> <li>Windows 8 Developer Preview running “on the metal” on some laptop/tablet. </li> <li>Alternatively, you could also run Windows 8 in a VM (VirtualBox being the best fit at this time) or off a VHD. </li> <li>Visual Studio 11 included as a part of Windows 8 Developer Preview. At this point, the templates to build Metro Apps aren’t available outside the Windows 8 bits. </li> <li>Curiosity </li> </ol> <h2></h2> <h2> </h2> <h2>The Application Bar</h2> <p>Remember our UI to show/manipulate our list of Team members? Here it is again:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/_TeamList%20%20with%20App%20Bar_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="TeamList with App Bar" alt="TeamList with App Bar" src="http://www.silverlightshow.net/Storage/Users/samidip/_TeamList%20%20with%20App%20Bar_thumb.png" width="644" height="364" /></a></p> <p>You’ll notice that the main UI has been kept clean with minimal controls. You can obviously add much much more to utilize the real estate; but the point is, commonly used actions should be tucked away in what’s called the <em>Application Bar</em> at the bottom & also at the top. If you have a touch-enabled tablet or PC, you could get to the Application Bars in any Metro App by swiping a little from the top or bottom of the screen. If using Windows 8 in a traditional mouse/keyboard computer, we need to right-click in the App to bring up the Application Bars. </p> <p>Please note that these Application Bars are optional – you can add an Application Bar at the bottom, top, both or none, as per your App’s needs. Commonly used App functionality tucked away in Application Bars like this just makes your App sit well with the rest of the Windows 8 OS & utilizes the UX the end-users are already used to.</p> <p>Quick Trivia – Why do you think the Application Bar buttons are at either end & not at the center ?? The answer lies is some detailed research Microsoft conducted to figure out what portion of the tablet form-factor’s screen is most accessible with thumbs when holding the tablet in both hands. See the point now? <img style="border-style: none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/__wlEmoticon-smile_2.png" /></p> <p>So, let’s take a look at what we had to do to build our Application Bar. The round Metro-looking icons are nothing but regular buttons with click-handlers behind them. Here’s how we add the Application Bars to our <em>MainPage.xaml</em> UI:</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <div style="padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; text-align: left;" id="codeSnippet"> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <UserControl x:Class=<span style="color: #006080;">"TeamMetro.MainPage"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> xmlns=<span style="color: #006080;">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> xmlns:x=<span style="color: #006080;">"http://schemas.microsoft.com/winfx/2006/xaml"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> xmlns:d=<span style="color: #006080;">"http://schemas.microsoft.com/expression/blend/2008"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> xmlns:mc=<span style="color: #006080;">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> mc:Ignorable=<span style="color: #006080;">"d"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> d:DesignHeight=<span style="color: #006080;">"768"</span> d:DesignWidth=<span style="color: #006080;">"1366"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> <!--Content--></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> <Grid x:Name=<span style="color: #006080;">"LayoutRoot"</span> Background=<span style="color: #006080;">"Chocolate"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> <span style="color: #008000;">// All the other content stuff ..</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span> <!--Application Bar--></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum15" style="color: #606060;"> 15:</span> <ApplicationBar x:Name=<span style="color: #006080;">"BottomAppBar"</span> VerticalAlignment=<span style="color: #006080;">"Bottom"</span> Height=<span style="color: #006080;">"100"</span> Opacity=<span style="color: #006080;">".8"</span> IsPersistent=<span style="color: #006080;">"False"</span> DismissMode=<span style="color: #006080;">"LightDismiss"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum16" style="color: #606060;"> 16:</span> <Grid></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum17" style="color: #606060;"> 17:</span> <Grid.ColumnDefinitions></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum18" style="color: #606060;"> 18:</span> <ColumnDefinition Width=<span style="color: #006080;">"*"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum19" style="color: #606060;"> 19:</span> <ColumnDefinition Width=<span style="color: #006080;">"Auto"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum20" style="color: #606060;"> 20:</span> </Grid.ColumnDefinitions></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum21" style="color: #606060;"> 21:</span> <StackPanel Grid.Column=<span style="color: #006080;">"0"</span> Orientation=<span style="color: #006080;">"Horizontal"</span> HorizontalAlignment=<span style="color: #006080;">"Left"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum22" style="color: #606060;"> 22:</span> <Button Content=<span style="color: #006080;">"Edit"</span> Style=<span style="color: #006080;">"{StaticResource EditButtonStyle}"</span> Click=<span style="color: #006080;">"EditButton_Click"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum23" style="color: #606060;"> 23:</span> <Button Content=<span style="color: #006080;">"Delete"</span> Style=<span style="color: #006080;">"{StaticResource DeleteButtonStyle}"</span> Click=<span style="color: #006080;">"DeleteButton_Click"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum24" style="color: #606060;"> 24:</span> </StackPanel></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum25" style="color: #606060;"> 25:</span> <StackPanel Grid.Column=<span style="color: #006080;">"1"</span> Orientation=<span style="color: #006080;">"Horizontal"</span> HorizontalAlignment=<span style="color: #006080;">"Right"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum26" style="color: #606060;"> 26:</span> <Button Content=<span style="color: #006080;">"Add"</span> Style=<span style="color: #006080;">"{StaticResource AddButtonStyle}"</span> Click=<span style="color: #006080;">"AddButton_Click"</span> /></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum27" style="color: #606060;"> 27:</span> <Button Content=<span style="color: #006080;">"Refresh"</span> Style=<span style="color: #006080;">"{StaticResource RefreshButtonStyle}"</span> /></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum28" style="color: #606060;"> 28:</span> </StackPanel></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum29" style="color: #606060;"> 29:</span> </Grid></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum30" style="color: #606060;"> 30:</span> </ApplicationBar></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum31" style="color: #606060;"> 31:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum32" style="color: #606060;"> 32:</span> <ApplicationBar x:Name=<span style="color: #006080;">"TopAppBar"</span> VerticalAlignment=<span style="color: #006080;">"Top"</span> Height=<span style="color: #006080;">"100"</span> Opacity=<span style="color: #006080;">".8"</span> IsPersistent=<span style="color: #006080;">"False"</span> DismissMode=<span style="color: #006080;">"LightDismiss"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum33" style="color: #606060;"> 33:</span> <StackPanel Margin=<span style="color: #006080;">"20,0,0,0"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum34" style="color: #606060;"> 34:</span> <TextBlock x:Name=<span style="color: #006080;">"topBarText"</span> Text=<span style="color: #006080;">"You can add stuff here as well .."</span> FontSize=<span style="color: #006080;">"26"</span> /></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum35" style="color: #606060;"> 35:</span> </StackPanel></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum36" style="color: #606060;"> 36:</span> </ApplicationBar></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum37" style="color: #606060;"> 37:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum38" style="color: #606060;"> 38:</span> </Grid> </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum39" style="color: #606060;"> 39:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum40" style="color: #606060;"> 40:</span> </UserControl></pre> <!--CRLF--></div> </div> <p>And here’s the button template defined in our <em>App.xaml</em> as a global resource. You could obviously have one template for all buttons and include any other styles you want re-used. If you overlook the story-board, each Application Bar is essentially an image icon inside an ellipse. Makes sense?</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <div style="padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; text-align: left;" id="codeSnippet"> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <Application xmlns=<span style="color: #006080;">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> xmlns:x=<span style="color: #006080;">"http://schemas.microsoft.com/winfx/2006/xaml"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> x:Class=<span style="color: #006080;">"TeamMetro.App"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <Application.Resources></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> <ResourceDictionary></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> <Style x:Key=<span style="color: #006080;">"EditButtonStyle"</span> TargetType=<span style="color: #006080;">"Button"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> <Setter Property=<span style="color: #006080;">"Background"</span> Value=<span style="color: #006080;">"Transparent"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> <Setter Property=<span style="color: #006080;">"Foreground"</span> Value=<span style="color: #006080;">"White"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> <Setter Property=<span style="color: #006080;">"BorderBrush"</span> Value=<span style="color: #006080;">"Transparent"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> <Setter Property=<span style="color: #006080;">"FontFamily"</span> Value=<span style="color: #006080;">"Segoe UI"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span> <Setter Property=<span style="color: #006080;">"FontSize"</span> Value=<span style="color: #006080;">"9"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum15" style="color: #606060;"> 15:</span> <Setter Property=<span style="color: #006080;">"Template"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum16" style="color: #606060;"> 16:</span> <Setter.Value></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum17" style="color: #606060;"> 17:</span> <ControlTemplate TargetType=<span style="color: #006080;">"Button"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum18" style="color: #606060;"> 18:</span> <Grid></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum19" style="color: #606060;"> 19:</span> <VisualStateManager.VisualStateGroups></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum20" style="color: #606060;"> 20:</span> <VisualStateGroup x:Name=<span style="color: #006080;">"CommonStates"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum21" style="color: #606060;"> 21:</span> <VisualState x:Name=<span style="color: #006080;">"Normal"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum22" style="color: #606060;"> 22:</span> <VisualState x:Name=<span style="color: #006080;">"MouseOver"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum23" style="color: #606060;"> 23:</span> <VisualState x:Name=<span style="color: #006080;">"Pressed"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum24" style="color: #606060;"> 24:</span> <Storyboard></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum25" style="color: #606060;"> 25:</span> <ColorAnimation Duration=<span style="color: #006080;">"0"</span> To=<span style="color: #006080;">"White"</span> Storyboard.TargetProperty=<span style="color: #006080;">"(Ellipse.Fill).(SolidColorBrush.Color)"</span> Storyboard.TargetName=<span style="color: #006080;">"ButtonEllipse"</span> /></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum26" style="color: #606060;"> 26:</span> <ColorAnimation Duration=<span style="color: #006080;">"0"</span> To=<span style="color: #006080;">"Black"</span> Storyboard.TargetProperty=<span style="color: #006080;">"(TextBlock.Foreground).(SolidColorBrush.Color)"</span> Storyboard.TargetName=<span style="color: #006080;">"Glyph"</span> /></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum27" style="color: #606060;"> 27:</span> </Storyboard></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum28" style="color: #606060;"> 28:</span> </VisualState></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum29" style="color: #606060;"> 29:</span> </VisualStateGroup></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum30" style="color: #606060;"> 30:</span> </VisualStateManager.VisualStateGroups></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum31" style="color: #606060;"> 31:</span> <StackPanel Orientation=<span style="color: #006080;">"Vertical"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum32" style="color: #606060;"> 32:</span> <Grid Margin=<span style="color: #006080;">"0,14,0,5"</span> ></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum33" style="color: #606060;"> 33:</span> <Ellipse x:Name=<span style="color: #006080;">"ButtonEllipse"</span> Height=<span style="color: #006080;">"40"</span> Width=<span style="color: #006080;">"40"</span> Fill=<span style="color: #006080;">"Transparent"</span> HorizontalAlignment=<span style="color: #006080;">"Center"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum34" style="color: #606060;"> 34:</span> Stroke=<span style="color: #006080;">"White"</span> StrokeThickness=<span style="color: #006080;">"2"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum35" style="color: #606060;"> 35:</span> <Image Source=<span style="color: #006080;">"/Images/appbar.edit.png"</span> HorizontalAlignment=<span style="color: #006080;">"Center"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum36" style="color: #606060;"> 36:</span> </Grid></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum37" style="color: #606060;"> 37:</span> <TextBlock Text=<span style="color: #006080;">"{TemplateBinding Content}"</span> HorizontalAlignment=<span style="color: #006080;">"Center"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum38" style="color: #606060;"> 38:</span> FontFamily=<span style="color: #006080;">"Segoe UI"</span> FontSize=<span style="color: #006080;">"12"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum39" style="color: #606060;"> 39:</span> </StackPanel></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum40" style="color: #606060;"> 40:</span> </Grid></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum41" style="color: #606060;"> 41:</span> </ControlTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum42" style="color: #606060;"> 42:</span> </Setter.Value></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum43" style="color: #606060;"> 43:</span> </Setter></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum44" style="color: #606060;"> 44:</span> </Style></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum45" style="color: #606060;"> 45:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum46" style="color: #606060;"> 46:</span> </ResourceDictionary></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum47" style="color: #606060;"> 47:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum48" style="color: #606060;"> 48:</span> </Application.Resources></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum49" style="color: #606060;"> 49:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum50" style="color: #606060;"> 50:</span> </Application></pre> <!--CRLF--></div> </div> <h2> </h2> <h2>UI Modes</h2> <p>Windows 8, being a hybrid OS supporting multiple form factors, will have enough hardware horsepower to support true multi-tasking even in Metro UI mode.. And the additional real estate offered by tablets form factors means that people should be allowed to run multiple applications side by side. Yes, you can do that, unlike the competition <img style="border-style: none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/__wlEmoticon-smile_2.png" /></p> <p>So, if are running Windows 8, try a few Metro Apps one after another .. and then swipe from left or hover mouse-cursor on left edge. What you should see pop-out is the last running application, which you can drag out onto the viewable area & also dock it. Accordingly, all Windows 8 Metro applications support three UI modes:</p> <ul> <li><strong>FullScreen</strong> – This is when the App has the full center-stage & nothing else is in the foreground. </li> <li><strong>Filled</strong> – This happens when a Metro App consumes about 75% of the screen real-estate and another App has been snapped to one side. </li> <li><strong>Snapped</strong> – This is the mode where the App in question is actually the one that has been snapped and has about 25% of screen real estate. </li> </ul> <p>It is important to note that supporting these modes is very highly recommended for Metro Apps, lest you do not care about the UX when users snap your App. So, we have seen how our Demo application looks in full-screen mode; here’s how it would be if another application was snapped to the side:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Filled_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Filled" alt="Filled" src="http://www.silverlightshow.net/Storage/Users/samidip/Filled_thumb.png" width="644" height="364" /></a></p> <p>And here’s how our App would look if snapped:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Snapped_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Snapped" alt="Snapped" src="http://www.silverlightshow.net/Storage/Users/samidip/Snapped_thumb.png" width="644" height="364" /></a></p> <p>So, let’s see what one has to do to support this snapping behavior. First up, in our application, we need to notified as when these layout changes happen so we can take appropriate action. So, let’s subscribe, as below:</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <div style="padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; text-align: left;" id="codeSnippet"> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #cc6633;">#region</span> <span style="color: #006080;">"Constructor"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #0000ff;">public</span> MainPage()</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> InitializeComponent();</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> <span style="color: #008000;">// Subscribe to Layout changes.</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> ApplicationLayout.GetForCurrentView().LayoutChanged += <span style="color: #0000ff;">new</span> TypedEventHandler<ApplicationLayout,ApplicationLayoutChangedEventArgs>(MainPage_LayoutChanged);</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> <span style="color: #008000;">// Other stuff.</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> <span style="color: #cc6633;">#endregion</span></pre> <!--CRLF--></div> </div> <p>Did you notice the <em>ApplicationLayout</em> object? Yeah, we subtly tap into a WinRT namespace called using <em>Windows.UI.ViewManagement</em> and trust the OS to inform us about layout changes in current view.</p> <p>And here’s how we respond to the change in Layout:</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <div style="padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; text-align: left;" id="codeSnippet"> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> MainPage_LayoutChanged(ApplicationLayout sender, ApplicationLayoutChangedEventArgs args)</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #0000ff;">if</span> (args.Layout == ApplicationLayoutState.Filled || args.Layout == ApplicationLayoutState.FullScreen)</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: #0000ff;">this</span>.fullMode.Visibility = Windows.UI.Xaml.Visibility.Visible;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> <span style="color: #0000ff;">this</span>.snappedMode.Visibility = Windows.UI.Xaml.Visibility.Collapsed;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> <span style="color: #0000ff;">this</span>.BottomAppBar.Visibility = Windows.UI.Xaml.Visibility.Visible;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> <span style="color: #0000ff;">this</span>.topBarText.Text = <span style="color: #006080;">"You can add stuff here as well .."</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (args.Layout == ApplicationLayoutState.Snapped)</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> <span style="color: #0000ff;">this</span>.fullMode.Visibility = Windows.UI.Xaml.Visibility.Collapsed;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span> <span style="color: #0000ff;">this</span>.snappedMode.Visibility = Windows.UI.Xaml.Visibility.Visible;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum15" style="color: #606060;"> 15:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum16" style="color: #606060;"> 16:</span> <span style="color: #0000ff;">this</span>.BottomAppBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum17" style="color: #606060;"> 17:</span> <span style="color: #0000ff;">this</span>.topBarText.Text = <span style="color: #006080;">"Snapped Mode:"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum18" style="color: #606060;"> 18:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum19" style="color: #606060;"> 19:</span> }</pre> <!--CRLF--></div> </div> <p>A few things happened .. so let’s dig in. For my demo application, I am not really limited in real estate in Filled mode .. so I treat that the same as in FullScreen mode. If however the App is snapped, we swap out controls for a more streamlined look. I chose to bind my results to 2 different ListBoxes in the UI that I toggle based on layout .. if you can have one Listbox & adjust through DataTemplates, that is totally desirable. So, here are my UI elements:</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <div style="padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; text-align: left;" id="codeSnippet"> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <StackPanel Background=<span style="color: #006080;">"Transparent"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span> x:Name=<span style="color: #006080;">"fullMode"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> <ListBox Name=<span style="color: #006080;">"fullTeamList"</span> Margin=<span style="color: #006080;">"40"</span> ItemsSource=<span style="color: #006080;">"{Binding WCFTeam}"</span> Foreground=<span style="color: #006080;">"Blue"</span> Background=<span style="color: #006080;">"Transparent"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <ListBox.ItemTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> <DataTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <StackPanel Margin=<span style="color: #006080;">"400,0,0,40"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span> Orientation=<span style="color: #006080;">"Horizontal"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> <Image Source=<span style="color: #006080;">"ninja.png"</span> Height=<span style="color: #006080;">"75"</span> Width=<span style="color: #006080;">"75"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> <TextBlock Text=<span style="color: #006080;">"{Binding Name}"</span> Margin=<span style="color: #006080;">"10,0,0,0"</span> FontSize=<span style="color: #006080;">"26"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> <TextBlock Text=<span style="color: #006080;">" -- aka "</span> FontSize=<span style="color: #006080;">"22"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> <TextBlock Text=<span style="color: #006080;">"{Binding TwitterHandle}"</span> Margin=<span style="color: #006080;">"10,0,0,0"</span> FontSize=<span style="color: #006080;">"22"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> </StackPanel></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> </DataTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> </ListBox.ItemTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> </ListBox></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span> </StackPanel></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum15" style="color: #606060;"> 15:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum16" style="color: #606060;"> 16:</span> <StackPanel Background=<span style="color: #006080;">"Transparent"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span> Width=<span style="color: #006080;">"320"</span> x:Name=<span style="color: #006080;">"snappedMode"</span> Visibility=<span style="color: #006080;">"Collapsed"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum17" style="color: #606060;"> 17:</span> <ListBox Name=<span style="color: #006080;">"snappedTeamList"</span> Margin=<span style="color: #006080;">"5"</span> ItemsSource=<span style="color: #006080;">"{Binding WCFTeam}"</span> Foreground=<span style="color: #006080;">"Blue"</span> Background=<span style="color: #006080;">"Chocolate"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum18" style="color: #606060;"> 18:</span> <ListBox.ItemTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum19" style="color: #606060;"> 19:</span> <DataTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum20" style="color: #606060;"> 20:</span> <StackPanel Margin=<span style="color: #006080;">"10,0,0,40"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span> Orientation=<span style="color: #006080;">"Horizontal"</span>> </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum21" style="color: #606060;"> 21:</span> <TextBlock Text=<span style="color: #006080;">"{Binding Name}"</span> Margin=<span style="color: #006080;">"10,0,0,0"</span> FontSize=<span style="color: #006080;">"26"</span>/></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum22" style="color: #606060;"> 22:</span> </StackPanel></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum23" style="color: #606060;"> 23:</span> </DataTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum24" style="color: #606060;"> 24:</span> </ListBox.ItemTemplate></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum25" style="color: #606060;"> 25:</span> </ListBox></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum26" style="color: #606060;"> 26:</span> </StackPanel></pre> <!--CRLF--></div> </div> So, I chose to only display Team member names in Snapped mode and adjust the Application Bars accordingly. It is totally up to you & your application to decide on what information you want to display in Snapped mode .. I would guess people would go for either minimalistic views for social media type applications or dense views conveying a lot of information for sustained Snapped view usage. The point is this is totally customizable through the XAML UI .. so let’s make the most of it. <h2> </h2> <h2>Contracts</h2> <p>Windows 8 introduces this concept of <strong>Contracts</strong>, which can be thought of as System Interfaces. You may also think of them as Let-Us-Not-Reinvent-The-Wheel mechanisms. If your App needs to let the user share something through Social media, why would you write interface code to post to Twitter/Facebook when another application in the system already knows how to do that? This also results in a consistent UX and less clutter in Apps. This concept of Contracts, when expanded to most common tasks, and the powerful WinRT APIs does give the developer a lot of flexibility. While there are lots of Contracts (details found on doing MSDN searches), let’s look at a couple of contracts which should highly recommended for most Metro Apps.</p> <h4>Sharing</h4> <p>The Share contracts enforces a requester-listener pattern .. one application says “I need to share this”, while another says “I know how to do that”. The application which actually implements the Share contract need to know how to receive data from other applications through the OS and share it through whatever medium the application is built to use.</p> <p>For our demo application, we will not be actually implementing the Share contract; but do the much easier, frequently needed utilization of the Share pattern. What if we need to share some information about our Team members on social media .. can we get away with simply providing the data to share? Yes .. let’s see how.</p> <p>First, if you need your application to share some information, please please please (3 times’ the charm <img style="border-style: none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/__wlEmoticon-smile_2.png" />) do not add anything inside your App or the Application Bar to enable this. The key is consistency. You see, there are these shortcuts called <strong>Charms</strong> accessible to Windows 8 users. Set of quick access tasks accessible when touch-enabled user swipes from the right edge of screen or the mouse user hovers at the left lower corner. Here’s what the user sees:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Charms_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Charms" alt="Charms" src="http://www.silverlightshow.net/Storage/Users/samidip/Charms_thumb.png" width="644" height="364" /></a></p> <p>So, what happens when we have a selected Team member selected & which we wish to share, and then we hit the Share Charm. Well, something like this:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Share_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Share" alt="Share" src="http://www.silverlightshow.net/Storage/Users/samidip/Share_thumb.png" width="644" height="364" /></a></p> <p>What you see is the list of applications that have implemented the Share contracts .. in other words, declared to the OS that they can handle sharing of information from other Apps. Exactly, what we need! Now, let’s try <strong>TwitterRama</strong> which is a simple Twitter client for Windows 8 built by some very smart MSFT interns. This App clearly knows how to talk/post to Twitter .. so we may not need to integrate with Twitter API directly. Here’s what we get when we try to share through TwitterRama:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Sharing_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Sharing" alt="Sharing" src="http://www.silverlightshow.net/Storage/Users/samidip/Sharing_thumb.png" width="644" height="364" /></a></p> <p>Did you notice that our App passed data to TwitterRama? Let’s see how we do that .. first, let us sign up for sharing by allowing the OS interfaces to request data from our application:</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <div style="padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; text-align: left;" id="codeSnippet"> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">using</span> Windows.ApplicationModel.DataTransfer;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #cc6633;">#region</span> <span style="color: #006080;">"Constructor"</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: #0000ff;">public</span> MainPage()</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> InitializeComponent();</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> <span style="color: #008000;">// Sign up to Share.</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> var dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.GetForCurrentView();</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> dataTransferManager.DataRequested += <span style="color: #0000ff;">new</span> TypedEventHandler<DataTransferManager,DataRequestedEventArgs>(dataTransferManager_DataRequested);</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> } </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span> endregion</pre> <!--CRLF--></div> </div> <p>Next, when data is actually requested (this happens when the user hits the Share Charm), we get to respond to the event in our application and make up what data element to share. Here’s how:</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <div style="padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; text-align: left;" id="codeSnippet"> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.fullTeamList.SelectedItem != <span style="color: #0000ff;">null</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: #008000;">// Set what to share.</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> Team selectedMember = (Team)<span style="color: #0000ff;">this</span>.fullTeamList.SelectedItem;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;">string</span> textToShare = <span style="color: #006080;">"Selected Team Member: "</span> + selectedMember.TwitterHandle;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> args.Request.Data.Properties.Title = <span style="color: #006080;">"Team Member Selection"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> args.Request.Data.SetText(textToShare);</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> }</pre> <!--CRLF--></div> </div> <p>That’s it .. easy to share, right? You may learn more about the Share contract from this BUILD sessions <a href="http://channel9.msdn.com/events/BUILD/BUILD2011/APP-405T" target="_blank">HERE</a>.</p> <h4>Implementing Contracts</h4> <p>Now, how would we go about actually implementing a Contract? Simple, most common ones are available in the “Add New Item” project wizard, as shown here:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Contracts_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Contracts" alt="Contracts" src="http://www.silverlightshow.net/Storage/Users/samidip/Contracts_thumb.png" width="644" height="444" /></a></p> <p>Now, let us say our application has some interesting data/files to search on. So, if we implement the <strong>Search</strong> contract, the end user may search for our application’s data directly from Windows Search, even if our application is not running. The user gets to see our App in the list for Search & search query parameters get passed directly into our application. Here’s how:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Search_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Search" alt="Search" src="http://www.silverlightshow.net/Storage/Users/samidip/Search_thumb.png" width="644" height="364" /></a></p> <p>If our application does implement the Search contract, the App Manifest file gets updated with <strong>Declarations</strong> .. others can be added from the same screen below along with implementation:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Declarations_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Declarations" alt="Declarations" src="http://www.silverlightshow.net/Storage/Users/samidip/Declarations_thumb.png" width="644" height="364" /></a></p> <p>So, now when the user searches contextually within your application from Windows Search, your application gets to respond showing a custom Search results view. The basics of this are added as a <em>SearchResultsPage.xaml </em>when we add the Search contract, as displayed below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/App%20Context%20Search_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="App Context Search" alt="App Context Search" src="http://www.silverlightshow.net/Storage/Users/samidip/App%20Context%20Search_thumb.png" width="644" height="364" /></a></p> <p>And we get to respond to Search queries from the user within our view as follows:</p> <div style="border: 1px solid silver; padding: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; text-align: left;" id="codeSnippetWrapper"> <div style="padding: 0px; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; text-align: left;" id="codeSnippet"> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">sealed</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span> SearchResultsPage</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #0000ff;">public</span> SearchResultsPage()</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> InitializeComponent();</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Activate(SearchActivatedEventArgs args)</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> var queryText = args.QueryText;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> <span style="color: #008000;">// Application-specific searching logic.</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> <span style="color: #008000;">// Bind Search results to UI.</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum15" style="color: #606060;"> 15:</span> <span style="color: #008000;">// Display the results</span></pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum16" style="color: #606060;"> 16:</span> <span style="color: #0000ff;">this</span>.PreviousContent = Window.Current.Content;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum17" style="color: #606060;"> 17:</span> Window.Current.Content = <span style="color: #0000ff;">this</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum18" style="color: #606060;"> 18:</span> Window.Current.Activate();</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum19" style="color: #606060;"> 19:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none;"><span id="lnum20" style="color: #606060;"> 20:</span> }</pre> <!--CRLF--></div> </div> <p>Much more details about the Search contract can be found in this BUILD session recording <a href="http://channel9.msdn.com/events/BUILD/BUILD2011/APP-406T" target="_blank">HERE</a>.</p> <h2>Artwork</h2> <p>Last but possibly the most important – let’s make nice looking Apps, shall we? Let’s take care of the user’s UX and they in turn, would take care of us developers, right? So, just like in Windows Phone, we developers need to put our Designer caps on, since graphics & artwork is of paramount importance.  Let us follow Metro design guidelines to make our application feel right at home in Windows 8. Here’s our demo application on start screen:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Start_2.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px; border-style: solid;" title="Start" alt="Start" src="http://www.silverlightshow.net/Storage/Users/samidip/Start_thumb.png" width="644" height="364" /></a></p> <p>Here are some things not to miss:</p> <ul> <li>Inviting App logo on Start screen </li> <li>Inviting & Contextual App logo in App Store, along with great screenshots & description </li> <li>Branded Splash screen if using one as your App launches </li> <li>Rich but minimal graphics & backgrounds in App </li> <li>Maintain consistency </li> <li>Enable Live Tiles with Push Notifications (topic for another post someday) </li> <li>Contract implementations through consistent UI to keep inviting your users back into the App </li> <li>Metro, Metro, Metro <img style="border-style: none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/__wlEmoticon-smile_2.png" /> </li> </ul> <p>Still waiting .. c’mon let’s get started! Let’s play a part in Windows re-imagined.</p> <h2>Summary</h2> <p>In this 2 part article, we talked about how to get started with Windows 8 Metro Apps with XAML/C# and we went on to consumption/updates of OData from a Windows 8 Metro application. In Part 1, we looked at a few techniques on how to do asynchronous programming in Windows 8 using the new C# 5.0 constructs of Async-Await. In Part 2, we talked about taking the first steps towards making your Metro Apps feel at home in the Windows 8 Operating System.</p> <p>I would appreciate any comments or concerns or how things could be done better. Thanks for reading & happy coding.</p> <p>Cheers <em>SilverlightShow</em>!</p> <h2></h2> <h2></h2> <h2>About the Author</h2> <p><img style="background-image: none; margin: 0px 15px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; float: left; border-width: 0px; border-style: solid;" title="ActualPic_thumb1" alt="ActualPic_thumb1" src="http://www.silverlightshow.net/Storage/Users/samidip/ActualPic_thumb1_3.jpg" width="104" height="126" />Samidip Basu (<a href="http://twitter.com/#!/samidip">@samidip</a>) is a technologist & gadget-lover working as a Manager & Solutions Lead for Sogeti out of the Columbus Unit. Having worked on WP7 since CTP days, he now spends much of his time in spreading the word to discover the full potential of the Windows Phone platform & cloud-based mobile solutions in general. He passionately runs the Central Ohio Windows Phone User Group (<a href="http://cowpug.org/">http://cowpug.org/</a>), labors in M3 Conf (<a href="http://m3conf.com/">http://m3conf.com/</a>/) organization and can be found with at-least a couple of hobbyist projects at any time. His spare times call for travel and culinary adventures with the wife. Find out more at <a href="http://samidipbasu.com/">http://samidipbasu.com/</a><a href="http://samidipbasu.com/">.</a></p> http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData-Part-2.aspx editorial@silverlightshow.net (Samidip Basu ) http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData-Part-2.aspx#comments http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData-Part-2.aspx Thu, 08 Dec 2011 10:57:00 GMT Simulating rain in Silverlight Part 4 - Adding sound effects <p><a href="http://twitter.com/home?status=New+article+by+%40silverlightshow%3A+Simulating+rain+in+Silverlight+Part+4+-+Adding+sound+effects+http%3A%2F%2Fbit.ly%2FoHN4mX+%23silverlight" target="_blank"><img style="border:0px solid; margin-bottom: 10px; float: right; margin-left: 10px;" alt="Tweet This!" src="http://www.silverlightshow.net/Storage/tt-big4.png" /></a><strong><em>This article is compatible with the latest version of Silverlight.</em></strong></p> <h3>Introduction</h3> <div style="border:1px solid #dddddd;padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;"> <h3>More resources...</h3> <ul style="list-style-type: circle; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Webinars.aspx">Free SilverlightShow Webinars</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/GetStarted.aspx">Get Started with Silverlight 4</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/silverlight_exam.aspx">'Getting Ready for Microsoft Silverlight Exam 70-506' Ebook </a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/silverlight_exam.aspx"><img style="border:0px solid;" alt="Getting Ready for Microsoft Silverlight Exam 70-506: Ebook" src="http://www.silverlightshow.net/Storage/sl_exam_thumb_small.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($9.99)</span></strong></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <p>This article is part 4 of my article series, <em>Simulating rain in Silverlight</em>. After I added wind effect in the previous article, now I add some “color” in the whole scene. Besides the sound effect, I also put in some visuals to control the wind speed. You can choose between three different rates that will alter the angle of the rain drops. To better react when changing the speed I had to do some minor changes in the simulation algorithm. You are free to download and play with the code from the link below.</p> <p>It may seem very unfamiliar to you to have sound in your Silverlight application, but it, actually, is not that hard. Silverlight provides you with tools for handling sounds and videos in code and XAML. How? Just in a few seconds...</p> <p>First, here is a demo:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/lnikolov/RainEffectPart4.html">View live demo</a></p> <p>As you might see, you can choose between three different speeds that affect respectively the angle of the rain. Obviously, the stronger the wind is, the bigger the angle is. In nature, having summer rain with 40 kilometers per hour, results in approximately 10 degrees of inclination of the rain. Respectively, 60 km/h yields 30 degrees and 80 km/h – 60 degrees. Again, it depends on the intensity and rain density, but we can use this rule for orientation marks in our simulation.</p> <p>You can download the source from the following link:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/lnikolov/RainEffectPart4SoundEffects.zip">Download source code</a></p> <h3>How to add sound in your application?</h3> <p>Rain and wind simulation is not complete without any sound effects. </p> <p>The<strong> MediaElement</strong> class is the key. It allows you to play a number of audio and video formats. For a complete list of supported files, read <a href="http://msdn.microsoft.com/en-us/library/cc189080(v=vs.95).aspx">here</a>.</p> <p>The first thing you need to do is to find (or create the sounds) you are to use. There are a bundle of websites on the net offering free sound effects in any audio format. For example, check these out: <a href="http://www.partnersinrhyme.com/soundfx/Weather.shtml">http://www.partnersinrhyme.com/soundfx/Weather.shtml</a> and <a href="http://www.shockwave-sound.com/">http://www.shockwave-sound.com/</a>.</p> <p>My rain simulation uses two audio files – one for the rain and one for the wind. You need to add the files in the project and change the build action to Resource to ensure the media file gets copied in the <em>ClientBin</em> folder.</p> <p>I declare my media elements in the XAML that control the both effects:</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">MediaElement</code> <code style="color: #808080;">x:Name</code><code style="color: #000000;">=</code><code style="color: blue;">"WindSound"</code></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #808080;">Source</code><code style="color: #000000;">=</code><code style="color: blue;">"wind.mp3"</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #808080;">AutoPlay</code><code style="color: #000000;">=</code><code style="color: blue;">"False"</code><code style="color: #000000;">></</code><code style="color: #006699; font-weight: bold;">MediaElement</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 11px;"> </span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">MediaElement</code> <code style="color: #808080;">x:Name</code><code style="color: #000000;">=</code><code style="color: blue;">"RainSound"</code></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #808080;">Source</code><code style="color: #000000;">=</code><code style="color: blue;">"rain.mp3"</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #808080;">AutoPlay</code><code style="color: #000000;">=</code><code style="color: blue;">"False"</code><code style="color: #000000;">></</code><code style="color: #006699; font-weight: bold;">MediaElement</code><code style="color: #000000;">></code></span></span></div> </div> <p>I set <em>AutoPlay=”False”</em> to prevent the media element from playing as soon as the app starts. I control this on my own:</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">private</code> <code style="color: #006699; font-weight: bold;">void</code> <code style="color: #000000;">WindSound_MediaOpened(</code><code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">sender, System.Windows.RoutedEventArgs e)</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;">{</code></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.windMarker.Time = TimeSpan.FromMilliseconds(</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.NaturalDuration.TimeSpan.TotalMilliseconds - 1000);</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.Markers.Add(</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.windMarker);</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.Volume = 0.3;</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.Play();</code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;">}</code></span></div> </div> <p>To loop the audio, I use markers. Markers are marks in the audio/video that you can jump to when needed. I create a marker one second before the end of the media file and I use it to mark the end of the file and loop the media. The alternative, to handle the media ended event, is not the best choice here since the sound is getting silent and silent in the very end:</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">private</code> <code style="color: #006699; font-weight: bold;">void</code> <code style="color: #000000;">WindSound_MarkerReached(</code><code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">sender, TimelineMarkerRoutedEventArgs e)</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;">{</code></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.Stop();</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.Play();</code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;">}</code></span></div> </div> <p>To change the rain angle on the fly, I must abstract the rain in maximum rate. The improvement that I make here is in the way I initialize the rain and all it dependencies. The drop settings are constructed in the rain constructor, so is the slice and the fall distance.</p> <p>Having all this in mind, we have this method:</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">public</code> <code style="color: #006699; font-weight: bold;">void</code> <code style="color: #000000;">ChangeAngle(</code><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">angle)</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;">{</code></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">fallDistance = (</code><code style="color: #006699; font-weight: bold;">int</code><code style="color: #000000;">)((</code><code style="color: #006699; font-weight: bold;">double</code><code style="color: #000000;">)</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Height / Math.Cos(Math.PI * angle / 180));</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.FallDistance = fallDistance;</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Angle = angle;</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Slice = (</code><code style="color: #006699; font-weight: bold;">int</code><code style="color: #000000;">)(</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Height * Math.Tan(Math.PI * angle / 180));</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.sliceCoef = (</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.FallDistance * Math.Sin(Math.PI * angle / 180)) / </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Width;</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.DropSettings = </code><code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">DropSettings(0, fallDistance, Constants.ANIMATION_DURATION);</code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;">}</code></span></div> </div> <p>It changes not only the angle, but every aspect of the rain that depends on the angle.</p> <p>Now, it’s easy to change the wind speed:</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #008200;">// Speed changed handler</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">private</code> <code style="color: #006699; font-weight: bold;">void</code> <code style="color: #000000;">SpeedSelector_SelectionChanged(</code><code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">sender, SelectionChangedEventArgs e)</code></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;">{</code></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.HideArrows();</code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"> </span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">switch</code> <code style="color: #000000;">(</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.SpeedSelector.SelectedIndex)</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #000000;">{</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>        </code><span style="margin-left: 24px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">case</code> <code style="color: #000000;">0:</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>            </code><span style="margin-left: 36px !important; font-size: 11px;"><code style="color: #000000;">{   </code><code style="color: #008200;">// Light rain</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.light1.Visibility = </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.light2.Visibility = </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.light3.Visibility = System.Windows.Visibility.Visible;</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.rain.ChangeAngle(</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.lightAngle);</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.Volume = 0.3;</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">break</code><code style="color: #000000;">;</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>            </code><span style="margin-left: 36px !important; font-size: 11px;"><code style="color: #000000;">}</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>        </code><span style="margin-left: 24px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">case</code> <code style="color: #000000;">1:</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>            </code><span style="margin-left: 36px !important; font-size: 11px;"><code style="color: #000000;">{   </code><code style="color: #008200;">// Medium rain</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.medium1.Visibility = </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.medium2.Visibility = </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.medium3.Visibility = System.Windows.Visibility.Visible;</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.rain.ChangeAngle(</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.mediumAngle);</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.Volume = 0.6;</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">break</code><code style="color: #000000;">;</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>            </code><span style="margin-left: 36px !important; font-size: 11px;"><code style="color: #000000;">}</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>        </code><span style="margin-left: 24px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">case</code> <code style="color: #000000;">2:</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>            </code><span style="margin-left: 36px !important; font-size: 11px;"><code style="color: #000000;">{   </code><code style="color: #008200;">// Rough rain</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.rough1.Visibility = </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.rough2.Visibility = </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.rough3.Visibility = System.Windows.Visibility.Visible;</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.rain.ChangeAngle(</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.roughAngle);</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.WindSound.Volume = 0.9;</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>                </code><span style="margin-left: 48px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">break</code><code style="color: #000000;">;</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>            </code><span style="margin-left: 36px !important; font-size: 11px;"><code style="color: #000000;">}</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important; font-size: 11px;"><code style="color: #000000;">}</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #000000;">}</code></span></div> </div> <p>Of course, changing the wind speed affects the Volume property of the media file. That’s how you volume up or down an audio.</p> <h3>Conclusion</h3> <p>In this article I add sound effects to my rain simulation. Moreover, I build some visuals to change the wind speed. I strongly encourage you to use <strong>MediaElement</strong> when dealing with media files. It provides you with all you could need. Or solid base for all you could ever need!</p> Feel free to ask or comment! http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-4-Adding-sound-effects.aspx editorial@silverlightshow.net (Lazar Nikolov ) http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-4-Adding-sound-effects.aspx#comments http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-4-Adding-sound-effects.aspx Fri, 30 Sep 2011 19:21:00 GMT Simulating rain in Silverlight Part 3 - Adding wind effect <a href="http://twitter.com/home?status=New+article+by+%40silverlightshow%3A+Simulating+rain+in+Silverlight+part+3%3A+Adding+wind+effect+http%3A%2F%2Fbit.ly%2FoHN4mX" target="_blank"><img style="border:0px solid; margin-bottom: 10px; float: right; margin-left: 10px;" alt="Tweet This!" src="http://www.silverlightshow.net/Storage/tt-big4.png" /></a> <p><strong><em>This article is compatible with the latest version of Silverlight.</em></strong></p> <h3>Introduction</h3> <p>This is the logical continuation of my article <a href="http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-2-Optimization.aspx" target="_blank" re_target="null">"Simulating rain in Silverlight Part 2 - Optimization"</a>. </p> <div style="border:1px solid #dddddd;padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;"> <h3>More resources...</h3> <ul style="list-style-type: circle; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Webinars.aspx">Free SilverlightShow Webinars</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/GetStarted.aspx">Get Started with Silverlight 4</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/silverlight_exam.aspx">'Getting Ready for Microsoft Silverlight Exam 70-506' Ebook </a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/silverlight_exam.aspx"><img style="border:0px solid;" alt="Getting Ready for Microsoft Silverlight Exam 70-506: Ebook" src="http://www.silverlightshow.net/Storage/sl_exam_thumb_small.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($9.99)</span></strong></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <p> In this publication, I will add wind effect to the rain. And why is this wind effect the logical extension of the rain? Obviously, the nature rarely brings us the rain without a wind. Furthermore, it is not that trivial to add the wind effect... </p> <p> </p> Ок, let's take a good look at the phenomenon, just to make sure we have a solid understanding of what we're trying to simulate. Our simulation will assume the wind is constant. This way we avoid the random fluctuations of the rain drops. Why is this? Since Silverlight does not limit you, just experiment with it by yourself. Clear, we have rain drops, constant wind blowing the scene, and that is...just deal with the angle the drops are falling. <br /> <p>From this point on, I will expect you to have read my previous articles, <a href="http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight.aspx" target="_blank" re_target="null">"Simulating rain in Silverlight"</a> and <a href="http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-2-Optimization.aspx" target="_blank" re_target="null">"Simulating rain in Silverlight Part 2 - Optimization"</a> since I am going to build over them.</p> <p>Before I begin with the problem, here is a demo:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/lnikolov/RainEffectPart3Wind.html" target="_blank" re_target="null">View live demo</a> - 30 degrees angle</p> <p><a href="http://www.silverlightshow.net/Storage/Users/lnikolov/RainEffectPart3Wind.zip" target="_blank" re_target="null">Download source code</a></p> <h3>What is the problem?</h3> <p>What are we up to now? In the previous articles we have the rain with the falling straight down drops. Now we will alter the angle of the drops to simulate the wind effect. You would say “Okay, that’s easy, just change the angle in the <em>RotateTransform</em> in the algorithm and it’s over”. I wish it was that easy. </p> <p>Changing the angle in the transformation does actually resemble the wind effect, but having the scene in the Canvas, we have to slice two portions to keep the picture consistent. First, we have drops from the left of the scene that need to be hidden after reaching the scene border. And then, we have the drops from the right that need to be hidden until reached the scene border.</p> <p>And,</p> <h3>What is the solution?</h3> <p>Not that hard, actually, I promise. Just simple math...trigonometry. </p> <p>We have three types of drops in this simulation. One that falls all its way in the scene. Other that starts in the scene and falls until hits the left border of the scene. And last, the drops that start their way outside the scene and, at some moment, enter the scene until they fall.</p> <p>We don’t need to pay any special attention to the first type of drops since they just need to have their angle set. It is rather different with the rest of the drops. First, we need to calculate what the point in the scene that distinguishes the first from the second type is. I call this property <em>Slice</em>. Having the height of the scene and the angle you simply use the tangent of the angle. Based on <em>Slice</em>, I need the slice coefficient:<br />  </p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Slice = ( </code><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">)( height * Math.Tan( Math.PI * </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Angle / 180 ) );</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.sliceCoef = ( </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.FallDistance * Math.Sin( Math.PI * </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Angle / 180 ) ) / </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Width;</code></span></div> </div> <p>Having this information, it is easy to determine what type is a drop. Of course, the third type is easily distinguishable using the right border of the scene.</p> <p><span style="line-height: 115%; font-size: 11pt;"></span></p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">leftMargin = Convert.ToInt32( rand.NextDouble() * ( </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Width + </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Slice ) );</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.sceneDrops[ currentDrop ].Margin = </code><code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">Thickness( leftMargin, 0, 0, 0 );</code></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">coef = ( </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">)leftMargin / ( </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">)</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Width;</code></span></div> </div> <p>The drop is Type 1 if the coefficient is less than the slice coefficient:</p> <p><span style="line-height: 115%; font-size: 11pt;"></span></p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">if</code> <code style="color: #000000;">( coef <= </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.sliceCoef )</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 11px;">{</span></code></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">newFinalHeight = ( </code><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">)( ( leftMargin ) / ( Math.Sin( Math.PI * </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Angle / 180 ) ) );</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.sceneDrops[ currentDrop ].FallDistance = newFinalHeight;</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.sceneDrops[ currentDrop ].FallTime =</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;">TimeSpan.FromMilliseconds( Constants.ANIMATION_DURATION.TotalMilliseconds *</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;">( ( </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">)newFinalHeight / ( </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">)</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.DropSettings.FallDistance ) );</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 11px;">}</span></code></span></div> </div> <p>To calculate the new length of the fall, that is the fall height, we use trigonometry. Of course, we also must alter the duration of the fall.</p> <p>Similarly, to calculate the way of Type 3 drops, we use this code:</p> <p><span style="line-height: 115%; font-size: 11pt;"></span></p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 11px;"><code style="color: #006699; font-weight: bold;">if</code> <code style="color: #000000;">( coef >= 1 )</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 11px;">{</span></code></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">newInitialHeight = ( </code><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">)( ( </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">)( leftMargin - </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Width ) / Math.Sin( Math.PI * </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Angle / 180 ) );</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.sceneDrops[ currentDrop ].FallInitialHeight = newInitialHeight;</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.sceneDrops[ currentDrop ].FallTime =</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 11px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;">TimeSpan.FromMilliseconds( Constants.ANIMATION_DURATION.TotalMilliseconds *</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 11px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;">( ( </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">)( </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.FallDistance - newInitialHeight ) / ( </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">)</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.FallDistance ) );</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 11px;">}</span></code></span></div> </div> <p>And voila! That was the main part of it all. Wasn’t that hard, right?</p> <h3>Conclusion</h3> <p>To summarize, in this article we’ve simulated wind effect applied to the rain effect from my previous article - <a href="http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-2-Optimization.aspx" target="_blank" re_target="null">"Simulating rain in Silverlight Part 2 - Optimization"</a>. In my next article, I will add visuals to harness and change the speed of the wind through UI. I will also create sound effects for both wind and rain to “color” the scene. <span style="line-height: 115%; font-family: wingdings; font-size: 11pt;">J</span></p> <div id="-chrome-auto-translate-plugin-dialog" style="opacity: 1 !important; background-image: initial !important; background-attachment: initial !important; background-origin: initial !important; background-clip: initial !important; background-color: transparent !important; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important; position: absolute !important; top: 0px; left: 0px; overflow-x: visible !important; overflow-y: visible !important; z-index: 999999 !important; display: none; text-align: left;"> <div style="max-width: 300px !important; color: #fafafa !important; opacity: 0.8 !important; border-top-left-radius: 10px 10px !important; border-top-right-radius: 10px 10px !important; border-bottom-right-radius: 10px 10px !important; border-bottom-left-radius: 10px 10px !important; background-color: #363636 !important; font-size: 16px !important; padding-top: 8px !important; padding-right: 8px !important; padding-bottom: 8px !important; padding-left: 8px !important; overflow-x: visible !important; overflow-y: visible !important; background-image: -webkit-gradient(linear, 0% 0%, 100% 100%, from(#000000), color-stop(0.5, #363636), to(#000000)); z-index: 999999 !important; text-align: left;border-width: 0px !important;border-color: #000000 !important;"> <div class="translate"></div> <div class="additional"></div> </div> <img alt="" src="http://www.google.com/uds/css/small-logo.png" onclick="" style="position: absolute !important; z-index: -1 !important; right: 1px !important; top: -20px !important; cursor: pointer !important; border-top-left-radius: 20px 20px; border-top-right-radius: 20px 20px; border-bottom-right-radius: 20px 20px; border-bottom-left-radius: 20px 20px; background-color: rgba(200, 200, 200, 0.292969) !important; padding-top: 3px !important; padding-right: 5px !important; padding-bottom: 0px !important; padding-left: 5px !important; margin-top: 0px !important; margin-right: 0px !important; margin-bottom: 0px !important; margin-left: 0px !important;" /></div> http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-3-Adding-wind-effect.aspx editorial@silverlightshow.net (Lazar Nikolov ) http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-3-Adding-wind-effect.aspx#comments http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-3-Adding-wind-effect.aspx Wed, 28 Sep 2011 11:47:00 GMT Book Review: 101 Windows Phone 7 Apps <a href="http://twitter.com/home?status=Check+this+review+submitted+at+%40silverlightshow%3A+%22Book+Review%3A+101+Windows+Phone+7+Apps%22+http%3A%2F%2Fbit.ly%2Fo9Uhvi+%23WPdev" target="_blank"><img src="http://www.silverlightshow.net/Storage/tt-big4.png" alt="Tweet This!" style="float: right; margin-left: 10px; border-width: 0px;border-style: solid;" /></a> <p><em>This review is on the book </em><a href="http://www.silverlightshow.net/book/101-Windows-Phone-7-Apps-Volume-I-Developing-Apps-1-50.aspx" target="_self"><em>'101 Windows Phone 7 Apps: Volume I: Developing Apps 1-50'</em></a><em>, and has been submitted by a member of the </em><a href="http://wpug.net/" target="_blank"><em>Windows Phone 7 User Group</em></a><em> - a user group supported by SilverlightShow.<br /> We </em><a href="http://www.silverlightshow.net/About/Partners.aspx" target="_self"><em>support user groups</em></a><em> with books, swag, events promotion, free event passes and others. </em><a href="http://www.silverlightshow.net/About/contacts.aspx" target="_self"><em>Contact us to get support for your user group</em></a><em>. <br />  </em></p> <div style="border:1px solid #dddddd;padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Getting-ready-for-the-Windows-Phone-7-Exam-70-599-Part-1.aspx">Article series: Getting ready for Microsoft WP7 Exam 70-599</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Windows-Phone-7-Part-1-Getting-Started.aspx">WP7 article series by Andrea Boschin</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/wp7_for_silverlight_developers.aspx">Windows Phone 7 for Silverlight Devs Ebook (also in MOBI and EPUB format):</a> </li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/wp7_for_silverlight_developers.aspx"><img style="border:0px solid; width: 100px; height: 141px;" alt="Windows Phone 7 for Silverlight Developers Ebook" src="http://www.silverlightshow.net/Storage/Ebooks/wp7_silverlight_devs.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($4.99)</span></strong></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> I think 101 windows phone 7 apps is a great book. It’s a great book if you're new to programming with Silverlight or to windows phone 7. It can also serve as a great reference material for intermediate programmers and veterans alike. <p>The last time I got this excited about a book was when I got head first java, but unlike head first java, 101 windows phone 7 apps doesn't try to take you into deep technicalities of what a class is or what an object is, neither does it try to take you into the technicalities of Silverlight or c# or xaml, but rather takes you straight to the point by building simple and practical windows phone apps, teaching you the design (xaml) and programming (c#) concept of the platform as you go along, though I will add here that it might not be as easy if you are completely new to programming.</p> <p>This approach of using real life apps to teach means that by the time you get midway through the book, you would have been involved in the building of 25 fairly standard and practical apps and also would have touched on a lot of features and functionalities of the windows phone 7 platform. This would involve both the user interface design and also the code behind.</p> <p>I think there's no better way to teach sometimes than by example, and in this case we've been offered 50 great examples. The author has managed to write a book that walks you through the code line by line thereby giving you the reader greater understanding of the role of what each line does.</p> <p>For those of us who are not newbies to windows phone 7, it comes in handy as a reference material. In my case I needed to incorporate a longlistselector or jumplist in my app and found it so easy to just lookup an app in the book that does this.</p> <p>Though the size of the book might seem daunting initially, don't be scared to have a go at it since its not one massive book that goes on and on about the same thing but rather it contains isolated chapters that treat on functions and features that are enough to build a fully functional standalone app.</p> <p>I highly recommend his book for beginners, and intermediate programmers alike, and I think even the veterans might find this a great addition to the tech bookshelf.</p> http://www.silverlightshow.net/items/101-Windows-Phone-7-Apps-Volume-I-Developing-Apps-1-50-A-review.aspx editorial@silverlightshow.net (taabello ) http://www.silverlightshow.net/items/101-Windows-Phone-7-Apps-Volume-I-Developing-Apps-1-50-A-review.aspx#comments http://www.silverlightshow.net/items/101-Windows-Phone-7-Apps-Volume-I-Developing-Apps-1-50-A-review.aspx Wed, 07 Sep 2011 15:13:00 GMT WP7 for iPhone and Android Developers - MVC and MVVM <div style="border:1px solid #dddddd;border-image: initial; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Webinars.aspx">Free SilverlightShow Webinars</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Windows-Phone-7-Part-1-Getting-Started.aspx">WP7 series by Andrea Boschin</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/wp7_iphone_android.aspx">The WP7 for iOS and Android series now available as an Ebook:</a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/wp7_iphone_android.aspx%22"><img style="border-color: initial; border-color: initial; border-color: initial; width: 100px; height: 141px; border-color: initial; border-width: 0px;border-style: solid;" alt="Windows Phone 7 for Silverlight Developers Ebook" src="http://www.silverlightshow.net/Storage/Ebooks/wp7_iphone.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($2.99)</span></strong></p> <p style="font-size: 12px;">     <a href="http://www.silverlightshow.net/ebooks.aspx">All SilverlightShow Ebooks</a> <img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <p>So far in this series of articles, we have been taking topics that might be second nature to iOS developers and relating them to the relatively new feature set found in the Windows Phone 7 SDK. Typically this involves talking about a few classes and code samples as they might appear in iOS and then relating them to classes with a similar purpose in the WP7 SDK. </p> <p>This article focuses more on a set of design patterns to illustrate that patterns themselves are universal and the code used to implement them is secondary to the pattern and its purpose. In this article we’ll take a look at the Model – View – Controller pattern and a variant of it, the Model-View-ViewModel pattern.</p> <p>In a typical data-bound user interface you generally have a view composed of controls and these controls are usually bound to some underlying source of data. For example, if you have a customer edit form you might have controls like text fields for editing the customer’s name and address and other types of controls for editing additional customer data. The model in this scenario might be an object called Customer (which could be a regular Objective-C or C# object or it could have been served up by a database access library or an Object-Relational Mapper).</p> <p>If this were an iOS application you might have created a class called <strong>CustomerEditViewController</strong> which inherits from <strong>UIViewController</strong>. The view is actually a view hierarchy composed of controls that allow a user to edit customers. Because iOS doesn’t actually support bindings the way the full desktop version of Cocoa does (or WP7 for that matter) the controller has to do an awful lot of work to react to user input and manually force values into control properties. </p> <p>A typical Model-View-Controller interaction looks like the following diagram:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/KotanCode/16fig01_2.png"><img style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px;" title="16fig01" alt="16fig01" src="http://www.silverlightshow.net/Storage/Users/KotanCode/16fig01_thumb.png" width="433" height="294" /></a></p> <p>In a bindings-capable environment, the model is bound to the view and the model is loaded and updated by the controller. Additional properties of the view are dealt with by the controller and user interaction events are passed on to the controller for handling.</p> <p>This works out pretty well in many scenarios and it’s original goal of separating concerns to make our applications easier to maintain and debug is still valid. Unfortunately what happens quite often is that with the MVC pattern we only have a single model. In order to keep bindings working, we end up making changes to the model to accommodate things that only have relevance in the UI. For example, we might add an <strong>isSelected</strong> property to the <strong>Customer</strong> class so that we can modify the background color of currently selected customers or, we’ll add a <strong>CurrentCustomer</strong> object to some other model and use that to help our UI maintain navigational consistency.</p> <p>In a typical iOS scenario, we might have a <strong>UITableViewController</strong> subclass. This class is responsible for handing instances of custom view cells to the UI subsystem. It performs the customization of these cells by pulling information from a model. </p> <p>What we really need are two different types of models. The first type is a model that represents the actual source of data which will more than likely be some kind of POCO (Plain-Old C# Object) that came from a database, an XML file, a Web Service, or somewhere else. The second type of model is a model whose properties and behaviors are designed specifically to support the view with which the user interacts. This type we call a <strong>View Model</strong>, and it is part of a variant of the MVC pattern called Model-View-ViewModel.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/KotanCode/16fig03_2.png"><img style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px;" title="16fig03" alt="16fig03" src="http://www.silverlightshow.net/Storage/Users/KotanCode/16fig03_thumb.png" width="431" height="474" /></a></p> <p>In a Model-View-ViewModel pattern, we take advantage of the fact that virtually all aspects of our user interface can be controlled via data binding. We wouldn’t really need to add the complexity of this pattern to our iOS applications because we don’t have bindings support but it comes in <em>extremely</em> handy when building large Windows Phone 7 applications.</p> <p>Notice that this pattern doesn’t actually have a controller – there is no single over-arching all-powerful class that is responsible for coordinating everything. This takes a little getting used to at first, but, once you’ve gotten into the habit of building highly data-bound UIs in Windows Phone 7, the use of MVVM seems like a natural evolution.</p> <p>As mentioned, MVVM is a <em>pattern</em>, it is a way of doing things and, as such, there is no single right way of doing it. For example, one thing people strive for in MVVM is to have as little code in a view’s code-behind as possible (it’s really not possible to avoid this entirely). If you ask folks building MVVM applications today about code-behind, you will probably start an argument.</p> <p>One concept that is especially hard for iOS developers to let go of is the idea of the controller. If you find yourself writing code that looks like this:</p> <p><em>myControl.Text = myModel.Property;</em></p> <p>Then you need to stop right there – this isn’t MVVM. Your view needs to be bound to a view model and the properties of the various controls and sub-controls should all be set via bindings and converters wherever possible. The trick with MVVM is figuring out how your view needs to get instances of view models. You can do this by creating factory methods, or you can use a <em>view model locator</em>, which is a static helper class responsible for doling out instances of view models to views.</p> <p>Take a look at the following XAML, which illustrates how you might create a single customer view that is bound to a view model object:</p> <div style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin-top: 20px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow-x: auto; overflow-y: auto; cursor: text; padding-top: 4px; text-align: left;" id="codeSnippetWrapper"> <div style="padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px; text-align: left;border-style: none;" id="codeSnippet"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <phone:PhoneApplicationPage x:Class=<span style="color: #006080;">"MyApp.CustomerPage"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> ...</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> DataContext=<span style="color: #006080;">"{Binding Customer,Source={StaticResource Locator}}"</span>></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> ...</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> </phone:PhoneApplicationPage></pre> <!--CRLF--></div> </div> <p>Basically what we’re saying is that there is a <em>view model</em> object called <em>Customer</em> to which this entire page is bound. This is also a very common practice with MVVM – try and make the binding as wide in scope as possible. It might be hard at first, but try and match your view models directly to pages and user controls. The benefit of having a view model in addition to a data-centric model is that you can have multiple view models for a single model, with each view model tailored specifically for a given control or page.</p> <p>Inside our <strong>App.xaml</strong> we can declare a global resource that points to the <em>view model locator</em>:</p> <div style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin-top: 20px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow-x: auto; overflow-y: auto; cursor: text; padding-top: 4px; text-align: left;" id="codeSnippetWrapper"> <div style="padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px; text-align: left;border-style: none;" id="codeSnippet"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Application.Resources</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">vm:ViewModelLocator</span> <span style="color: #ff0000;">x:Key</span><span style="color: #0000ff;">="Locator"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Application.Resources</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>Here “vm” is the namespace prefix of the CLR namespace where we have our view model locator defined. This class really just has public properties on it that allow our XAML to obtain instances of view models. This is also unfamiliar territory for iOS developers and developers who traditionally follow a more MVC style. Instead of having a controller object that knows about the view and knows about the model that is responsible for hooking the two up, the view declares its intent via bindings. In the sample case, the view says that it should be bound to a view model called <em>Customer</em> which can be found on the view model locator class. The view model locator is responsible for <em>instantiating </em>the view model. During this instantiation, the view model also typically has an <em>initialization</em> method which is called directly or indirectly (again, this is a source of difference and debate depending on how you decide to implement your MVVM pattern).</p> <p>So the flow of control and instantiation might go something like this: <em>Customer View Page –> Locator –> Customer View Model –> Customer Model (database or web service source)</em>.</p> <p>The UI intentionally has absolutely no idea how the bound data is actually persisted on disk (or in the cloud). All it cares about is how the data is represented visually to the user and made available for interaction – this is the job of the view model. Many of the tasks we traditionally keep in controllers, such as responding to user input and manipulating model values, all take place within the view model whenever possible.</p> <p>At first you might be thinking that MVVM seems a lot more complicated than just having code-behind in your WP7 views that manipulates controls directly, especially when this looks a lot like the code you may have been writing in iOS. For really small applications, this may be true. However, once you start writing applications that have several pages and these pages have multiple controls, different states, and need to respond to when users navigate to and away from those pages and finally when you try and attach an asynchronous data source (such as web services in the cloud) to your application – the small increase in complexity of code is well worth it in the long run.</p> <p>Bindings is only a small part of MVVM, it is far more than that. Let’s take another very common scenario – navigating between pages. In iOS, you might write code in a method that is invoked when a user selects a row in a table view. Here, you might create an instance of the view controller responsible for the next screen and then <em>pop</em> it into the stack via the navigation controller. If this view controller needs a model in order to prep the UI, the parent controller is often responsible for creating an instance of this model, loading it from some source, and then passing it as a parameter to the child controller.</p> <p>With MVVM we do things a little differently. A user might tap a button which results in the <em>execution</em> of a <em>Command</em> object that is actually a property of the view model (view models encapsulate both behavior <em>and </em>data!). As a result of this execution, a message might be broadcast indicating that Customer 123 has been selected. The <em>CustomerViewModel</em> class is listening for such a message. When it receives this message, it loads Customer 123 from disk, populates all of its properties accordingly, and then tells the WP7 navigation system to navigate to the <em>CustomerView.xaml</em> page. As you can see, the “concerns” here are even more separate than in MVC – the parent controller doesn’t actually know what happens when someone selects a customer and many proponents of MVVM argue that it shouldn’t. The view model that backs the view that should appear upon selecting a customer is responsible for listening for the event (or events, and this is key to re-usability) that trigger the appearance of that view.</p> <p>It might seem like a minor detail but if you go back into an application written MVC style a few months after writing it – it could take you a very long time to figure out all of the different paths through an application. If you’re looking at an MVVM view model, then a quick glance at the message subscribers on that model will tell you exactly the list of actions that can cause that view to appear.</p> <p>In this article I’ve tried to explain the basics of the MVVM pattern and how it differs from the MVC pattern that iOS developers are familiar with. I have deliberately avoided talking about any one MVVM implementation because the decision as to which MVVM library you use (or whether you roll your own) is entirely up to you. </p> <p>MVVM isn’t limited to just Windows Phone 7, and there are implementations on just about every platform you can imagine. For Windows Phone 7, the library that I have used most often is MVVM Lite. If you don’t feel like writing your own view model locator classes, your own pub/sub messaging system, and your own command helpers, then using a library like MVVM Lite will save you a lot of time and effort.</p> <p>At one point, the installation process for MVVM Lite was so cumbersome that many people just wrote their own stuff rather than attempting the install. Recently, they have released an automated installer that makes adopting MVVM Lite much easier. You can find the code for MVVM Lite, the downloader, and related documentation here: <a href="http://mvvmlight.codeplex.com/">http://mvvmlight.codeplex.com/</a>.</p> <p>In closing, iOS developers are very used to having to manually fetch objects from a data source via a controller and then, using that same controller, instantiate custom views and set view properties and manually build view hierarchies programmatically. Using the MVVM pattern on Windows Phone 7 allows developers to take full advantage of bindings, resource dictionaries, templating, and the flexibility of Xaml-based object hierarchies. As an iOS developer if you ever find yourself writing code like this:</p> <p><em>myControl.Text = myModel.TextProperty;</em></p> <p>Then you should take a step back and see if the MVVM pattern and possibly an MVVM toolkit might help you.</p> http://www.silverlightshow.net/items/WP7-for-iPhone-and-Android-Developers-MVC-and-MVVM.aspx editorial@silverlightshow.net (Kevin Hoffman ) http://www.silverlightshow.net/items/WP7-for-iPhone-and-Android-Developers-MVC-and-MVVM.aspx#comments http://www.silverlightshow.net/items/WP7-for-iPhone-and-Android-Developers-MVC-and-MVVM.aspx Thu, 01 Sep 2011 13:41:00 GMT TIP: Transformations explained <p style="text-align: justify;">Placing elements on the page is really simple but many times the six types of shapes available in Silverlight do not suffice to satisfy all the needs. Also often, especially in junction with animations, the need of moving elements on the screen means transforming basic shapes, applying the rules of the simmetry that in Silverlight go under the name of transform. </p> <p style="text-align: justify;">Applying a trasform means setting the value of the RenderTransform property that is exposed by every class that implements UIElement. Differently from WPF in Silverlight it is possible to apply transform only during the render phase but unfortunately, the LayoutTransform is missing. This is an important limitation of Silverlight because applying the transform during the Rendering pass implies that, the transformed elements, have already been positioned during the layout pass, so this can lead to unwanted overlapping of shapes. However if you need the Layout Transform (e.g. to present a vertical text) you can rely on the LayoutTransformer that is available into the Silverlight Toolkit.</p> <div style="text-align: justify;"> <div style="text-align: left; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; padding-top: 4px;border: silver 1px solid;" id="codeSnippetWrapper"> <div style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;" id="codeSnippet"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Border</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="Red"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Border.RenderTransform</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">RotateTransform</span> <span style="color: #ff0000;">Angle</span><span style="color: #0000ff;">="40"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">Border.RenderTransform</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">In Silverlight there is 4 types of possible tranform:</p> <ul> <li> <div style="text-align: justify;"><strong>Rotation</strong>: used to rotate the element around a given point. It is implemented by the class RotateTransform that allows the user to specify an angle in degrees.</div> </li> <li> <div style="text-align: justify;"><strong>Translate</strong>: used to move an element along the x and y axis of a given amount. The TranslateTransform may seem unuseful since the Canvas layout element appear to allow the same transform but please remember that positioning using Canvas is strongly discouraged</div> </li> <li> <div style="text-align: justify;"><strong>Scale</strong>: Used to change the size of an element along the x and y axis. Interesting to know that using the ScaleTransform class you can also apply mirror effects using negative values</div> </li> <li> <div style="text-align: justify;"><strong>Skew</strong>: Used to distort a figure along its axis. SkewTransform allows to bend the shape to which it is applied</div> </li> </ul> <p style="text-align: justify;">Obviously it is absolutely possible you have the need of apply more that a transform to an element. To solve this question there are two possible ways to follow. Before the release 4.0 of Silverlight the sole way was using a TransformGroup class that is a transform that can collect multiple other transformations and make a logical sum of them. Blend 3.0 was known to creates a single TransformGroup with an instance for every type of transform also if you are applying a single type. However here is a sample: </p> <div style="text-align: justify;"> <div style="text-align: left; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; padding-top: 4px;border: silver 1px solid;" id="codeSnippetWrapper"> <div style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;" id="codeSnippet"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Border</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="Red"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Border.RenderTransform</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">TransformGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">RotateTransform</span> <span style="color: #ff0000;">Angle</span><span style="color: #0000ff;">="40"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">ScaleTransform</span> <span style="color: #ff0000;">ScaleX</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">ScaleY</span><span style="color: #0000ff;">=".5"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">TransformGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">Border.RenderTransform</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">After the release 4.0 it was added a new type of transform, called CompositeTransform, that is a single class gathering all the properties of the four original transformations. So, Blend 4.0 now creates a single instance of CompositeTransform and it tunes the various properties according with the transformations you applied. Here is how you can convert the previous sample:</p> <p style="text-align: justify;"> </p> <div style="text-align: justify;"> <div style="text-align: left; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; padding-top: 4px;border: silver 1px solid;" id="codeSnippetWrapper"> <div style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;" id="codeSnippet"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Border</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="Red"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Border.RenderTransform</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">TransformGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">CompositeTransform</span> <span style="color: #ff0000;">Rotation</span><span style="color: #0000ff;">="40"</span> <span style="color: #ff0000;">ScaleX</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">ScaleY</span><span style="color: #0000ff;">=".5"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">TransformGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">Border.RenderTransform</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">It is important, however, to note that the two samples of code, also if the properties have the same values, does not led to the same result. This is because the TransformGroup apply the transformation separated, one following the other in the order of appearance, but the CompositeTransform apply the properties in a sole passage. It is all up to you to know if your expectations are in a way or in the other.</p> <p style="text-align: justify;">Finally, especially when you are applying a RotationTransform, but really with all the other kind of transform, you may want to define the reference point from which the transformation will be applied. The best is to use the RenderTransformOrigin property that allows you to specify the point using a percentage value. The RenderTransformOrigin can contain two coordinates, expressed with a value from 0 to 1, where 0 means 0%, 0.5 means 50% and obviously 1 means 100%. Many transformations have similar properties that are instead specified with absolute coordinates and this makes them difficult to be used.</p> <div style="text-align: justify;"> <div style="text-align: left; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; padding-top: 4px;border: silver 1px solid;" id="codeSnippetWrapper"> <div style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;" id="codeSnippet"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Border</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="Red"</span> <span style="color: #ff0000;">RenderTransformOrigin</span><span style="color: #0000ff;">=".5,.5"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Border.RenderTransform</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">TransformGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">CompositeTransform</span> <span style="color: #ff0000;">Rotation</span><span style="color: #0000ff;">="40"</span> <span style="color: #ff0000;">ScaleX</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">ScaleY</span><span style="color: #0000ff;">=".5"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">TransformGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">Border.RenderTransform</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">Please remember that RenderTransformOrigin is not of type string, but when you specify it in codebehind you have to use the Point class to express the couple of cordinates.</p> http://www.silverlightshow.net/items/TIP-Transformations-explained.aspx editorial@silverlightshow.net (Andrea Boschin ) http://www.silverlightshow.net/items/TIP-Transformations-explained.aspx#comments http://www.silverlightshow.net/items/TIP-Transformations-explained.aspx Fri, 10 Jun 2011 19:26:00 GMT Simulating rain in Silverlight <p><strong><em>This article is compatible with the latest version of Silverlight.</em></strong></p> <p><strong></strong></p> <div style="border:1px solid #dddddd;padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Webinars.aspx">Free SilverlightShow Webinars</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/Getting-ready-for-the-exams-Part-1.aspx">Getting ready for Silverlight Exam 70-506 series</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/ClassifiedCabinet-A-Quick-Start.aspx">ClassifiedCabinet: A Quick Start</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/book/Pro-Business-Applications-with-Silverlight-3.aspx">Pro Business Apps with SL4 book: </a></li> </ul> <p style="padding-bottom: 5px;">        <a href="http://www.silverlightshow.net/book/Pro-Business-Applications-with-Silverlight-3.aspx"> <img alt="Pro Business Applications with Silverlight 4 book" src="http://www.silverlightshow.net/Storage/ProSL4.jpg" /></a> </p> <p style="font-size: 12px;">           <a href="http://www.silverlightshow.net/Books.aspx">Show more books</a><img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <h3><strong> <h3>Introduction</h3> </strong></h3> <p>In this article I will try to simulate rain in Silverlight application that can be programmatically configured to meet your expectations. Although Silverlight at the time being is very CPU consuming, rain effect may be a common challenge for a developer or designer.</p> <p>I believe that there are many computer graphics techniques, such as <a href="http://en.wikipedia.org/wiki/Particle_system">Particle system</a>, to simulate realistically processes that involve tiny particles interacting with each other. However, in this article I will show you how to simulate rain with almost no effort with some very simple algorithm.</p> <p>Here is a little demo and source code of what we will have done at the end in just a few minutes:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/lnikolov/RainEffectTestPage.html">View live demo</a> - with a small amount of raindrops to avoid performance issues</p> <p><a href="http://www.silverlightshow.net/Storage/Users/lnikolov/RainEffect.zip">Download source code</a></p> <p>Also check the second part of this series - <a href="http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight-Part-2-Optimization.aspx">"Simulating rain in Silverlight Part 2 - Optimization"</a>!</p> <p><strong></strong></p> <h2><strong> <h3>The idea</h3> </strong></h2> <p>Before looking at the algorithm, let me make the main flow clear. As I wrote a few lines above, the designer adjusts programmatically the rain on his own. That is – the height and width of the scene, the interval of falling drops and the amount of drops animated at a time. This all is achieved with a couple of classes that form the rain nature:</p> <ul> <li>Drop – holds the drop view </li> <li>DropSettings – describes a drop and its settings; currently only the height that the drop pours is implemented; this act as a view-model as I use it to bind in the drop view when animating the motion from top to bottom part of the scene </li> <li>Rain – this is my main object to maintain the rain process; it uses a simple algorithm, I will next describe, to simulate drops falling randomly through scene </li> </ul> <p><strong></strong></p> <h2><strong> <h3>The algorithm</h3> </strong></h2> <p>Now it’s time for the algorithm. It, actually, is really very simple one. What determines the average rain? Yes, you are right and this is what I was looking for – direction and intensity.</p> <p>First, to simulate the rain, we need to perform the algorithm exactly as many times, as we had previously defined to be the amount of drops to fall simultaneously. Furthermore, this should be done exactly as many times as we have specified to be the interval between the raindrops. </p> <p>We start with the following:</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #006699; font-weight: bold;">for</code> <code style="color: #000000;">(</code><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">i = 0; i < </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.DropsPerInterval; ++i)</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 12px;">{</span></code></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 12px;">}</span></code></span></div> </div> <p>To distinguish between UI elements in the scene, when constructing the Rain object, a canvas is specified, and this panel is where the rain will be simulated in. Every drop that we create should be a child of this panel.</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;">Drop drop = </code><code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">Drop(</code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.DropSettings);</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Scene.Children.Add(drop);</code></span></div> </div> <p>Next step is to generate the depth in which the drop is shown in the scene. Depth visually controls the scale and further you go deep in the scene, drops become smaller.</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">depth = rand.NextDouble();</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;">drop.RenderTransform = </code><code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">ScaleTransform</code></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 12px;">{</span></code></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;">ScaleX = depth,</code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;">ScaleY = depth,</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 12px;">};</span></code></span></div> </div> <p>The direction of the rain affects directly on the angle which drops fall the ground in. In the demo this angle is fixed to be between 0 and 10 degrees clockwise rotation.</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">angle = rand.NextDouble() * 10;</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;">drop.LayoutRoot.RenderTransform = </code><code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">RotateTransform</code></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 12px;">{</span></code></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;">Angle = angle,</code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 12px;">};</span></code></span></div> </div> <p>So far we had spread the drops randomly in depths and directions between 0 and 10 degrees. To put the finishing touches, we need to randomly scatter the raindrops in the two dimensional perspective of the scene.</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;">drop.Margin = </code><code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">Thickness(Convert.ToInt32(rand.NextDouble() * </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Width), 0, 0, 0);</code></span></div> </div> <p>This will set gratuitously from 0 to the right most corner the gap between the drop and most left corner.</p> <p>Finally, the last thing to do is to start the animation.</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 12px;">drop.Animate();</span></code></span></div> </div> <p><strong></strong></p> <p>That's it!</p> <h3>Designing the drop</h3> <p>To design the raindrop view I use <a href="http://www.microsoft.com/expression/products/blend_overview.aspx">Expression Blend</a>. Here is the XAML for it (for clarity I have omitted the <em>Data </em>attribute):</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">Path</code> <code style="color: #808080;">Stretch</code><code style="color: #000000;">=</code><code style="color: blue;">"Fill"</code> <code style="color: #000000;">Data="...</code></span><span style="font-size: 12px;"><code style="color: #000000;">" </code><code style="color: #808080;">VerticalAlignment</code><code style="color: #000000;">=</code><code style="color: blue;">"Stretch"</code> <code style="color: #808080;">RenderTransformOrigin</code><code style="color: #000000;">=</code><code style="color: blue;">"0.5,0.5"</code></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #808080;">    Margin</code><code style="color: #000000;">=</code><code style="color: blue;">"1.222,-2.518,-4.94,-7.559"</code> <code style="color: #808080;">UseLayoutRounding</code><code style="color: #000000;">=</code><code style="color: blue;">"False"</code> <code style="color: #000000;">></code></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">Path.Fill</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">LinearGradientBrush</code> <code style="color: #808080;">EndPoint</code><code style="color: #000000;">=</code><code style="color: blue;">"1.420529961586,0.976535022258759"</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>            </code><span style="margin-left: 36px !important;"><code style="color: #808080;">StartPoint</code><code style="color: #000000;">=</code><code style="color: blue;">"0.331510990858078,0.976535022258759"</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>            </code><span style="margin-left: 36px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">LinearGradientBrush.RelativeTransform</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>                </code><span style="margin-left: 48px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">TransformGroup</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>                    </code><span style="margin-left: 60px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">SkewTransform</code> <code style="color: #808080;">AngleY</code><code style="color: #000000;">=</code><code style="color: blue;">"0"</code> <code style="color: #808080;">AngleX</code><code style="color: #000000;">=</code><code style="color: blue;">"17.4704"</code> <code style="color: #808080;">CenterY</code><code style="color: #000000;">=</code><code style="color: blue;">"0.976535"</code> <code style="color: #808080;">CenterX</code><code style="color: #000000;">=</code><code style="color: blue;">"0.331511"</code><code style="color: #000000;">/></code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>                    </code><span style="margin-left: 60px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">RotateTransform</code> <code style="color: #808080;">Angle</code><code style="color: #000000;">=</code><code style="color: blue;">"-61.3206"</code> <code style="color: #808080;">CenterY</code><code style="color: #000000;">=</code><code style="color: blue;">"0.976535"</code> <code style="color: #808080;">CenterX</code><code style="color: #000000;">=</code><code style="color: blue;">"0.331511"</code><code style="color: #000000;">/></code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>                </code><span style="margin-left: 48px !important;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">TransformGroup</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>            </code><span style="margin-left: 36px !important;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">LinearGradientBrush.RelativeTransform</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>            </code><span style="margin-left: 36px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">GradientStop</code> <code style="color: #808080;">Color</code><code style="color: #000000;">=</code><code style="color: blue;">"#FE739EAD"</code><code style="color: #000000;">/></code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>            </code><span style="margin-left: 36px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">GradientStop</code> <code style="color: #808080;">Color</code><code style="color: #000000;">=</code><code style="color: blue;">"#FFD3E9F9"</code> <code style="color: #808080;">Offset</code><code style="color: #000000;">=</code><code style="color: blue;">"1"</code><code style="color: #000000;">/></code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">LinearGradientBrush</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">Path.Fill</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">Path</code><code style="color: #000000;">></code></span></div> </div> <p>It is nothing more than a path with some gradient brush on it. This results in the following, magnified about 20 times:</p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/lnikolov/raindrop.png" /></p> <p>To simulate the drop falling I use a storyboard that:</p> <ol> <li>animates the height the drop is in each moment </li> <li>animate the visibility to collapsed when the desired height is reached, that is the drop has fallen through the whole scene </li> </ol> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">Storyboard</code> <code style="color: #808080;">x:Name</code><code style="color: #000000;">=</code><code style="color: blue;">"Pour"</code><code style="color: #000000;">></code></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">DoubleAnimationUsingKeyFrames</code> <code style="color: #808080;">BeginTime</code><code style="color: #000000;">=</code><code style="color: blue;">"00:00:00"</code> <code style="color: #808080;">Storyboard.TargetName</code><code style="color: #000000;">=</code><code style="color: blue;">"drop"</code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #808080;">Storyboard.TargetProperty</code><code style="color: #000000;">=</code><code style="color: blue;">"(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"</code><code style="color: #000000;">></code></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">SplineDoubleKeyFrame</code> <code style="color: #808080;">KeyTime</code><code style="color: #000000;">=</code><code style="color: blue;">"00:00:00"</code> <code style="color: #808080;">Value</code><code style="color: #000000;">=</code><code style="color: blue;">"0"</code><code style="color: #000000;">/></code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">SplineDoubleKeyFrame</code> <code style="color: #808080;">KeyTime</code><code style="color: #000000;">=</code><code style="color: blue;">"00:00:00.6"</code> <code style="color: #808080;">Value</code><code style="color: #000000;">=</code><code style="color: blue;">"{Binding FallHeight}"</code><code style="color: #000000;">/></code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">DoubleAnimationUsingKeyFrames</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">ObjectAnimationUsingKeyFrames</code> <code style="color: #808080;">BeginTime</code><code style="color: #000000;">=</code><code style="color: blue;">"00:00:00"</code> <code style="color: #808080;">Storyboard.TargetName</code><code style="color: #000000;">=</code><code style="color: blue;">"drop"</code></span></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #808080;">Storyboard.TargetProperty</code><code style="color: #000000;">=</code><code style="color: blue;">"(UIElement.Visibility)"</code><code style="color: #000000;">></code></span></div> <div style="background-color: #ffffff;"><span style="font-size: 12px;"><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">DiscreteObjectKeyFrame</code> <code style="color: #808080;">KeyTime</code><code style="color: #000000;">=</code><code style="color: blue;">"00:00:00.6"</code> <code style="color: #808080;">Value</code><code style="color: #000000;">=</code><code style="color: blue;">"Collapsed"</code> <code style="color: #000000;">/></code></span></span></div> <div style="background-color: #f8f8f8;"><span style="font-size: 12px;"><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">ObjectAnimationUsingKeyFrames</code><code style="color: #000000;">></code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">Storyboard</code><code style="color: #000000;">></code></span></div> </div> <p>To obtain the scene height I use binding to the DropSettings object that is injected in the constructor when the raindrop is created.</p> <p><strong></strong></p> <h2><strong> <h3>Let’s start raining!</h3> </strong></h2> <p>This was all you need to simulate rain. To actually start it you have to call the classes we created in a manner that satisfies our expectations.</p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;">DropSettings dropSettings = </code><code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">DropSettings(300);</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important; font-size: 12px;"><code style="color: #000000;">Rain rain = </code><code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">Rain(dropSettings, </code><code style="color: #006699; font-weight: bold;">this</code><code style="color: #000000;">.Scene, 40, 3, 400);</code></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;"><span style="font-size: 12px;">rain.Start();</span></code></span></div> </div> <p><strong></strong></p> <h2><strong> <h3>Conclusion</h3> </strong></h2> <p>Although Silverlight is still very CPU consuming, in this article I’ve shown you how to use a simple algorithm to simulate rain. For all that we still should not expect miracles when it comes to real time particle simulations. But I hope soon we shall have what we wish to make our application look and behave really realistic.</p> <h3>About the author</h3> <p><img alt="" style="float: left; margin-right: 10px;" src="http://www.silverlightshow.net/Storage/lazar.png" />Lazar Nikolov is a software developer at <a href="http://www.completit.com/" target="_blank">CompletIT</a> - the company behind <a href="http://www.silverlightshow.net/">SilverlightShow.net</a> and leader in <strong>Silverlight</strong> related technologies in Bulgaria. His main interests are focused on Silverlight rich applications and <strong>Windows Phone 7</strong> development.</p> <p>In addition to authoring Silverlight articles (his series on ‘<a href="http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight.aspx">Simulating rain in Silverlight</a>’ became one of the most popular articles on SilverlightShow!), Lazar is involved in the verification of all SilverlightShow articles, making sure that all content is consistent and in-line with the latest Silverlight/WP7 release updates.</p> http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight.aspx editorial@silverlightshow.net (Lazar Nikolov ) http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight.aspx#comments http://www.silverlightshow.net/items/Simulating-rain-in-Silverlight.aspx Mon, 14 Mar 2011 10:58:00 GMT A classic memory game: Part 1 - Designing the game <p><em><strong>This article is compatible with the latest version of Silverlight.</strong></em></p> <div style="padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;border: #dddddd 1px solid;"> <h3>Don't miss...</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/XNA-for-Silverlight-developers-Part-1-Fundamentals.aspx">XNA for SL developers series</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/book/Pro-Game-Design-with-Silverlight-4.aspx">Pro Game Design with SL4 book: </a></li> </ul> <p style="padding-bottom: 5px;">         <a href="http://www.silverlightshow.net/book/Pro-Game-Design-with-Silverlight-4.aspx"><img alt="Beginning Windows Phone 7 Development" src="http://www.silverlightshow.net/Storage/GameDesign.jpg" /></a> </p> <p style="font-size: 12px;">             <a href="http://www.silverlightshow.net/Books.aspx">Show more books</a><img alt="" src="http://www.silverlightshow.net/Storage/arrow-content.jpg" /></p> </div> <p>This article is Part 1 of “A classic memory game”.</p> <h3>Introduction</h3> <p>My wife has started learning Silverlight and because of my Expression Blend skills are still lacking, we have decided to build the following classic memory game so both of us can learn something new. We kept things simple but we respected basic Silverlight principles. That’s why we used MVVM which might sound an overkill for a simple game but you’ll see that it fits together perfectly. </p> <p>Nowadays everything revolves around Windows Phone 7 in the Silverlight world and I am not an exception either. Once I got my phone I quickly ported the game over to WP7 to see that with a few modifications it’s running nicely. </p> <p>In this first article I will go around the game’s concepts, designing the controls and the main game-states. In the second article I’ll finish building the game by adding the necessary code and connecting it with the View. The third part will be about porting the Silverlight game to Windows Phone 7.</p> <p>First things first, here’s the game itself and <a href="http://www.silverlightshow.net/Storage/Sources/memoria_2.zip">download link for the source code</a>.</p> <p style="text-align: center;"><iframe width="570" height="570" src="http://www.silverlightshow.net/Storage/demos/Memoria/MemoriaPart1.html"></iframe></p> <p> </p> <h3>Step 0. – creating a new MVVM Light project</h3> <p>For the project we have used my personal favorite and probably the most popular lightweight MVVM framework out there: Laurent  Bugnion’s MVVM Light toolkit. If you haven’t already installed it, you can do it from here: <a href="http://www.galasoft.ch/mvvm/installing/manually/" title="http://www.galasoft.ch/mvvm/installing/manually/">http://www.galasoft.ch/mvvm/installing/manually/</a></p> <p>After installing and copying the Blend template in its place, two new ‘New Project’ templates should appear in the Silverlight department:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_0_thumb1_2.png"><img width="333" height="177" title="mem_0_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_0_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_0_thumb1_thumb.png" /></a></p> <p>Of course you can add the MVVM Light toolkit bits later to the project as well, but it is very nice to have a template for an easy start. It’s also important to note that the MVVM Light toolkit is available for Silverlight 3, <strong>Silverlight 4</strong>, WPF3.5, WPF4 and <strong>Windows Phone 7</strong>.</p> <h3>Creating a custom ToggleButton Style – the Card</h3> <p>After drawing the different cards, the back of the cards,  and saving them as images, our first step was to create a custom control for the cards. </p> <p>In Blend put a Grid in the LayoutRoot and put two Images inside this Grid. One will represent the back of the card, the other will be the front. Right click on the Grid and choose Make into Control..</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_cardctrl1_thumb1_2.png"><img width="277" height="252" title="mem_cardctrl1_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_cardctrl1_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_cardctrl1_thumb1_thumb.png" /></a></p> <p>In the upcoming panel find the ToggleButton control and add the name CardToggleButtonStyle. Select a separate resource file (you may have to create a new one) to define the style in to keep the MainPage.xaml clean.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_cardctrl2_thumb3_2.png"><img width="273" height="339" title="mem_cardctrl2_thumb3" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_cardctrl2_thumb3" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_cardctrl2_thumb3_thumb.png" /></a></p> <p>Delete the ContentPresenter, so you will end up something like this:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_cardctrl3_thumb1_2.png"><img width="272" height="358" title="mem_cardctrl3_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_cardctrl3_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_cardctrl3_thumb1_thumb.png" /></a></p> <p>Notice the States panel, especially the CheckStates state-group. Every ToggleButton has a checked and unchecked state and we will use these two states to switch between our card’s front and back. So select the Unchecked state and change the front image’s Visibility to Collapsed. Then select the Checked state and do the same with the back image.</p> <p>Now if you run the application you should be able to switch between the back and front of the card by clicking on it. Let’s add the turning-animation to the switching to make it look better! </p> <p>Select the Unchecked state and add a transition to Checked state (1). A good length for the animation is 0.3 secs (2). By selecting the newly created transition we can edit its animation. Forward to 0.2 sec in the timeline, select the front image (3) and click the Record Keyframe button (4). Do this for the back image too (3,4). Set up a 90 degrees Y rotation in the Projection panel for the front image, and a –90 for the back (5). (Don’t worry when Blend automatically overrides the 90 degrees to 89...) Change the Visibility of the images, the front was Collapsed, change it to Visible. The back was Visible, change it to Collapsed (6). Now forward to the 0.3 sec mark and change the front images Y rotation to 0 (7). Now when you press the play button, you should see the card turning from one side to the other.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_ctrl_anim_thumb1_2.png"><img width="455" height="402" title="mem_ctrl_anim_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_ctrl_anim_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_ctrl_anim_thumb1_thumb.png" /></a></p> <p>You’ll have to create the opposite of this animation in the Checked->Unchecked transition.</p> <p>The cards will be flipped back when a certain time elapsed or a third card is about to turn. That means the logic is responsible for this task not the player. So in the Checked state set the <strong>IsHitTestVisible</strong> to false. At first I didn’t do this and had this bug where the user could turn back and forth a card without the MoveCounter increasing.</p> <h3>Designing the layout – Creating a WrapListBox</h3> <p>So we have the card control, now we need to place them. The memory game shouts for a WrapPanel, you’ll find that in the <a href="http://silverlight.codeplex.com/">Silverlight toolkit</a>. But we wanted a more dynamic solution, having different number of cards for each difficulty. That’s why we used a WrapListBox, a ListBox with WrapPanel’s layout. Here’s how to do it:</p> <p>Drop a ListBox in the Layout Grid, right click on it and choose Edit Additional Templates –> Edit Layout of Items (ItemsPanel) –> Create Empty..</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap_thumb2_2.png"><img width="462" height="289" title="mem_wrap_thumb2" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_wrap_thumb2" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap_thumb2_thumb.png" /></a></p> <p>Give it a name (WrapItemsTemplate) and again place the template in the separate resource dictionary to keep the main xaml clean. The ItemsPanel is responsible for the layout of the ListBox’s items. Here you can override the ListBox’s default layout (which is a StackPanel) and do anything you want. Just check out <a href="http://bea.stollnitz.com/blog/?p=40">Bea Stollnitz’s famous solar system example</a>.</p> <p>We’ll need only a simple WrapPanel now. Delete the default StackPanel and replace it with the WrapPanel (you’ll need the <a href="http://silverlight.codeplex.com/">Silverlight toolkit</a>).</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap2_thumb1_2.png"><img width="347" height="97" title="mem_wrap2_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_wrap2_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap2_thumb1_thumb.png" /></a></p> <p>Trying it by placing a few Cards inside you’ll see that it doesn’t do exactly what we wanted. The problem is the ScrollViewer.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap3_thumb_2.png"><img width="243" height="244" title="mem_wrap3_thumb" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_wrap3_thumb" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap3_thumb_thumb.png" /></a></p> <p>The quickest solution is to remove it from the ListBox’s template (we wouldn’t want the user to scroll for flipping cards).</p> <p>Right click on the ListBox, select Edit Template and Edit a Copy.. After giving it a name (MemoryListBoxStyle) and placing it in the separate resource dictionary, move up the ItemsPresenter into the Grid, and delete the unneeded parts: the Border, the ScrollViewer and the ValidationErrorElement. The ItemsPresenter defines where the ItemsPanel (that’s our WrapPanel) is added inside the ListBox template. So we will need just that.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap6_thumb1_2.png"><img width="388" height="154" title="mem_wrap6_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_wrap6_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap6_thumb1_thumb.png" /></a></p> <p>Much better:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap7_thumb1_2.png"><img width="381" height="287" title="mem_wrap7_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mem_wrap7_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/mem_wrap7_thumb1_thumb.png" /></a></p> <h3>Designing the layout – Menu and VisualStates</h3> <p>The game has three main stages: choosing a difficulty (start), playing, score (end). VisualStates are useful not just in (Custom) Control level, but in UserControl level as well. I’ve added three VisualStates to the LayoutRoot after building the menu items.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/state0_thumb1_2.png"><img width="256" height="256" title="state0_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="state0_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/state0_thumb1_thumb.png" /></a><a href="http://www.silverlightshow.net/Storage/Users/wildfox/state1_thumb5_2.png"><img width="256" height="256" title="state1_thumb5" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="state1_thumb5" src="http://www.silverlightshow.net/Storage/Users/wildfox/state1_thumb5_thumb.png" /></a><a href="http://www.silverlightshow.net/Storage/Users/wildfox/state2_thumb2_2.png"><img width="257" height="256" title="state2_thumb2" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="state2_thumb2" src="http://www.silverlightshow.net/Storage/Users/wildfox/state2_thumb2_thumb.png" /></a></p> <p>All the menus are Grids with a rounded Rectangle inside them. The Buttons use a custom style containing a rounded Rectangle and the ContentPresenter. </p> <p>The template of the RadioButtons are the ContentPresenter and two Rectangles. One Rectangle behaves as a highlight border, because it doesn’t fill and is visible only when in Checked state.</p> <p>For the states first we need to add a VisualStateGroup, select the LayoutRoot, switch to the States panel, and add a VisualStateGroup. Now we can add our three states and of course we won’t miss adding transitions as well. The result looks like this:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/mainstates_thumb4_2.png"><img width="395" height="276" title="mainstates_thumb4" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="mainstates_thumb4" src="http://www.silverlightshow.net/Storage/Users/wildfox/mainstates_thumb4_thumb.png" /></a></p> <p>Note that you can add Easing to transitions (highlighted too) to make a more realistic animation. For example in my case I have an ElasticInOut Easing on the MenuState –> GameState transition.</p> <h4>Switching States using the GoToStateAction behavior</h4> <p>A great and straightforward way to change between states is the GoToStateAction behavior. With this behavior we can easily set up the initial state, the GameState, and the switching from EndState to MenuState. What we can’t do with it, is the switch from GameState to EndState because it’s not trivial, it’s decided by the game logic. So let’s do the trivial ones:</p> <p>Switch to the Assets panel and find the GoToStateAction behavior in the Behaviors. Put the behavior inside the LayoutRoot and select Loaded for EventName and MenuState for State. Don’t forget to check the UseTransitions box.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/gotostate0_thumb1_2.png"><img width="255" height="286" title="gotostate0_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="gotostate0_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/gotostate0_thumb1_thumb.png" /></a>  <a href="http://www.silverlightshow.net/Storage/Users/wildfox/gotostate01_thumb6_2.png"><img width="468" height="286" title="gotostate01_thumb6" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px;" alt="gotostate01_thumb6" src="http://www.silverlightshow.net/Storage/Users/wildfox/gotostate01_thumb6_thumb.png" /></a></p> <p>To switch from MenuState to GameState place another GoToStateAction behavior inside the start button, EventName is Click, StateName is GameState. Put the final behavior inside the new game button to make the switch from EndState to MenuState again (StateName is MenuState).</p> <h3>Summary</h3> <p>In this article we started designing a game, our main tool was Expression Blend. We’ve created a custom control for the Cards, a WrapListBox for laying out them, and we set up the three main states of the game. All of these parts are real, working elements.</p> <p>In the next part we will put some logic behind the game and connect it with the View, using converters, the CallDatacontextMethodAction behavior and others. We will again rely heavily on Blend.</p> <h3>About the Author</h3> <p><img width="150" height="190" style="width: 100px; float: left; height: 134px; margin-right: 15px;" alt="Levente Mihaly" src="http://www.silverlightshow.net/Storage/levi.jpg" />My name is Levente Mihaly. I've entered the .NET world in 2006, and after graduating at Budapest University of Technology (Msc in Computer Science) I started working as a .NET software developer. After meeting technologies like WinForms and ASP.NET, Silverlight quickly became my favourite platform from the early Silverlight 2 beta stages. I was always interested in mobile development and now I'm very happy since with Windows Phone 7 I can easily expand my knowledge to the mobile world. Nowadays beside following Silverlight I'm focusing on WP7 in my free time. I'm also the runner-up of the 2010 Silverlight ecoContest. You can reach me on twitter (<a href="http://twitter.com/#!/leventemihaly" target="_blank">@leventemihaly</a>). <br />  </p> http://www.silverlightshow.net/items/A-classic-memory-game-Part-1-Designing-the-game.aspx editorial@silverlightshow.net (Levente Mihály ) http://www.silverlightshow.net/items/A-classic-memory-game-Part-1-Designing-the-game.aspx#comments http://www.silverlightshow.net/items/A-classic-memory-game-Part-1-Designing-the-game.aspx Thu, 20 Jan 2011 10:00:00 GMT Step-by-Step Guide to Silverlight Shape Controls <p><em><span style="line-height: 115%; font-family: calibri, sans-serif; font-size: 11pt;"><strong>This article is compatible with the latest version of Silverlight.</strong></span></em></p> <p>In my previous post “<a href="http://www.kunal-chowdhury.com/2010/09/introduction-to-shapes-in-silverlight-4.html" target="_blank">Introduction to Shapes in Silverlight</a>” I introduced you with various types of Shapes available in Silverlight and informed you that, I will post an article describing each one of them and here it is.</p> <p>In this article, I am going to describe you about each shapes and the process to add them in our application (whenever you need). This article is for the Beginners, who don’t know much about the shape controls. If you have any suggestions/concerns please use the feedback section to let me know.</p> <h2>Prerequisite</h2> <p>As mentioned in my previous post, you need “<span style="color: #800000;">Microsoft.Expression.Drawing.dll</span>” assembly to get the new Shape controls in hand to work with. You can get this dll once you install the Expression Blend SDK to your development PC. If you don’t have the Expression Blend, you can easily download it from the <a href="http://expression.microsoft.com/en-us/cc136530.aspx" target="_blank">Microsoft Expression site</a>.</p> <p>Apart from this, your development environment should have the following Tools already installed:</p> <ul> <li>Microsoft Visual Studio </li> <li>Silverlight Tools for Visual Studio </li> </ul> <h2>Introducing the Shape Controls</h2> <p>Once your development environment is ready, you can open the Expression Blend IDE and create a new Silverlight Application Project. I am demonstrating with the help of Expression Blend here, so that, it will be easy for you to understand properly.</p> <p><img width="400" height="342" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image8.png?imgmax=800" /></p> <p>Now, once your project has been created by the IDE, open your “Assets” tab and click on the “Shapes” sub section to expand it at the right. In the right pane you will see all the collection of the shapes available in Silverlight 4. </p> <p><img width="373" height="547" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image11.png?imgmax=800" /></p> <p>Lets start describing one by one. We will discuss both from the IDE and the XAML code. It will be helpful for you to understand. </p> <p>To work with the Shape controls, you need to add one xmlns namespace in your XAML page:</p> <p><img width="640" height="94" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image24.png?imgmax=800" /></p> <p>If you are using the Expression Blend IDE (designer), it will add this xmlns namespace automatically when you add the first shape control in your XAML page.</p> <h2>Arc Control</h2> <p>Let’s start with the Arc control. Earlier to Silverlight 4, how can you create an Arc shape? You have to use one Ellipse and two Rectangle controls to design the shape. You have to crop those controls as a Path control. Need more designing knowledge using the Blend IDE. Just think to create it from the backend code. OMG!!! You have to design the UserControl first as described earlier and the create the instance from the code behind and rotate it as necessary. Let us create a Arc using the Arc shape control. Click on the Arc symbol from the Assets pane and draw it in your designer page. </p> <p><img width="640" height="296" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image18.png?imgmax=800" /></p> <p>This will create the below XAML code:</p> <div class="wlWriterEditableSmartContent" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:f04b5861-a01f-42f5-bdb7-b721c4bf1460" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px;"><img alt="" style="width: 629px; height: 72px;border: 0px;" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/transformedimage161.png?imgmax=800" /></div> <p>So easy right? Yes, it is very easy to design. Now, from the Properties panel, you can change any attribute of the shape like “StrokeThickness”, “ArcThickness”, “ArcThicknessUnit”, “StartAngel”, “EndAngel” etc.</p> <p>Setting the “StrokeThickness” will change the thickness of the Arc. Have look into the following snapshot:</p> <p><img width="640" height="300" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image27.png?imgmax=800" /></p> <p>Increasing the “ArcThickness” will change the Arc like this: </p> <p><img width="640" height="300" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image30.png?imgmax=800" /></p> <p>“StartAngel” and “EndAngel” describes the start and end point of the Arc. Here I used zero as the start angel and 90 as the end angel. Hence, it produced 90 degree Arc. If you set StartAngel as zero and EndAngel as 360, it will create a circle for you. The Ring control available in the list produces same code. </p> <p><img width="640" height="293" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B3%5D.png?imgmax=800" /></p> <p>If you want to draw a Pie in your UI, you can use the Pie shape control available in the list. It internally uses the same Arc control having different StartPoint and EndPoint to produce the Pie Shape. Have a look into the following snapshot: </p> <p><img width="640" height="298" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B6%5D.png?imgmax=800" /></p> <p>Setting the StartAngel to 90 and EndAngel to 360 creates the Pie Shape. You can adjust the angels to generate a different pie shape. </p> <h2>Block Arrow Control</h2> <p>If you want to add some arrows in your application for direction, what will you do if you are using the earlier version of Silverlight? Yes, you have to create an Arrow UserControl properly shaped with other controls like Rectangle and/or Paths. Then based on the direction you had to rotate the control. So Irritating!!!</p> <p>No need to tense more. Silverlight 4 is there for you. The Expression Blend SDK now has support for Block Arrow controls. There are four types of Block Arrow Control named “Block Arrow Down”, “Block Arrow Left”, “Block Arrow Top” and “Block Arrow Right”. They are not different controls, only changing the enum property will do the trick for you. So, no need to use transform to rotate the control and no need to use four different controls.</p> <p>From the Assets pane chose any one of the Block Arrow and draw four shapes of the same. Now, from the properties panel, search for the orientation property. Select “Left”, “Right”, “Up” or “Down” from the orientation dropdown based on your requirement. That’s it. It will change the shape accordingly.</p> <p><img width="640" height="295" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image36.png?imgmax=800" /></p> <p>There are some other common properties available for the Block Arrow control e.g. ArrowheadAngle and ArrowBodySize. They are responsible for changing the size of the arrow head and arrow body respectively. You can find those properties in the property panel. </p> <p><img width="271" height="231" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image39.png?imgmax=800" /></p> <p>Let’s see the XAML code, which has been generated for our four controls. Here it is: </p> <div class="wlWriterEditableSmartContent" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:809148d2-75b2-4d6c-a6f7-ef68f01cfe16" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px;"><img alt="" style="width: 631px; height: 298px;border: 0px;" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/transformedimage330.png?imgmax=800" /></div> <p>As you see, the only change between them is the Orientation property. So, just setting the Enum value you can set the direction of the Block Arrow. <img class="wlEmoticon wlEmoticon-openmouthedsmile" style="border-style: none;" alt="Open-mouthed smile" src="http://lh4.ggpht.com/_MOj9mkIt81A/TIplVpMH_uI/AAAAAAAAGj0/riljZrojWAc/wlEmoticonopenmouthedsmile2.png?imgmax=800" /></p> <h2>Callout Control</h2> <p>Before starting with this point think 10 times, if you want to develop a Callout control in earlier version of Silverlight, how would you do this? Any idea? Hmmm… little bit difficult. Some hint is to create a vector image and scale it as per need or use some path controls to create the shape. Not a good idea but this needs some effort from a good designer. Am I right? Yes.</p> <p>But now Silverlight gives you those controls inbuilt in the runtime. Choice is yours, how do you want to utilize them. Like the Block Arrow, the Callout control also has four different enum types which you have to set based on your requirement.</p> <p>Here are some example of Callout Controls:</p> <p><img width="570" height="154" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image52.png?imgmax=800" /></p> <p>Once you draw a callout control in the XAML designer, in the properties panel you will see a property called “CalloutStyle”. This dropdown has four enum values called “Cloud”, “Oval”, “Rectangle” and “RoundedRectangle”, which ones set will produce the respective shape in your UI.</p> <p><img width="264" height="228" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image55.png?imgmax=800" /></p> <p>The property called “AnchorPoint” gives you the option to change the callout start point for the anchor. This displays as (x, y) coordinate value. The default value for the AnchorPoint is (0, 1.5). </p> <p>Here is the actual XAML code to produce four different types of callout shapes:</p> <div class="wlWriterEditableSmartContent" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:43fe53ed-5236-459a-a5d1-50b1e199ee54" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px;"><img alt="" style="width: 631px; height: 411px;border: 0px;" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/transformedimage113.png?imgmax=800" /></div> <p>You can easily find out the difference between each callout type.</p> <h2>Ellipse Control</h2> <p>This is not a new control in Silverlight 4. It was part of initial version of Silverlight too. You can find it in the System.Windows.dll assembly. Using Ellipse control, you can draw ellipse and circles.</p> <div class="wlWriterEditableSmartContent" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:bcaadd82-c4eb-42ea-8049-c6f70fc396c8" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px;"><img alt="" style="width: 631px; height: 60px;border: 0px;" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/transformedimage41.png?imgmax=800" /></div> <p>The above code will produce a circle as shown in the below screenshot:</p> <p><img width="300" height="225" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px solid;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image4.png?imgmax=800" /></p> <p>Setting different height & width, you can create an ellipse for your UI. Not going to discuss more on this control as it’s a common control for all.</p> <h2>Regular Polygon Control</h2> <p>Pentagon, Hexagon, Star and Triangle shape controls use the RegularPolygon internally to generate the said shapes in the UI. The properties called “InnerRadius” and “PointCount” are responsible to generate not only those shapes but other various shapes too. Have a look here:</p> <p><img width="640" height="293" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B9%5D.png?imgmax=800" /></p> <p>InnerRadius of 100% and PointCount of 6 produces a Hexagon Shape as shown above. The XAML code for the above shape will look as below:</p> <div class="wlWriterEditableSmartContent" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:ff338a00-e419-4298-b35e-b50588d38201" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px;"><img alt="" style="width: 630px; height: 67px;border: 0px;" src="http://lh6.ggpht.com/_MOj9mkIt81A/TIplcdGOJII/AAAAAAAAGkQ/pewYpIeres4/transformedimage%5B52%5D.png?imgmax=800" /></div> <p><img width="640" height="291" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B12%5D.png?imgmax=800" /></p> <p>Inner Radius of 100% and PointCount of 5 generates Pentagon as shown in the above figure.</p> <p><img width="640" height="291" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B18%5D.png?imgmax=800" /></p> <p>If you want to create a Star shape, set the InnerRadius to a lower value. Setting InnerRadius to 50% and PointCount to 5 generates a perfect Star shape. </p> <p><img width="640" height="296" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B15%5D.png?imgmax=800" /></p> <p>Want to add a Triangle in your page? Set the PointCount to 3. 3 is the minimum value for the PointCount property of the RegularPolygon shape control. </p> <p><img width="640" height="289" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B24%5D.png?imgmax=800" /></p> <p>You can also generate a circle using the same RegularPolygon shape control. Set the PointCount to 100 and it will create the above shape. Remember that, 100 is the Maximum value for the PointCount property. </p> <p><img width="640" height="295" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B21%5D.png?imgmax=800" /></p> <p>Setting the InnerRadius to 50% and PointCount to 100 will produce the above shape.</p> <h2>Rectangle Control</h2> <p>The Rectangle shape was available in earlier versions too. But, let me describe a bit of it here too. It is available as part of the System.Windows.dll assembly. The default generates a Rectangle shape. But tweaking it with the help of exposed properties, you can generate Rounded Rectangle or even a Circle too.</p> <p><img width="640" height="292" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B30%5D.png?imgmax=800" /></p> <p>In the default case, the RadiusX and RadiusY properties will have a value ‘0’ (zero) and hence it generates a pure square/rectangle shape.</p> <div class="wlWriterEditableSmartContent" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:28bdcdd8-77c7-44e8-abe6-91777ec3d768" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px;"><img alt="" style="width: 630px; height: 54px;border: 0px;" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/transformedimage%5B79%5D.png?imgmax=800" /></div> <p><img width="640" height="289" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B33%5D.png?imgmax=800" /></p> <p>Setting those properties higher than zero will render the rectangle with rounded corner. In the above screenshot, it has a value of 20 for both RadiusX & RadiusY. Hence, created a rounded corner. If you set them to a more higher value, it may change to a Circle too.</p> <h2>Line Arrow Control</h2> <p>It’s a new shape control introduced in Silverlight 4. Before going into the deep discussion, think of creating a simple arrow (straight or bendable). To create such kind of arrow will take a good effort from your production development. Now it comes with Silverlight runtime. Tweaking the control by setting proper properties you can make it straight or bended. You can also make it one directional or bi directional. Have a look here:</p> <p><img width="640" height="289" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B36%5D.png?imgmax=800" /></p> <p>Here is the XAML code:</p> <div class="wlWriterEditableSmartContent" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:fb10f13d-61bc-4739-9c8d-e1370b5c7435" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px;"><img alt="" style="width: 628px; height: 56px;border: 0px;" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/transformedimage%5B111%5D.png?imgmax=800" /></div> <p>Setting the BendAmount to zero will create a straight line for you. You can also change the starting point by changing the StartCorner property of the control.</p> <p><img width="640" height="290" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B39%5D.png?imgmax=800" /></p> <p>If you want a fully bended arrow, you can do it by setting the BendAmount property to 1. Remember that, 1 is the highest value for the BendAmount. Have a look into the below screenshot:</p> <p><img width="640" height="289" title="image" style="background-image: none; margin: 0px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/userfiles/StepByStepGuideToShapeControls/image%5B42%5D.png?imgmax=800" /></p> <p>There are 5 types of ArrowHead. You can set them as the StartArrow and EndArrow property. See the above figure for more details. In the above example I set the StartArrow as “OvalArrow” and the EndArrow as the default “Arrow”.</p> <h2>End Note</h2> <p>This is all about the new Shape controls. Hope this long article will help you understanding the basics about them. Please note that, all the diagrams were drawn on top of a Grid control and hence had the property Margin set for each one of them. If you are using Canvas, you have to use Height & Width explicitly for the controls.</p> <p>Don’t forget to share this article link to others who might feel it very useful.</p> <p>Appreciate your Feedbacks and/or Suggestions to improve this Article.</p> http://www.silverlightshow.net/items/Step-by-Step-Guide-to-Silverlight-Shape-Controls.aspx editorial@silverlightshow.net (Kunal Chowdhury ) http://www.silverlightshow.net/items/Step-by-Step-Guide-to-Silverlight-Shape-Controls.aspx#comments http://www.silverlightshow.net/items/Step-by-Step-Guide-to-Silverlight-Shape-Controls.aspx Thu, 30 Sep 2010 11:30:00 GMT Using Blend 4's new built-in TransitionEffects in Navigation and MVVM applications <p><em><span style="line-height: 115%; font-family: calibri, sans-serif; font-size: 11pt;"><strong>This article is compatible with the latest version of Silverlight.</strong></span></em></p> <p>Expression Blend 4 comes with some pretty cool pre-built </p> <strong>VisualState</strong> transition-animations called <strong>TransitionEffects</strong>. A <strong>TransitionEffect</strong> is a pixel-based transition from one state to another, in other words it’s a PixelShader that has an animatable Progress property. These effects can be used in various scenarios, they are very developer/designer friendly, and they are an easy way to make your Silverlight application more attractive. <p>In this article I will show you two situations to use Blend 4’s built-in TransitionEffects: </p> <p>- Navigating between pages in Navigation Framework and</p> <p>- switching between Views in an MVVM (Light Toolkit) scenario.</p> <p>Here are the two samples with the „Pixelate” and the „Slide In” effects, live demo and source codes:</p> <p><iframe width="600" height="300" src="http://www.silverlightshow.net/Storage/demos/MvvmTransition/MvvmTransition.html"></iframe></p> <p><a href="http://www.silverlightshow.net/Storage/Sources/MvvmTransition.zip">Source code to MVVM Transition Demo</a></p> <p><a href="http://www.silverlightshow.net/Storage/demos/CosmopolitanTheme/CosmopolitanTheme.html">Live demo for Navigation Transition</a></p> <p><a href="http://www.silverlightshow.net/Storage/Sources/CosmopolitanThemeWithTransition.zip">Source code to Navigation Transition</a></p> <h3>VisualState and Transition recap</h3> <p>You probably know VisualStates from Silverlight SDK Controls and from custom Controls. The name of the concept is “Parts and State Model”. This means that every control has Parts (named elements within the Control) and States (and State Groups). Between switching from a state to another we can define transitions. VisualStateManager is the one that handles state-changes.</p> <p>The States panel first appeared in Blend 2 SP1, in Blend 3 there were the pre-setted Easings for the transition storyboards, and now in the fourth version of Blend there are the TransitionEffects.</p> <p>Here’s the standard Button’s States-view in Blend 4:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/buttonStates_2.png"><img width="244" height="225" title="buttonStates" style="display: inline;border: 0px solid;" alt="buttonStates" src="http://www.silverlightshow.net/Storage/Users/wildfox/buttonStates_thumb.png" /></a> </p> <p>It’s good to know that we can use VisualStates and Transitions not just in custom Controls but in UserControls as well.</p> <h3>TransitionEffect in a Navigation Framework Application</h3> <p>To enable one of Blend 4’s new TransitionEffects in a Navigation Framework application, all we need is Blend 4 and zero coding. :)</p> <ol> <li>If you don’t have an existing navigation application in which you can test, create one using Visual Studio. Create a new project using the Silverlight Navigation Application template. </li> <li>Once you’re application is ready, open it in Blend 4. Open the main page (default is MainPage.xaml). </li> <li>Expand the LayoutRoot and put the ContentBorder in a Grid. You can do this by right clicking on the ContentBorder and selecting Group Into ->Grid. ContentBorder contains the ContentFrame. We will add the transition effect to the newly created grid. <br />  <a href="http://www.silverlightshow.net/Storage/Users/wildfox/groupinto_2.png"><img width="377" height="295" title="groupinto" style="display: inline;border: 0px solid;" alt="groupinto" src="http://www.silverlightshow.net/Storage/Users/wildfox/groupinto_thumb.png" /></a> </li> <li>Luckily ContentFrame exposes both the Navigat<strong>ing</strong> and Navigat<strong>ed</strong> events. The first one fires before the navigation, the second one after the navigation is made. We will create two states according to these events, a “NavigatingState” and a “NavigatedState”. <br /> Select the States panel, and add a VisulStateGroup by clicking on the plus icon. Add two VisualStates to the group. <br />  <a href="http://www.silverlightshow.net/Storage/Users/wildfox/navstates_2.png"><img width="244" height="119" title="navstates" style="display: inline;border: 0px solid;" alt="navstates" src="http://www.silverlightshow.net/Storage/Users/wildfox/navstates_thumb.png" /></a> </li> <li>Notice the “fx” icon next to the Default Transition. Click on it and from the dropdown select the TransitionEffect you would like to use. Some effects have additional options (for “Slide In” there’s the option for slide direction). <br /> <a href="http://www.silverlightshow.net/Storage/Users/wildfox/navtrans_2.png"><img width="364" height="229" title="navtrans" style="display: inline;border: 0px solid;" alt="navtrans" src="http://www.silverlightshow.net/Storage/Users/wildfox/navtrans_thumb.png" /></a> </li> <li>Next to fx icon you can set an easing and the duration of the transition, mine is 1 second long. <br /> <a href="http://www.silverlightshow.net/Storage/Users/wildfox/easings_2.png"><img width="203" height="244" title="easings" style="display: inline;border: 0px solid;" alt="easings" src="http://www.silverlightshow.net/Storage/Users/wildfox/easings_thumb.png" /></a> </li> <li>So now there will be an animation between the two states we created. Next step is to wire up the states. On the Assets panel in the Behaviors, there’s a behavior called GoToStateBehavior. In this Behavior we can connect an event with a state. Just what we need. Expand the “ContentFrame” Border element in the Object and Timeline panel. Drag a GoToStateBehavior to the ContentFrame. Then drag another one. <br /> <a href="http://www.silverlightshow.net/Storage/Users/wildfox/gotostate1_2.png"><img width="199" height="353" title="gotostate1" style="display: inline;border: 0px solid;" alt="gotostate1" src="http://www.silverlightshow.net/Storage/Users/wildfox/gotostate1_thumb.png" /></a> </li> <li>Using the Behaviors, we can connect the NavigatingState with the Navigating event and the NavigatedState with the Navigated event. We can do this on the Properties panel of each Behavior. <br /> <a href="http://www.silverlightshow.net/Storage/Users/wildfox/gotostate2_2.png"><img width="198" height="244" title="gotostate2" style="display: inline;border: 0px solid;" alt="gotostate2" src="http://www.silverlightshow.net/Storage/Users/wildfox/gotostate2_thumb.png" /></a> </li> <li>After the events are connected with the states, we can run the application and voila, the navigation is animated. <br /> Though you may notice that not only the content is animated, but the selected TransitionEffect is applied to the navigation links’ header also. This might be an unwanted side-effect. For a workaround, switch to XAML view, and move the whole VisualStateManager definition just inside the Grid we created in the first step. Something like this: <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="LayoutRoot"</span> <span style="color: #ff0000;">Style</span><span style="color: #0000ff;">="{StaticResource LayoutRootGridStyle}"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,0,0,0"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #008000;"><!-- VisualStateManager moved from LayoutRoot, just the Content will have the TransitionEffect --></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateManager.CustomVisualStateManager</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ei:ExtendedVisualStateManager</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateManager.CustomVisualStateManager</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateGroup</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="VisualStateGroup"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateGroup.Transitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualTransition</span> <span style="color: #ff0000;">GeneratedDuration</span><span style="color: #0000ff;">="0:0:1"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ei:ExtendedVisualStateManager.TransitionEffect</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ee:SlideInTransitionEffect</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ei:ExtendedVisualStateManager.TransitionEffect</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualTransition.GeneratedEasingFunction</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">CircleEase</span> <span style="color: #ff0000;">EasingMode</span><span style="color: #0000ff;">="EaseIn"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualTransition.GeneratedEasingFunction</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualTransition</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateGroup.Transitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="NavigatingState"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="NavigatedState"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff;">></span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Border</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="ContentBorder"</span> <span style="color: #ff0000;">Style</span><span style="color: #0000ff;">="{StaticResource ContentBorderStyle}"</span> <span style="color: #ff0000;">Margin=</span><span style="color: #0000ff;">"0"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span>...</pre> <!--CRLF--></div> </div> </li> </ol> Now when we run the application again, the TransitionEffect is only applied to content, the header will stay intact. <p>For the <a href="http://dl.dropbox.com/u/5906693/NavigationTestPage.html">demo</a> I added the “Slide In” effect to the <a href="http://visualstudiogallery.msdn.microsoft.com/en-us/9329bdf4-3be7-4347-b1cd-b2c5d4e5a293">Cosmopolitan Theme Sample</a>. Notice when there are a lot of different controls on a page the transition might not be very smooth. That’s the case in the demo on the SDK Controls and Toolkit Controls page, where the page contains a lot of different controls. Loading all the controls takes long, it’s not the effect itself that is slow. Well, nothing is perfect.</p> <h3>TransitionEffect in an MVVM application</h3> <p>The second sample for using transitions is an MVVM application. Scenario is simple; we have a few Views and a menu. The user can select between the Views, and one is visible at a time. I really like Laurent Bugnion’s <a href="http://mvvmlight.codeplex.com/">MVVM Light Toolkit</a> for its simplicity and efficiency, so I’ll be using that.</p> <p>We will create a DataTemplate selector ContentControl, and will bind the Content to the selected ViewModel. Let’s create the Views and ViewModels first.</p> <ol> <li>First, we can start a new application using the MVVM Light (SL4) template. The MainPage.xaml, the MainPageViewModel and the ViewModelLocator will be automatically created. </li> <li>We can add the a few Views and their ViewModels using the MVVM Light Toolkit templates (add new item: MvvmView(SL) and MvvmViewModel (SL)). Let’s call these OneView, TwoView, ThreeView and OneViewModel, TwoViewModel, ThreeViewModel. <br /> <a href="http://www.silverlightshow.net/Storage/Users/wildfox/_listproject_2.png"><img width="229" height="221" title="listproject" style="display: inline;border: 0px solid;" alt="listproject" src="http://www.silverlightshow.net/Storage/Users/wildfox/_listproject_thumb.png" /></a> </li> <li>In the ViewModelLocator we must set up properties for the ViewModels. We can do this by using the “mvvmlocatorproperty” snippet. Once this is done for all three ViewModels, we can set up the DataContext bindings in the Views. <br /> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: hidden; overflow-y: hidden; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; height: 17px; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span>DataContext="{Binding OneVM, Source={StaticResource Locator}}"</pre> <!--CRLF--></div> </div> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> OneViewModel _oneViewModel;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #008000;">/// <summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #008000;">/// Gets the OneVM property.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #008000;">/// </summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> OneViewModel OneVMStatic</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (_oneViewModel == <span style="color: #0000ff;">null</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> CreateOneVM();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> _oneViewModel;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #008000;">/// <summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #008000;">/// Gets the OneVM property.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #008000;">/// </summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> [System.Diagnostics.CodeAnalysis.SuppressMessage(<span style="color: #006080;">"Microsoft.Performance"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #006080;">"CA1822:MarkMembersAsStatic"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> Justification = <span style="color: #006080;">"This non-static member is needed for data binding purposes."</span>)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> OneViewModel OneVM</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> OneVMStatic;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> <span style="color: #008000;">/// <summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> <span style="color: #008000;">/// Provides a deterministic way to delete the OneVM property.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> </span> <span style="color: #008000;">/// </summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> ClearOneVM()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (_oneViewModel != <span style="color: #0000ff;">null</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum40" style="color: #606060;"> </span> _oneViewModel.Cleanup();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum41" style="color: #606060;"> </span> _oneViewModel = <span style="color: #0000ff;">null</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum42" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum43" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum44" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum45" style="color: #606060;"> </span> <span style="color: #008000;">/// <summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum46" style="color: #606060;"> </span> <span style="color: #008000;">/// Provides a deterministic way to create the OneVM property.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> </span> <span style="color: #008000;">/// </summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum48" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> CreateOneVM()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum49" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum50" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (_oneViewModel == <span style="color: #0000ff;">null</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum51" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum52" style="color: #606060;"> </span> _oneViewModel = <span style="color: #0000ff;">new</span> OneViewModel();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum53" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum54" style="color: #606060;"> </span> }</pre> <!--CRLF--></div> </div> </li> </ol> <p><span style="line-height: 30px; font-size: 20px;">The DataTemplate selector</span></p> <p>For the DataTemplate selector we must create a custom ContentControl.</p> <ol> <li>Add a new class (in my case it’s called MvvmDataTemplateSelector) that inherits from ContentControl. <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: hidden; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; height: 64px; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> MvvmDataTemplateSelector : ContentControl</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> { </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> ...</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> }</pre> <!--CRLF--></div> </div> </li> <li>Add a property - type of DataTemplate - for each property. <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #008000;">/// <summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #008000;">/// DataTemplate for type OneViewModel</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #008000;">/// </summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> DataTemplate OneView { get; set; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #008000;">/// <summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #008000;">/// DataTemplate for type TwoViewModel</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #008000;">/// </summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> DataTemplate TwoView { get; set; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #008000;">/// <summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #008000;">/// DataTemplate for type ThreeViewModel</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #008000;">/// </summary></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> DataTemplate ThreeView { get; set; }</pre> <!--CRLF--></div> </div> </li> <li>Override the OnContentChanged method. In this method connect the ViewModel with its View, as we will bind the Content to the selected ViewModel. <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnContentChanged(<span style="color: #0000ff;">object</span> oldContent, <span style="color: #0000ff;">object</span> newContent)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> { </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #008000;">// select ContentTemplate for ViewModel</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (newContent <span style="color: #0000ff;">is</span> OneViewModel)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> ContentTemplate = OneView;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (newContent <span style="color: #0000ff;">is</span> TwoViewModel)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> ContentTemplate = TwoView;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (newContent <span style="color: #0000ff;">is</span> ThreeViewModel)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> ContentTemplate = ThreeView;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;">base</span>.OnContentChanged(oldContent, newContent); </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> }</pre> <!--CRLF--></div> </div> </li> <li>Set up the MainPage and MainPageViewModel. We can add buttons for each view in the xaml, and in the MainPageViewModel we can add Commands. Each Command will set the SelectedViewModel property to a ViewModel. </li> <li>Finally we can host our Views in the newly created MvvmDataTemplateSelector. Now when we compile and run the application we can switch between the Views. <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #008000;"><!--DataTemplates --></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DataTemplate</span> <span style="color: #ff0000;">x:Key</span><span style="color: #0000ff;">="oneView"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Views:OneView</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DataTemplate</span> <span style="color: #ff0000;">x:Key</span><span style="color: #0000ff;">="twoView"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Views:TwoView</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DataTemplate</span> <span style="color: #ff0000;">x:Key</span><span style="color: #0000ff;">="threeView"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Views:ThreeView</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> ...</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">Helpers:MvvmDataTemplateSelector</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="{Binding ActiveViewModel}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #ff0000;">OneView</span><span style="color: #0000ff;">="{StaticResource oneView}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #ff0000;">TwoView</span><span style="color: #0000ff;">="{StaticResource twoView}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #ff0000;">ThreeView</span><span style="color: #0000ff;">="{StaticResource threeView}"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Stretch"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Stretch"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #ff0000;">HorizontalContentAlignment</span><span style="color: #0000ff;">="Stretch"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #ff0000;">VerticalContentAlignment</span><span style="color: #0000ff;">="Stretch"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;">/></span></pre> </div> </div> </li> </ol> <h4>TransitioningContentControl</h4> <p>The easiest way to add transitions to our application is to use the Silverlight Toolkit’s TransitioningContentControl:</p> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">toolkit:TransitioningContentControl</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="{Binding ActiveViewModel}"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #ff0000;">Style</span><span style="color: #0000ff;">="{StaticResource TransitioningContentControlStyle2}"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #ff0000;">HorizontalContentAlignment</span><span style="color: #0000ff;">="Stretch"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #ff0000;">VerticalContentAlignment</span><span style="color: #0000ff;">="Stretch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">toolkit:TransitioningContentControl.ContentTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Helpers:MvvmDataTemplateSelector</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="{Binding }"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #ff0000;">OneView</span><span style="color: #0000ff;">="{StaticResource oneView}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #ff0000;">TwoView</span><span style="color: #0000ff;">="{StaticResource twoView}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #ff0000;">ThreeView</span><span style="color: #0000ff;">="{StaticResource threeView}"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Stretch"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Stretch"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #ff0000;">HorizontalContentAlignment</span><span style="color: #0000ff;">="Stretch"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #ff0000;">VerticalContentAlignment</span><span style="color: #0000ff;">="Stretch"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">toolkit:TransitioningContentControl.ContentTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">toolkit:TransitioningContentControl</span><span style="color: #0000ff;">></span> </pre> <!--CRLF--></div> </div> <p>There’s one drawback, there are only three transition animations built in the Control. Luckily we can help that by editing its template, thus enabling Blend 4’s TransitionEffect.</p> <ol> <li>Open up Blend, and on the MainPage edit the TransitioningContentControl’s template (right click, edit template, edit a copy.) It will look like this: <br /> <a href="http://www.silverlightshow.net/Storage/Users/wildfox/trans1_2.png"><img width="227" height="298" title="trans1" style="display: inline;border: 0px solid;" alt="trans1" src="http://www.silverlightshow.net/Storage/Users/wildfox/trans1_thumb.png" /></a> <p>The Control consists of two grids, one for the previous content, and one for the current content, this way enabling a transition between them. Each Transition animation has a State, when you set the TransitionName property, you set one of the upper States. The transition will happen between the Normal state (we cannot delete this) and the selected one. <br /> To add a new animation, you can add a new State, and set-up a Storyboard for it. This time though we will enable one of the built-in TransitionEffects, by setting the Default transition just like in the Navigation Framework example.</p> </li> <li>We can add a new State, or just edit the existing ones. I’ve edited the DefaultTransition: deleted the other States (this step is not necessary), deleted the DefaultTransition Storyboard, and in the State I set the PreviousContentPresetationSite to Collapsed, just like in the Normal state, because we will take care of this in the Default transition. </li> <li>Select the Default transition (the one with the TransitionEffect), and create a Storyboard, where you hide the PreviousContentPresentationSite halfway through the transition. <br /> <a href="http://www.silverlightshow.net/Storage/Users/wildfox/trans2_2.png"><img width="244" height="226" title="trans2" style="display: inline;border: 0px solid;" alt="trans2" src="http://www.silverlightshow.net/Storage/Users/wildfox/trans2_thumb.png" /></a> <p>At 0:00,000 the PreviousContentPresentationSite is Visible, at 0:00,500 it is Collapsed. The full transition is 1 second long. Of course you can change the timeline, e.g. when you are using a non-linear easing for the TransitionEffect. <br /> Here’s the code for the finished VisualStateManager:</p> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 90.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateManager.CustomVisualStateManager</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ei:ExtendedVisualStateManager</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateManager.CustomVisualStateManager</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateGroup</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="PresentationStates"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateGroup.Transitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualTransition</span> <span style="color: #ff0000;">GeneratedDuration</span><span style="color: #0000ff;">="0:0:1"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ei:ExtendedVisualStateManager.TransitionEffect</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ee:PixelateTransitionEffect</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ei:ExtendedVisualStateManager.TransitionEffect</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ObjectAnimationUsingKeyFrames</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Visibility)"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="PreviousContentPresentationSite"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DiscreteObjectKeyFrame</span> <span style="color: #ff0000;">KeyTime</span><span style="color: #0000ff;">="0:0:0.5"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DiscreteObjectKeyFrame.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Visibility</span><span style="color: #0000ff;">></span>Collapsed<span style="color: #0000ff;"></</span><span style="color: #800000;">Visibility</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DiscreteObjectKeyFrame.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DiscreteObjectKeyFrame</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ObjectAnimationUsingKeyFrames</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualTransition</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateGroup.Transitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="DefaultTransition"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ObjectAnimationUsingKeyFrames</span> <span style="color: #ff0000;">BeginTime</span><span style="color: #0000ff;">="00:00:00"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Visibility)"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="PreviousContentPresentationSite"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DiscreteObjectKeyFrame</span> <span style="color: #ff0000;">KeyTime</span><span style="color: #0000ff;">="00:00:00"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DiscreteObjectKeyFrame.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Visibility</span><span style="color: #0000ff;">></span>Collapsed<span style="color: #0000ff;"></</span><span style="color: #800000;">Visibility</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DiscreteObjectKeyFrame.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DiscreteObjectKeyFrame</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ObjectAnimationUsingKeyFrames</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualState</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Normal"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ObjectAnimationUsingKeyFrames</span> <span style="color: #ff0000;">BeginTime</span><span style="color: #0000ff;">="00:00:00"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum40" style="color: #606060;"> </span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Visibility)"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum41" style="color: #606060;"> </span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="PreviousContentPresentationSite"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum42" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DiscreteObjectKeyFrame</span> <span style="color: #ff0000;">KeyTime</span><span style="color: #0000ff;">="00:00:00"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum43" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DiscreteObjectKeyFrame.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum44" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Visibility</span><span style="color: #0000ff;">></span>Collapsed<span style="color: #0000ff;"></</span><span style="color: #800000;">Visibility</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum45" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DiscreteObjectKeyFrame.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum46" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DiscreteObjectKeyFrame</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ObjectAnimationUsingKeyFrames</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum48" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum49" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualState</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum50" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum51" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff;">></span></pre> </div> </div> </li> </ol> <h3>Summary</h3> <p>I hope I could show you in this short tutorial how easy it is to add a transition-animation to your application. The possible scenarios are endless, I’m sure everybody can find his own best way. You can even create custom TransitionEffects if you are familiar with the HLSL language.</p> http://www.silverlightshow.net/items/Using-Blend-4-s-new-built-in-TransitionEffects-in-Navigation-and-MVVM-applications.aspx editorial@silverlightshow.net (Levente Mihály ) http://www.silverlightshow.net/items/Using-Blend-4-s-new-built-in-TransitionEffects-in-Navigation-and-MVVM-applications.aspx#comments http://www.silverlightshow.net/items/Using-Blend-4-s-new-built-in-TransitionEffects-in-Navigation-and-MVVM-applications.aspx Wed, 28 Jul 2010 00:58:00 GMT WP7: UI Concepts of Windows Phone 7 <p><strong>This is part 4 of the Windows Phone 7 series</strong>:</p> <div style="padding-bottom: 2px; background-color: rgb(243,243,243); margin-top: 5px; padding-left: 5px; width: 200px; float: right; margin-left: 10px; padding-top: 5px;border: rgb(221,221,221) 1px solid;"> <h3>Don't Miss</h3> <ul style="list-style-type: circle; margin: 0px; padding-left: 20px; padding-right: 10px; font-size: 12px;"> <li style="padding-bottom: 2px;"><a href="http://www.silverlightshow.net/items/WP7-Stock-Quoting-Demo-Series-Part1.aspx">WP7 Stock Quoting Demo series</a> </li> <li style="padding-bottom: 2px;"><a href="http://www.silverlightshow.net/Search.aspx?q=WP7&adv=true&tg=true&ro=1&t=1,2,3&r=10&o=1">See all Windows Phone 7 articles</a> </li> <li style="padding-bottom: 2px;"><a href="http://www.silverlightshow.net/Search.aspx?q=WP7&adv=true&tg=true&ro=1&t=0&r=10&o=1">See latest Windows Phone 7 news</a> </li> </ul> </div> <h3>Metro Style</h3> <p>A Windows Phone design system, codenamed Metro is used as a basis for the Windows Phone 7 User Interface. It aims at easily directing end users to the content needed. In order to reach this, its principles focus on a look that uses type to echo the visual language of airport and metro system signage. Harmonious, functional and attractive visual elements are supposed to be realized in Metro interfaces. A good User Interface design should provoke playful exploration when using the application and give users a sense of wonder and excitement. It is highly recommended that developers incorporate Metro design style whenever this is possible. Its clear and straightforward design makes an application legible, while at the same time ecnourages the usage. Based on the application, the requirements may vary, but it still provides a more consistent, fluid User Interface experience from the custom and built-in view.</p> <p style="text-align: center;">  <img width="179" height="347" title="LockedScreen" style="display: inline;border: 0px;" alt="LockedScreen" src="http://www.silverlightshow.net/Storage/Users/AnTo/LockedScreen_3.jpg" /> <img width="187" height="349" title="Main" style="display: inline;border: 0px;" alt="Main" src="http://www.silverlightshow.net/Storage/Users/AnTo/Main_3.jpg" /> <img width="187" height="349" title="Office" style="display: inline;border: 0px;" alt="Office" src="http://www.silverlightshow.net/Storage/Users/AnTo/Office_3.jpg" /> </p> <p style="text-align: center;"><img width="179" height="347" title="Profile" style="display: inline;border: 0px;" alt="Profile" src="http://www.silverlightshow.net/Storage/Users/AnTo/Profile_3.jpg" /> <img width="187" height="348" title="Calendar_MonthView" style="display: inline;border: 0px;" alt="Calendar_MonthView" src="http://www.silverlightshow.net/Storage/Users/AnTo/Calendar_MonthView_3.jpg" /> </p> <p>User Interface elements should be authentically digital and embody harmonious, functional and attractive visual elements. Applications should grab the attention of users by promoting navigation, exploration, and exciting visuals in their design.This concept is the basis for the five principles of the Metro design:</p> <ul> <li>Clean, light, open, and fast: It is visually distinctive, contains ample white space, reduces clutter and elevates typography as a key design element. </li> <li>Content, not chrome: It accentuates focus on the content that the user cares most about, making the product simple and approachable for everyone. </li> <li>Integrated hardware and software: Hardware and software blend into each other and create a seamless user experience from single-button access to Search, Start, Back and the camera to on-board sensor integration. </li> <li>World-class motion: The Windows Phone 7 touch and gesture experiences on capacitive screens are consistent with Windows 7 on the desktop and include hardware-accelerated animations and transitions to enhance the user’s experience at every turn. </li> <li>Soulful and alive: A personalized, automatically updated view into the information that matters most to the user is enabled and brings to life a cinematic photo and video experience by having a fully integrated Zune media player experience. </li> </ul> <p> </p> <h2>Metro Style Controls</h2> <p>All controls, that come with Windows Phone 7 Development Tools are metro styled. The Panoramic View Control and the Pivot Control are exclusively developed for Windows Phone 7 but they are yet to be available. Nevertheless, while waiting for the official controls, a “temporary solution” has been elaborated. <a href="http://phone.codeplex.com/" target="_blank">Here</a> is the link to the codeplex project.</p> <h3>Panoramic View Control</h3> <p><img width="624" height="393" title="image" style="display: block; float: none; margin-left: auto; margin-right: auto;border: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/Users/AnTo/image.png" /> </p> <p>The Panoramic View Control itself is pretty basic. </p> <p>A Title and Background Image dependent properties are implemented within the Panoramic View Control. Just like a tab control, it also derives from ItemsControll. Each individual Item is of type PanoramaItem. You can think of these as visual sections. There is a default Width, provided by the control, which can be used by every section. Shall more space be needed, a custom Width can be specified. For each PanoramaItem should be assigned header and content properties.</p> <h3>Pivot Control</h3> <p><img width="629" height="480" title="clip_image001" style="display: block; float: none; margin-left: auto; margin-right: auto;border: 0px;" alt="clip_image001" src="http://www.silverlightshow.net/Storage/Users/AnTo/clip_image001_bf433b04-ba63-4532-9c3d-6a7c2ef06a10.jpg" /></p> <p> </p> <p>The Pivot Control is very close to the Tab Control. It can be compared to the dividers of a notebook. It allows multiple pages to be defined for the same window. Each page consists of a certain type of information or a group of controls that the application displays when the user selects the corresponding tab (Pivot Item). To navigate from one page to another you can either click the page’s Header or simply flick through pages.</p> <p> </p> <h3>Other Controls</h3> <ol> <li>Progress Indicator </li> <li>Border </li> <li>Check box </li> <li>Content control </li> <li>Content presenter </li> <li>Grid </li> <li>Hyperlink </li> <li>Image </li> <li>InkPresenter </li> <li>ListBox </li> <li>MediaElement </li> <li>Multi scale image </li> <li>Password box </li> <li>Progress bar </li> <li>Radio button </li> <li>Scroll viewer </li> <li>Slider </li> <li>Stack panel </li> <li>Text block </li> <li>Text box </li> <li>Canvas </li> <li>Push button </li> </ol> <p>Most of the controls have the same functionality as their corresponding controls in Silverlight.</p> <p>For more info about these controls read the <a href="http://go.microsoft.com/fwlink/?LinkID=183218">UI Design and Interaction Guide for Windows Phone 7 v2.0</a>.</p> http://www.silverlightshow.net/items/UI-Concepts-of-Windows-Phone-7.aspx editorial@silverlightshow.net (Anton Polimenov ) http://www.silverlightshow.net/items/UI-Concepts-of-Windows-Phone-7.aspx#comments http://www.silverlightshow.net/items/UI-Concepts-of-Windows-Phone-7.aspx Tue, 27 Jul 2010 00:07:00 GMT Understanding control customization with templates: part #2 <p style="text-align: justify;"><em><span style="line-height: 115%; font-family: calibri, sans-serif; font-size: 11pt;"><strong>This article is compatible with the latest version of Silverlight.</strong></span></em></p> <p style="text-align: justify;">In the <a href="http://www.silverlightshow.net/items/Understanding-control-customization-with-templates-part-1.aspx">previous part of this article</a>, I've explained the role of templates in Silverlight controls showing how to radically change the appearance of a control without having to change or rewrite its logic. This is an important feature of Silverlight's controls that allow a developer to create an application without concerning about its appearance and leave the designer free of manipulate it without needing to know their intimate logic. Unfortunately there are many times when built-in controls, the SDK and the Toolkit do not contains the control we need for our application. So you have to start writing the control by yourself, and creating a templated control make your work more reusable and customizable for future usages.</p> <p style="text-align: justify;"><a href="http://www.silverlightshow.net/Storage/Sources/SilverlightPlayground.ControlTemplates.zip">Download Source Code</a></p> <h4 style="text-align: justify;">Starting a new control</h4> <p style="text-align: justify;"><img width="337" height="104" title="Capture" style="margin: 0px; display: inline; float: right;" alt="Capture" src="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/_Capture_1.png" /> The set of controls of Silverlight is very wide and cover a lot of needs, so it is hard to find a missing control to show in this article. The inspiration comes from the new generation phones, which often include controls that are very innovative. I decided to try a port of the Special button switch that you have certainly appreciated by accessing an iPhone.</p> <p style="text-align: justify;">The figure shows two instances of a control, I will call Switch, one in the Checked state (the red one) and the other in the Unchecked state. You can change the state of the control acting two ways: clicking on the coloured area or dragging the thumb with the chevron in the direction you want. The beautiful of the control is that it shows an animation when you make a change in its state scrolling the thumb from a side to the other. </p> <p style="text-align: justify;">The control, as you can figure out, is a sort of ToggleButton, so we should start its building from this class. I choosed of starting from scratch implementing a ContentControl directly for two reasons. First of all I would want to make the example simple and basic, and secondly I noticed there isn't an easy way to implement the behavior I described using VisualStateManager. So let me start writing code:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Switch : ContentControl</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span>{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> Switch()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.DefaultStyleKey = <span style="color: #0000ff;">typeof</span>(Switch);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">In this snippet you see two basic concepts. My class inherits from ContentControl because I need to have some content, like a normal ToggleButton. This content is the label on the side or a more complex structure of objects. When you are starting a new control this is the first choice you have to make: Control (or something inheriting from Control) if the control is a leaf in the VisualTree. ContentControl if it can have a content. </p> <p style="text-align: justify;">On the other side you can see I given a value to the DefaultStyleKey property. This lets the runtime will search its template in a file we are about to add to the project. The file, called always  generic.xaml, must be in a folder called "Themes" in the root of the project that contains the control. Its purpose is containing the basic templates of all the controls in the assembly. So, Here is the initial generic.xaml</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">ResourceDictionary</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #ff0000;">xmlns</span><span style="color: #0000ff;">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #ff0000;">xmlns:x</span><span style="color: #0000ff;">="http://schemas.microsoft.com/winfx/2006/xaml"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #ff0000;">xmlns:local</span><span style="color: #0000ff;">="clr-namespace:SilverlightPlayground.ControlTemplates"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Style</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="local:Switch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Template"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ControlTemplate</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="local:Switch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="Auto"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="*"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Border</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #ff0000;">BorderThickness</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">BorderBrush</span><span style="color: #0000ff;">="Black"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #ff0000;">CornerRadius</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Stretch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Stretch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OnColumnElement"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="0*"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="Auto"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OffColumnElement"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="100*"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OnBackgroundElement"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="Red"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OffBackgroundElement"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="Green"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FF617584"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Thumb</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="ThumbElement"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="40"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ContentPresenter</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Right"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,0,5,0"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Style</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">ResourceDictionary</span><span style="color: #0000ff;">></span></pre> </div> </div> </div> <p style="text-align: justify;">This template creates the basic appearance of the control, as you have seen in the previous figure. It misses some important parts, but I will add something else in the following snippets. In the template I have a basic Grid that separates the label from the body of the control. The body is made of another grid with three columns. The size of the first and the last column will be changed to move the thumb from the left to the right or viceversa. In the template I also have a Thumb control, representing an element that can be dragged and a couple of rectangles that give the background color to the visible area. </p> <p style="text-align: justify;">Now we need to take some references to the elements we need to use for the animation. They are the Columns, the thumb and the coloured rectangles:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span>[TemplatePart(Name = Switch.ThumbElementName, Type = <span style="color: #0000ff;">typeof</span>(Thumb))]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span>[TemplatePart(Name = Switch.OnColumnElementName, Type = <span style="color: #0000ff;">typeof</span>(ColumnDefinition))]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span>[TemplatePart(Name = Switch.OffColumnElementName, Type = <span style="color: #0000ff;">typeof</span>(ColumnDefinition))]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span>[TemplatePart(Name = Switch.OnBackgroundElementName, Type = <span style="color: #0000ff;">typeof</span>(Shape))]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span>[TemplatePart(Name = Switch.OffBackgroundElementName, Type = <span style="color: #0000ff;">typeof</span>(Shape))]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Switch : ContentControl</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span>{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> ThumbElementName = <span style="color: #006080;">"ThumbElement"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> Thumb ThumbElement { get; set; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> OnColumnElementName = <span style="color: #006080;">"OnColumnElement"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> ColumnDefinition OnColumnElement { get; set; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> OffColumnElementName = <span style="color: #006080;">"OffColumnElement"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> ColumnDefinition OffColumnElement { get; set; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> OnBackgroundElementName = <span style="color: #006080;">"OnBackgroundElement"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> Shape OnBackgroundElement { get; set; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> OffBackgroundElementName = <span style="color: #006080;">"OffBackgroundElement"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> Shape OffBackgroundElement { get; set; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> Switch()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.DefaultStyleKey = <span style="color: #0000ff;">typeof</span>(Switch);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnApplyTemplate()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.ThumbElement = <span style="color: #0000ff;">this</span>.GetTemplateChild(Switch.ThumbElementName) <span style="color: #0000ff;">as</span> Thumb;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.ThrowIfMissing(<span style="color: #0000ff;">this</span>.ThumbElement, Switch.ThumbElementName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.OffColumnElement = <span style="color: #0000ff;">this</span>.GetTemplateChild(Switch.OffColumnElementName) <span style="color: #0000ff;">as</span> ColumnDefinition;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.ThrowIfMissing(<span style="color: #0000ff;">this</span>.OffColumnElement, Switch.OffColumnElementName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.OnColumnElement = <span style="color: #0000ff;">this</span>.GetTemplateChild(Switch.OnColumnElementName) <span style="color: #0000ff;">as</span> ColumnDefinition;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.ThrowIfMissing(<span style="color: #0000ff;">this</span>.OnColumnElement, Switch.OnColumnElementName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.OnBackgroundElement = <span style="color: #0000ff;">this</span>.GetTemplateChild(Switch.OnBackgroundElementName) <span style="color: #0000ff;">as</span> Shape;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.OffBackgroundElement = <span style="color: #0000ff;">this</span>.GetTemplateChild(Switch.OffBackgroundElementName) <span style="color: #0000ff;">as</span> Shape;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.UpdateVisualState();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum40" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum41" style="color: #606060;"> </span> <span style="color: #0000ff;">base</span>.OnApplyTemplate();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum42" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum43" style="color: #606060;"> </span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum44" style="color: #606060;"> </span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> UpdateVisualState()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum45" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum46" style="color: #606060;"> </span> <span style="color: #008000;">// update the control appearance here</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum48" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum49" style="color: #606060;"> </span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> ThrowIfMissing(DependencyObject element, <span style="color: #0000ff;">string</span> name)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum50" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum51" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (element == <span style="color: #0000ff;">null</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum52" style="color: #606060;"> </span> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> Exception(<span style="color: #0000ff;">string</span>.Format(<span style="color: #006080;">"Missing required element '{0}'"</span>, name));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum53" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum54" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">The OnApplyTemplate method is useful for this purpose. It is called in the initial phase of the life of the control and lets the developer to connect some elements of the control I have called "parts" in the previous article. An element is a "part" when it is attached in the OnApplyTemplate method and it is declared with the TemplatePart attribute at the top of the class. This attribute is not used by the runtime but is useful to external tools to detect the parts for design purpose. </p> <p style="text-align: justify;">Many times a part is optional and can be easily removed without causing an error in the control. Some other times it is required. The control has to handle both the cases. When a part is optional the logic have to gracefully skip it when its value is null. When a part is required the better thing to do is raising an exception during the OnApplyTemplate method, as I did in the ThrowIfMissing method. Remember that the more the parts are optional more your control will be customizable. And also when you choose a class to take a reference to a part choose always the closest to the root of the inheritance hierarchy that has all the methods and property you need to make it working.</p> <p style="text-align: justify;">Finally, UpdateVisualState is the method where the visual appearance of the control is updated every time a property changes its value. The method is useful every time there is something changed and it needs to be reflected into the UI. In my control, this method will starts an animation to move the thumb. This update is needed only when the IsChecked property (a dependency property) is changed and when the control is initialized to make it respectful of the current value of the same property. </p> <p style="text-align: justify;">In Silverlight there is not any way to animate a GridLenght property and this is the reason we need to create a custom animation to make the sliding. I create an empty storyboard and I use it as a timer to change the with of the colums, increasing one and decreasing the other. When the thumb has reached its position the animation is stopped:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> UpdateVisualState()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span>{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.SwitchStoryBoard.Begin();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span>}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> SwitchStoryBoard_Completed(<span style="color: #0000ff;">object</span> sender, EventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span>{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">this</span>.IsChecked)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.OffColumnElement.Width.Value == 100.0)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.SwitchStoryBoard.Stop();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;">else</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.OffColumnElement.Width = <span style="color: #0000ff;">new</span> GridLength(<span style="color: #0000ff;">this</span>.OffColumnElement.Width.Value + 10, GridUnitType.Star);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.OnColumnElement.Width = <span style="color: #0000ff;">new</span> GridLength(<span style="color: #0000ff;">this</span>.OnColumnElement.Width.Value - 10, GridUnitType.Star);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.SwitchStoryBoard.Begin();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;">else</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.OnColumnElement.Width.Value == 100.0)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.SwitchStoryBoard.Stop();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;">else</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.OnColumnElement.Width = <span style="color: #0000ff;">new</span> GridLength(<span style="color: #0000ff;">this</span>.OnColumnElement.Width.Value + 10, GridUnitType.Star);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.OffColumnElement.Width = <span style="color: #0000ff;">new</span> GridLength(<span style="color: #0000ff;">this</span>.OffColumnElement.Width.Value - 10, GridUnitType.Star);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.SwitchStoryBoard.Begin();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">Another thing to do, is to bind some properties of the template to the properties of the control. I used the TemplateBinding for the BorderBrush and BorderThickness, then I created two dependency properties in the control, OnBackground e OffBackground, to leave the user free of customizing the colors of the control. I used again the TemplateBinding, same way I did with the other properties. </p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">Style</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="local:Switch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="BorderThickness"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="1"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="OnBackground"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="#FFFF0000"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="OffBackground"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="#FF008800"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="BorderBrush"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">LinearGradientBrush</span> <span style="color: #ff0000;">EndPoint</span><span style="color: #0000ff;">="0.5,1"</span> <span style="color: #ff0000;">StartPoint</span><span style="color: #0000ff;">="0.5,0"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FFA3AEB9"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FF8399A9"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0.375"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FF718597"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0.375"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FF617584"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="1"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">LinearGradientBrush</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Template"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ControlTemplate</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="local:Switch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="Auto"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="*"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Border</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #ff0000;">BorderThickness</span><span style="color: #0000ff;">="<strong>{TemplateBinding BorderThickness}</strong>"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #ff0000;">BorderBrush</span><span style="color: #0000ff;">="<strong>{TemplateBinding BorderBrush}</strong>"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> <span style="color: #ff0000;">CornerRadius</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Stretch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Stretch"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OnColumnElement"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="0*"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="Auto"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OffColumnElement"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="100*"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OnBackgroundElement"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="<strong>{TemplateBinding OnBackground}</strong>"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="1.0"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OffBackgroundElement"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="<strong>{TemplateBinding OffBackground}</strong>"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="1.0"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FF617584"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Thumb</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="ThumbElement"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="40"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Path</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OffChevron"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Data</span><span style="color: #0000ff;">="M-5,-5 L6,3 L-5,11 L3,3 z"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> </span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FF617584"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="14,4"</span> <span style="color: #ff0000;">Stretch</span><span style="color: #0000ff;">="Fill"</span> <span style="color: #ff0000;">UseLayoutRounding</span><span style="color: #0000ff;">="False"</span><span> </span><span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="1.0"</span> <span style="color: #ff0000;">IsHitTestVisible</span><span style="color: #0000ff;">="False"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Path</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="OnChevron"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Data</span><span style="color: #0000ff;">="M6.114583,-5 L-2.25,3 L5.8854165,11 L-5,3 z"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum40" style="color: #606060;"> </span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FF617584"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="14,4"</span> <span style="color: #ff0000;">Stretch</span><span style="color: #0000ff;">="Fill"</span> <span style="color: #ff0000;">UseLayoutRounding</span><span style="color: #0000ff;">="False"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0.0"</span> <span style="color: #ff0000;">IsHitTestVisible</span><span style="color: #0000ff;">="False"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum41" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="DisabledVisualElement"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">ColumnSpan</span><span style="color: #0000ff;">="3"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum42" style="color: #606060;"> </span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0.0"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#eeFFFFFF"</span> <span style="color: #ff0000;">IsHitTestVisible</span><span style="color: #0000ff;">="False"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum43" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="ContentFocusVisualElement"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">ColumnSpan</span><span style="color: #0000ff;">="3"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="2"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum44" style="color: #606060;"> </span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="#FF6DBDD1"</span> <span style="color: #ff0000;">StrokeThickness</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">IsHitTestVisible</span><span style="color: #0000ff;">="false"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum45" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum46" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ContentPresenter</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Right"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,0,5,0"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum48" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum49" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum50" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum51" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum52" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">Style</span><span style="color: #0000ff;">></span></pre> </div> </div> </div> <p style="text-align: justify;">Using the Style this way is very comfortable because it lets the developer to define some default values for properties. In the Setter on top of the template I defined some colors, and attributes that the user can change, but they have defaults to prevent unexpected results.</p> <h4 style="text-align: justify;">The Visual States</h4> <p style="text-align: justify;">Now that the control works as expected, it is time to make it more customizable. This capability comes from the use of the VisualStateManager that is able to manage some state groups. First of all I added the couple Normal/Disabled but also the Focused and Unfocused status. While the first couple is implemented using a rectangle on top of all the other parts, the Focused status uses another rectangle to create a border around the control. </p> <p style="text-align: justify;">Another couple of styles, I've implemented, are Checked/Unchecked. Also if these conditions are showed by the sliding thumb the developer can find useful to have these statuses for the purpose of add some other effects. In my case I added a chevron that switches from left to right. Here is the code for the VisualStateManager:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateGroup</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="CommonStates"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Normal"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Disabled"</span> <span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DoubleAnimation</span> <span style="color: #ff0000;">Duration</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">To</span><span style="color: #0000ff;">="0.5"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Opacity)"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="DisabledVisualElement"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualState</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateGroup</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="FocusStates"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Unfocused"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Focused"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DoubleAnimation</span> <span style="color: #ff0000;">Duration</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">To</span><span style="color: #0000ff;">="1.0"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Opacity)"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="ContentFocusVisualElement"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualState</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateGroup</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="CheckStates"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Checked"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DoubleAnimation</span> <span style="color: #ff0000;">Duration</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">To</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Opacity)"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="OffChevron"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DoubleAnimation</span> <span style="color: #ff0000;">Duration</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">To</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Opacity)"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="OnChevron"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualState</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Unchecked"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DoubleAnimation</span> <span style="color: #ff0000;">Duration</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">To</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Opacity)"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="OffChevron"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DoubleAnimation</span> <span style="color: #ff0000;">Duration</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">To</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Opacity)"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="OnChevron"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualState</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">This chunk of code must be inserted in the root element of the ControlTemplate. As you can see, it defines some animations the runtime will show during the transition. The VSM is capable of interpolate all the possible transitions and due to this reason it is possible to not define all the transitions between states. </p> <p style="text-align: justify;">Once you have defined the states in the markup into the generic.xaml, you have two final things to do. You have to notify the VisualStateManager about the transitions from a state to another and you have to publish the available states using the TemplateState attribute as you already did with parts and the TemplatePart attribute. Starting by the last, the TemplateState attribute enables the graphics tools to know how many statuses they have to handle. </p> <p style="text-align: justify;">But what really matter is setting the state of the control because it enables the VisualStateManager to apply the defined animations and transitions. In an event handler you can simply call the GoToState static method on the VisualStateManager class. Here is and example:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> Switch_IsEnabledChanged(<span style="color: #0000ff;">object</span> sender, DependencyPropertyChangedEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span>{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.ThumbElement.IsEnabled = (<span style="color: #0000ff;">bool</span>)e.NewValue;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">this</span>.ThumbElement.IsEnabled != <span style="color: #0000ff;">true</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> VisualStateManager.GoToState(<span style="color: #0000ff;">this</span>, <span style="color: #006080;">"Disabled"</span>, <span style="color: #0000ff;">true</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">else</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> VisualStateManager.GoToState(<span style="color: #0000ff;">this</span>, <span style="color: #006080;">"Normal"</span>, <span style="color: #0000ff;">true</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span>}</pre> </div> </div> </div> <p style="text-align: justify;">This code sets the correct state according to the IsEnabled property value. The three arguments of the GoToState method are: </p> <ul> <li> <div style="text-align: justify;">The UIElement which you have to change the state</div> </li> <li> <div style="text-align: justify;">The destination state as you have called it in the markup</div> </li> <li> <div style="text-align: justify;">A boolean indicating if the transitions must be used or if the change must be immediate</div> </li> </ul> <h4 style="text-align: justify;">Template or not template?</h4> <p style="text-align: justify;">The process of creating a templated control may appear hard, but once you have understood how it works you will find there is not any reason to create controls without a template if they have an UI. Having the basic template expressed as xaml markup makes the development process more simple and straightforward then having to create parts in code. The trick, about control reusability, is to think at them always like behaviors and then add a default appearance, but remember not to close any way to future drastic changes.</p> http://www.silverlightshow.net/items/Understanding-control-customization-with-templates-part-2.aspx editorial@silverlightshow.net (Andrea Boschin ) http://www.silverlightshow.net/items/Understanding-control-customization-with-templates-part-2.aspx#comments http://www.silverlightshow.net/items/Understanding-control-customization-with-templates-part-2.aspx Thu, 15 Jul 2010 11:36:00 GMT Understanding control customization with templates: part #1 <p style="text-align: justify;"><em><span style="line-height: 115%; font-family: calibri, sans-serif; font-size: 11pt;"><strong>This article is compatible with the latest version of Silverlight.</strong></span></em></p> <p style="text-align: justify;"><em><span style="line-height: 115%; font-family: calibri, sans-serif; font-size: 11pt;"></span></em>Every Silverlight developer - and more extensively each Windows developer - knows what I mean with the term "Control". The term is referred to a reusable component that let the developer to add a known behavior to the user interface. The Silverlight plugin, the SDK and the Control's Toolkit have plenty of these controls, and we are used to put them into our application without any fear. Unfortunately, often their appearance is ugly and we may be tempted to change it someway, to give our application a fresh and unique look & feel. With Silverlight there are various degree of personalization you can apply to them, from the simple markup attribute, to an implicit style, but often we need a more deep and drastic revision. In these cases Silverlight grant a unique capability of changing the very inner structure of every control to bend it to our will.</p> <h4 style="text-align: justify;">Behavior versus Appearance</h4> <p style="text-align: justify;"><img width="198" height="211" title="Capture" style="margin: 0px 15px 0px 0px; display: inline; float: left;" alt="Capture" src="http://www.silverlightshow.net/Storage/Users/AndreaBoschin/Capture_1.png" /> </p> <p style="text-align: justify;">Given that the middle control in figure is a ToggleButton, what they have in common the three controls? At a superficial exam it may appear that the sole thing they have in common is the text "Select this option...". From an user experience point of view, the meaning they have in an user interface is someway different. But if you analyze them, from a developer perspective, you may agree they are perfectly equals. All the controls infact can be switched on or off and everyone has a label. So, the very important difference is not about the behavior but is about the aspect they have. And If you investigate deeply using Visual Studio you will understand that CheckBox and RadioButton are both inherited from ToggleButton, that is the root of this kind of controls. </p> <p style="text-align: justify;">In Silverlight, there is a clear distinction between the behavior and the aspect of every control, at least if the control is developed with a set of rules in mind, that make it a Templated Control. This distinction separates the work of two key figures in the development process: the developer and the designer. Both these figures have different roles in the team and often the requirements of the first are totally opposite to the other's. </p> <p style="text-align: justify;">I'm a developer, and when I put a CheckBox in the interface I'm acquiring a behavior to my application. I simply need that someone can choose if the user needs to activate or not an option. Nothing else. At the opposite, when a designer looks at the same interface it does not matter what the control does, but his main concern is its appearance, to make the application not only beautiful, but also more easily understandable and usable.</p> <h4 style="text-align: justify;">Templated controls.</h4> <p style="text-align: justify;">In one of the last sentences, I used the term "templated control". First of all you have to know that all the controls in the Silverlight core, in the SDK and in the Control's Toolkit are fundamentally Templated Controls. But what does this mean? </p> <p style="text-align: justify;">In every control you can detect some fixed parts, and some other parts that can be changed by the developer. In the CheckBox you have a Content property that let you change the label, but you can customize colors, borders, and many other properties. If you think at the inner structure of a the checkbox, made of simple shapes held toghether by some layout elements, you understand that changing a property of the control means changing one or more property of one or more shapes in this structure. This "structure" is called "ControlTemplate", because of the fact you can think at it as a placeholder for properties you can change and parts you can add. The template appearance will remain the same across different instances of the control but the label can change its content, the border its thickness and so on. Obviously you can create your own Templated Controls, but this is matter for the next part of the article. In this paragraphs you will learn how to customize the template and deeply change the appearance of the existing controls.</p> <p style="text-align: justify;">Until now I said that every control has a template, but I never tried to explain where this template is located. So, if you watch to the properties of a CheckBox you will easily find a Template property, and this is the location where an instance of ControlTemplate class retain the appearance of the control. Now, please point your browser to Google and type "silverlight control styles and templates" and hit "I'm feeling lucky". The first link of the search probably will take you to this page: <a href="http://msdn.microsoft.com/en-us/library/cc278075(VS.95).aspx">http://msdn.microsoft.com/en-us/library/cc278075(VS.95).aspx</a>. Here you can find a complete list of the Controls in Silverlight and a link to a page containig the original template of every control. Hit CheckBox Style and Templates and you will be revealed the whole template behind the CheckBox. Probably something like this:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">ControlTemplate</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="CheckBox"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="16"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="*"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Top"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Background"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="14"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="14"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="{TemplateBinding BorderBrush}"</span> <span style="color: #ff0000;">StrokeThickness</span><span style="color: #0000ff;">="{TemplateBinding BorderThickness}"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FFFFFFFF"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="1"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="BackgroundOverlay"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FFC4DBEE"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="14"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="14"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">StrokeThickness</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="#00000000"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="BoxMiddleBackground"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="{TemplateBinding Background}"</span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="#00000000"</span> <span style="color: #ff0000;">StrokeThickness</span><span style="color: #0000ff;">="1"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="BoxMiddle"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">StrokeThickness</span><span style="color: #0000ff;">="1"</span> <span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle.Stroke</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">LinearGradientBrush</span> <span style="color: #ff0000;">EndPoint</span><span style="color: #0000ff;">=".5,1"</span> <span style="color: #ff0000;">StartPoint</span><span style="color: #0000ff;">=".5,0"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FFFFFFFF"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="1"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FFFFFFFF"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FFFFFFFF"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0.375"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FFFFFFFF"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0.375"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">LinearGradientBrush</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Rectangle.Stroke</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle.Fill</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">LinearGradientBrush</span> <span style="color: #ff0000;">StartPoint</span><span style="color: #0000ff;">="0.62,0.15"</span> <span style="color: #ff0000;">EndPoint</span><span style="color: #0000ff;">="0.64,0.88"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#FFFFFFFF"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0.013"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#F9FFFFFF"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0.375"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#EAFFFFFF"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="0.603"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GradientStop</span> <span style="color: #ff0000;">Color</span><span style="color: #0000ff;">="#D8FFFFFF"</span> <span style="color: #ff0000;">Offset</span><span style="color: #0000ff;">="1"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">LinearGradientBrush</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Rectangle.Fill</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Rectangle</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="BoxMiddleLine"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="{TemplateBinding BorderBrush}"</span> <span style="color: #ff0000;">StrokeThickness</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">=".2"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Path</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="CheckIcon"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="1,1,0,1.5"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FF333333"</span> <span style="color: #ff0000;">Stretch</span><span style="color: #0000ff;">="Fill"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="10.5"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">Data</span><span style="color: #0000ff;">="M102.03442,598.79645 L105.22962,597.78918 L106.78825,600.42358 C106.78825,600.42358 108.51028,595.74304 110.21724,593.60419 C112.00967,591.35822 114.89314,591.42316 114.89314,591.42316 C114.89314,591.42316 112.67844,593.42645 111.93174,594.44464 C110.7449,596.06293 107.15683,604.13837 107.15683,604.13837 z"</span> <span style="color: #ff0000;">FlowDirection</span><span style="color: #0000ff;">="LeftToRight"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="IndeterminateIcon"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FF333333"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="6"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="DisabledVisualElement"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="14"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="14"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FFFFFFFF"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="ContentFocusVisualElement"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="#FF6DBDD1"</span> <span style="color: #ff0000;">StrokeThickness</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">IsHitTestVisible</span><span style="color: #0000ff;">="false"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="16"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="16"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Border</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="ValidationErrorElement"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">BorderThickness</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">CornerRadius</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">BorderBrush</span><span style="color: #0000ff;">="#FFDB000C"</span> <span style="color: #ff0000;">Visibility</span><span style="color: #0000ff;">="Collapsed"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> </span> <span style="color: #ff0000;">ToolTipService</span>.<span style="color: #ff0000;">PlacementTarget</span><span style="color: #0000ff;">="{Binding RelativeSource={RelativeSource TemplatedParent}}"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ToolTipService.ToolTip</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ToolTip</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="validationTooltip"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> </span> <span style="color: #ff0000;">Template</span><span style="color: #0000ff;">="{StaticResource ValidationToolTipTemplate}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum40" style="color: #606060;"> </span> <span style="color: #ff0000;">DataContext</span><span style="color: #0000ff;">="{Binding RelativeSource={RelativeSource TemplatedParent}}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum41" style="color: #606060;"> </span> <span style="color: #ff0000;">Placement</span><span style="color: #0000ff;">="Right"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum42" style="color: #606060;"> </span> <span style="color: #ff0000;">PlacementTarget</span><span style="color: #0000ff;">="{Binding RelativeSource={RelativeSource TemplatedParent}}"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum43" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ToolTip.Triggers</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum44" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">EventTrigger</span> <span style="color: #ff0000;">RoutedEvent</span><span style="color: #0000ff;">="Canvas.Loaded"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum45" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">EventTrigger.Actions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum46" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">BeginStoryboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum48" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ObjectAnimationUsingKeyFrames</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="validationTooltip"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="IsHitTestVisible"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum49" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DiscreteObjectKeyFrame</span> <span style="color: #ff0000;">KeyTime</span><span style="color: #0000ff;">="0"</span> <span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum50" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DiscreteObjectKeyFrame.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum51" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">sys:Boolean</span><span style="color: #0000ff;">></span>true<span style="color: #0000ff;"></</span><span style="color: #800000;">sys:Boolean</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum52" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DiscreteObjectKeyFrame.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum53" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">DiscreteObjectKeyFrame</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum54" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ObjectAnimationUsingKeyFrames</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum55" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum56" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">BeginStoryboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum57" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">EventTrigger.Actions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum58" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">EventTrigger</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum59" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ToolTip.Triggers</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum60" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ToolTip</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum61" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ToolTipService.ToolTip</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum62" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="10"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Right"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,-4,-4,0"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Top"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="Transparent"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum63" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Path</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,3,0,0"</span> <span style="color: #ff0000;">Data</span><span style="color: #0000ff;">="M 1,0 L5,0 A 2,2 90 0 1 7,2 L7,6 z"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#FFDC000C"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum64" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Path</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,3,0,0"</span> <span style="color: #ff0000;">Data</span><span style="color: #0000ff;">="M 0,0 L2,0 L 7,5 L7,7"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="#ffffff"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum65" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum66" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum67" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum68" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ContentPresenter</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum69" style="color: #606060;"> </span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum70" style="color: #606060;"> </span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="contentPresenter"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum71" style="color: #606060;"> </span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="{TemplateBinding Content}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum72" style="color: #606060;"> </span> <span style="color: #ff0000;">ContentTemplate</span><span style="color: #0000ff;">="{TemplateBinding ContentTemplate}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum73" style="color: #606060;"> </span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="{TemplateBinding HorizontalContentAlignment}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum74" style="color: #606060;"> </span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="{TemplateBinding VerticalContentAlignment}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum75" style="color: #606060;"> </span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="{TemplateBinding Padding}"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum76" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum77" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">In the snippet, I've removed some parts of the template, related to the Visual State Manager, to shorten the code and concentrate our attention on the appearance of the control. If you are experienced in XAML you will understand the anatomy of the control, but the better is oversimplify it and change the control with our own template: Here is a shorter XAML snippet:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="20"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="*"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="#FF666666"</span> <span style="color: #ff0000;">StrokeThickness</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">ColumnSpan</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="WhiteSmoke"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="CheckIcon"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="Orange"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="1,1,0,1"</span> <span style="color: #ff0000;">Stretch</span><span style="color: #0000ff;">="Fill"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="1.0"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ContentPresenter</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="contentPresenter"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="3"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">In the first element I declare a ControlTemplate. This element can be inserted directly into the Template property of the control or better added to a Style that we can apply to multiple controls. The inner content is the root of the template of the control and it is easy to understand the new checkbox will appear as a rectangle with an orange section used as selection indicator. The important part is the ContentPresenter control. This kind of control is useful to indicate where the value of the Content property has to be put. It is a real placeholder that will be filled with the sentence "Select this option..." or with something else you can write in the markup. </p> <p style="text-align: justify;">A template may have some "parts", that are particular elements, referenced by the underlying class. The checkbox does not declare any parts, but often there is the need of attaching events to an element so, the developer give it a name, and the element becomes a "part". Watch the page "Slider Styles and Templates" for a real example of some parts. The slider has many parts, and as you can understand they are required to get the user interaction and change the values. </p> <p style="text-align: justify;">What you have to be concerned about the parts is that you have never to change its name and its underlying type. The pages of MSDN accurately describe the names and the types of the parts, so if you find a part is declared "Button" you can use only a Button, but if the same part is declared as ButtonBase you can use indifferently a Button or an HyperlinkButton because both derive from ButtonBase.</p> <p style="text-align: justify;">Once you defined the new appearance of the control there is another need you can have. In my example you may want to change the color and thickness of the border or some other properties without creating different templates for each combination. You probably expect to put the new color in the BorderBrush property of the CheckBox and have the border changed. To allow this you have to create a binding between the property of the control and one or more properties in the template. For this purpose you have to use the TemplateBinding markup extension:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="20"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="*"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="<strong>{TemplateBinding BorderBrush}</strong>"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="<strong>{TemplateBinding Background}</strong>"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">ColumnSpan</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="2"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="CheckIcon"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="Orange"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="1,1,0,1"</span> <span style="color: #ff0000;">Stretch</span><span style="color: #0000ff;">="Fill"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="1.0"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ContentPresenter</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="contentPresenter"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="3"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> </div> <p style="text-align: justify;">The TemplateBinding creates a sort of link between two properties. You only have to be sure both the properties have the same type. Also if this may appear similar to the Binding markup extension, the TemplateBinding is very limited in Silverlight. It has not any Converter property and cannot use anything else the a property name, but it is equally useful to spare time when reusing a template you created.</p> <h4 style="text-align: justify;">Managing states</h4> <p style="text-align: justify;">If you run the project after assigning the template I wrote in the previous box you will remain deluded. The new CheckBox has a new appearance but it does not work anymore. It is become a shape on the plugin surface and is unable to react to the user interaction. The problem is that we have not defined what in the control have to change to react at the various states it might assume. With "state" I mean Checked or Unchecked, Hover or Normal, Focused or disabled. Each state changes some properties of the template and gives a feedback to the user. In the page "CheckBox Styles and Templates" you will find a table containing all the states of the CheckBox. They are managed by a component called VisualStateManger that is responsible of maintaining a number of state groups and track the current. You can put an entire section describing how a state must appear and every state is represented by one or more animations. The great thing is that you only have to be concerned about how an animation must change the appearance, and the VSM will interpolate all the transitions to the states. So, let me add a state to my checkbox template:</p> <div style="text-align: justify;"> <div id="codeSnippetWrapper" style="text-align: left; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px;border: silver 1px solid;"> <div id="codeSnippet" style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="20"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="*"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualStateGroup</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="CheckStates"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Checked"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">DoubleAnimation</span> <span style="color: #ff0000;">Duration</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">To</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetProperty</span><span style="color: #0000ff;">="(UIElement.Opacity)"</span> <span style="color: #ff0000;">Storyboard</span>.<span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="CheckIcon"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Storyboard</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualState</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">VisualState</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="Unchecked"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateGroup</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">VisualStateManager.VisualStateGroups</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">Stroke</span><span style="color: #0000ff;">="{TemplateBinding BorderBrush}"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="{TemplateBinding Background}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">ColumnSpan</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="2"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="CheckIcon"</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="Orange"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="1,1,0,1"</span> <span style="color: #ff0000;">Stretch</span><span style="color: #0000ff;">="Fill"</span> <span style="color: #ff0000;">Opacity</span><span style="color: #0000ff;">="0"</span> <span style="color: #ff0000;">RadiusX</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">RadiusY</span><span style="color: #0000ff;">="1"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ContentPresenter</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="contentPresenter"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="3"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">ControlTemplate</span><span style="color: #0000ff;">></span></pre> </div> </div> </div> <p style="text-align: justify;">As you can see I've added an animation, for the Checked state, that animates the Opacity property of the Orange rectangle in the middle of the checkbox . I have not added an animation to the Unchecked state and this mean the VSM will make the transition from Opacity = 1.0 to Opacity = 0.0 when the control move to the uncheked state. If you run the sample you will see the orange rectangle appear when you hit the control.</p> <h4 style="text-align: justify;">Good to know but...</h4> <p style="text-align: justify;">What I've described in these rows is for sure very interesting for people that need a deep customization of controls appearance. But probably, you are now concerned about the complex syntax you have to use and learn. The good news is that Blend, since the release 3.0, is your friend when editing templates. When you are developing an application the better is having a tools that supports template editing. Blend is very powerful and let you manage the constituting elements of the templates but also the states in a very simple way. Learning about how to customize the templates manually is really interesting, but it is only the starting point for the next step: build your own templated controls.</p> http://www.silverlightshow.net/items/Understanding-control-customization-with-templates-part-1.aspx editorial@silverlightshow.net (Andrea Boschin ) http://www.silverlightshow.net/items/Understanding-control-customization-with-templates-part-1.aspx#comments http://www.silverlightshow.net/items/Understanding-control-customization-with-templates-part-1.aspx Mon, 12 Jul 2010 02:31:00 GMT A Designer-friendly Approach to MVVM <h3><em><span style="font-size: 11pt; line-height: 115%; font-family: calibri, sans-serif;"><strong>This article is compatible with the latest version of Silverlight.</strong></span></em></h3> <div><em><span style="font-size: 11pt; line-height: 115%; font-family: calibri, sans-serif;"><strong><br /> </strong></span></em></div> <h3>Introduction</h3> <p>If you work with Silverlight or WPF, you have probably met the phrase “MVVM”. Almost everyone who is anyone in the WPF / Silverlight scene has their own MVVM framework, and their own way of explaining and teaching MVVM. Scary terms like IoC, Dependency Injection, Commanding Frameworks, Event Aggregators, Unit Testing, etc just roll off the tongue of the MVVM experts. This is one of the reasons why MVVM is intimidating for a lot of people. Still, you can create perfectly valid MVVM applications without even knowing what those terms mean. This post will show you my approach to MVVM, which is hopefully simple enough to get you started.</p> <p>So, what is MVVM? There are tons of blog posts on the topic on the net - for example, take a look at John Papa’s <a href="http://johnpapa.net/silverlight/5-minute-overview-of-mvvm-in-silverlight/">5 Minute Overview of MVVM in Silverlight</a>. I won’t go into details, but here is my very short summary:</p> <ul> <li>MVVM allows for real separation between logic and presentation (or developer and designer). </li> <li>Model is the data that is displayed in the application. Model is created by a developer. </li> <li>View is the User Interface, that is defined in XAML (mostly). View is the responsibility of a designer. </li> <li>ViewModel is the logic behind the UI, it handles data retrieval and manipulation, follows the state of the application (such as whether the user has logged on or not). The ViewModel is owned by the developer, and is present in the View as the DataContext. </li> </ul> <p>From our perspective, the interesting part is how the View and the ViewModel are communicating. There are two components to this: <strong>databinding</strong> (synchronizing data between the View and the ViewModel) and <strong>commanding</strong> – which is essentially a mechanism that allows the View to notify the ViewModel when user interaction has happened. </p> <p><strong>Databinding </strong>in Silverlight and WPF is pretty powerful. In my mind, the Zen of WPF and Silverlight development is:</p> <p><em>“Get the data to be displayed to the client, and trust databinding and XAML – the designer - to do the rest”.</em></p> <p>Similarly, the Zen of WPF and Silverlight design is:</p> <p><em>“No matter how you want to display the data for the user, XAML and databinding can probably handle it. Only ask a developer to help you after you have tried really hard.”</em></p> <p>On the other hand, I always had a bad taste in the mouth when it comes to the commanding facilities of Silverlight. Commanding has two key features:</p> <ul> <li>Notify the ViewModel if something (usually a user interaction) happens in the View </li> <li>Disable UI elements when a command is not available (for example, the save button, icons, etc should be disabled if the user does not have the right to modify an item). </li> </ul> <p>Here is why I don’t like commanding:</p> <ul> <li>For the designer to be able select a command in Blend, the developer has to create a lot of code – and usually that code simply invokes a method. There is RelayCommand and DelegateCommand to help with this though. </li> <li>The biggest issue I have with commanding is that it really ties the hand of the designer. What if I don’t just want to disable the Save button, I want to change its text to “Login first to Save”? What if I am a crazy designer and want to have all the buttons fly in from outside the screen when the user has logged in and is authorized to press them? </li> <li>Also, the CanExecute approach can be tedious for the developer. For example, after logging in, you have to re-evaluate pretty much all commands, and call CanExecuteChanged for all of them. For complicated tasks, when there are tons of commands, and their executability (is there such a word) is driven by database settings, the built-in approach may be the right one. But for simpler software, this can be overkill. </li> </ul> <h3>The key goals of my MVVM approach</h3> <p>For the project itself:</p> <ul> <li>Total separation of the designer and developer workflows </li> <li>Shallow learning curve for both the designer and the developer </li> <li>Allowing both the designer and the developer to remain in their comfort zone, and only use the tools they are familiar with </li> <li>Approachable solution for projects with low or medium complexity </li> </ul> <p>For the designer: </p> <ul> <li>As much Blend support as possible (this is not totally achieved yet due to limitations in Blend 3) </li> <li>Use of Visual States to reflect different states of the application </li> <li>High level of flexibility </li> <li>Almost everything can be done in Blend and XAML </li> <li>Shallow learning curve: there is only an Action and a Behavior to learn about </li> <li>Create modern UI, including animations, transitions, custom skins, etc. </li> </ul> <p>For the developer:</p> <ul> <li>Focus only on coding </li> <li>Display logic (ViewModel) code is unit testable, including user actions </li> <li>Application states can be expressed naturally, via enum values </li> <li>Ability to include techniques from other MVVM approaches, such as the <a href="http://www.galasoft.ch/mvvm/getstarted/" target="_blank">MVVM Light Toolkit</a> </li> </ul> <h3>So, what do I do instead of commanding?</h3> <p>I use an Action and a Behavior. The Action is for calling methods in the DataContext (that is, the ViewModel). It works similar to the CallDataMethod Action in the <a href="http://expressionblend.codeplex.com/" target="_blank">Expression Blend Samples</a> project.</p> <h2>The CallDataContextMethodAction</h2> <p>In the attached sample project, there is a TextBox and a Button to illustrate the basic functionality of the CallDataContextMethodAction. The TextBlock is bound to the Message property of the ViewModel, and the Button has the CallDataContextMethodAction applied to it, with the method name set to ShowMsgBox.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image3.png"><img width="389" height="107" title="image" style="display: inline;border-width: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image3_thumb.png" /></a> </p> <p>Here is the relevant part of the ViewModel (which is set to be the DataContext of the entire form):</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> </span><span class="kwrd">public</span> <span class="kwrd">string</span> Message { get; set; }</pre> <pre><span class="lnum"> </span> </pre> <pre class="alt"><span class="lnum"> </span><span class="kwrd">public</span> <span class="kwrd">void</span> ShowMsgBox()</pre> <pre><span class="lnum"> </span>{</pre> <pre class="alt"><span class="lnum"> </span> <span class="kwrd">if</span> (Message == <span class="kwrd">null</span>)</pre> <pre><span class="lnum"> </span> MessageBox.Show(<span class="str">"Enter something in the textbox"</span>);</pre> <pre class="alt"><span class="lnum"> </span> <span class="kwrd">else</span></pre> <pre><span class="lnum"> </span> MessageBox.Show(Message);</pre> <pre class="alt"><span class="lnum"> </span>}</pre> </div> <p>Here is our Action in Blend:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_6.png"><img width="424" height="289" title="image" style="border:0px solid; display: inline;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_thumb_2.png" /></a> </p> <p>If the Button is pressed, a MessageBox is shown, with the text entered into the TextBox:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_2.png"><img width="244" height="184" title="image" style="border:0px solid; display: inline;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_thumb.png" /></a> </p> <p><em>Note: You shouldn’t show a MessageBox from a ViewModel because the designer has no way of modifying what it looks like and how it behaves. However, this is just a test application, and the message boxes are only here to illustrate that the ViewModel actually received the call</em></p> <p>So far, it is pretty trivial. What is new in the CallDataContextMethodAction is that it can handle collections pretty well, too. As Glenn Block said in his excellent article <a href="http://codebetter.com/blogs/glenn.block/archive/2009/08/02/the-spirit-of-mvvm-viewmodel-it-s-not-a-code-counting-exercise.aspx">The spirit of MVVM (ViewModel), it’s not a code counting exercise, </a>you usually do not need to have parameters for commands. But there are some circumstances when you cannot avoid parameters, Consider the “Greetings to” list in the above picture. We want to display a greeting message for the person the user has clicked on. If the names are displayed in a ListBox, you can bind the SelectedItem property of the ListBox to a ViewModel property, and call the GreetPerson method by capturing the SelectionChanged event (there is a pretty handy EventTrigger built into Blend to help you with this). But then clicking on the same name again won’t fire the SelectionChanged event one more time. Also, what if the designer uses an ItemsControl instead of a ListBox? What if we want to greet the person not by clicking, but by doing some other, non-selective gesture? In this case, we have to have the GreetPerson method either on the person’s ViewModel, or some way to let the main ViewModel know which person we need to greet.</p> <p>Here is the relevant code in the ViewModel (note that there is no SelectedItem as the names are displayed in a simple ItemsControl):</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> </span><span class="kwrd">public</span> MyViewModel()</pre> <pre><span class="lnum"> </span>{</pre> <pre class="alt"><span class="lnum"> </span> Names = <span class="kwrd">new</span> ObservableCollection<<span class="kwrd">string</span>> {<span class="str">"John"</span>, <span class="str">"Smith"</span>, <span class="str">"Toby"</span>, <span class="str">"Emily"</span>};</pre> <pre><span class="lnum"> </span> SG1 = PanelState.On;</pre> <pre class="alt"><span class="lnum"> </span>}</pre> <pre><span class="lnum"> </span> </pre> <pre class="alt"><span class="lnum"> </span><span class="kwrd">public</span> <span class="kwrd">void</span> GreetPerson(<span class="kwrd">string</span> name)</pre> <pre><span class="lnum"> </span>{</pre> <pre class="alt"><span class="lnum"> </span> MessageBox.Show(<span class="str">"Hello, "</span> + name);</pre> <pre><span class="lnum"> </span>}</pre> </div> <style type="text/css"> .csharpcode { BACKGROUND-COLOR: #ffffff; FONT-FAMILY: consolas, "Courier New", courier, monospace; COLOR: black; FONT-SIZE: small } .csharpcode PRE { BACKGROUND-COLOR: #ffffff; FONT-FAMILY: consolas, "Courier New", courier, monospace; COLOR: black; FONT-SIZE: small } .csharpcode PRE { 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; MARGIN: 0em; WIDTH: 100% } .csharpcode .lnum { COLOR: #606060 } </style> <p>The Action is now attached to the ItemTemplate:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_8.png"><img width="421" height="259" title="image" style="border:0px solid; display: inline;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_thumb_3.png" /></a> </p> <p>But the items displayed in the ItemsControl are strings, and therefore the DataContext of the TextBlock is also a string. And a string does not have a GreetPerson method, so how does the Action work in this case? When the Action cannot find a method in the DataContext of the AssociatedObject (the element the Action is attached to, in our case, the TextBlock displaying the name), it tries to find the same method in the parent of the AssociatedObject, and its parent and so on. If such a method is found in the parent, it passes the DataContext (ViewModel) of the AssociatedObject to the parent method. By traveling up the VisualTree, we get to the MainPage, where the DataContext is the MyViewModel class shown above. This class has a GreetPerson method, so that method gets called. The GreetPerson method also has a parameter of string – this will be the DataContext of the TextBlock, thus the name of the person to be greeted. Note, that with CallDataContextMethodAction, we could use a strongly typed parameter for the method, unlike in the case of Commands where the parameter has to be an object.</p> <p>The big drawback of the CallDataContectMethodAction is that the name of the Method has to be typed in by the designer, thus it introduces the possibility of human error. Hopefully, we will be able to extend the design time experience later on, so that the developer can simply select the Method from a list instead of typing its name.</p> <h2>The VSMChangerBehavior</h2> <p>The other piece of the puzzle is the VSMChangerBehavior. It ties enum values in the ViewModel to Visual States in the View. As VisualStateGroups are orthogonal (meaning each group can be in any state regardless of what states the others are in), this is a very powerful means of visually reflecting the internal states the ViewModel is in. Here is an example:</p> <p>Suppose we have two panels that we want to show depending on various ViewModel calculations. We have an enum type of PanelState:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">enum</span> PanelState { Off, On }</pre> <style type="text/css"> .csharpcode { BACKGROUND-COLOR: #ffffff; FONT-FAMILY: consolas, "Courier New", courier, monospace; COLOR: black; FONT-SIZE: small } .csharpcode PRE { BACKGROUND-COLOR: #ffffff; FONT-FAMILY: consolas, "Courier New", courier, monospace; COLOR: black; FONT-SIZE: small } .csharpcode PRE { 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; MARGIN: 0em; WIDTH: 100% } .csharpcode .lnum { COLOR: #606060 } </style> <p> And here are the two enums:</p> <div class="csharpcode"> <pre><span class="lnum"> </span>[VisualStateGroup]</pre> <pre><span class="lnum"> </span><span class="kwrd">public</span> PanelState Panel1</pre> <pre><span class="lnum"> </span>{</pre> <pre><span class="lnum"> </span> get { <span class="kwrd">return</span> _panel1; }</pre> <pre><span class="lnum"> </span> set</pre> <pre><span class="lnum"> </span> {</pre> <pre><span class="lnum"> </span> _panel1 = <span class="kwrd">value</span>;</pre> <pre><span class="lnum"> </span> FirePropertyChanged(<span class="str">"Panel1"</span>);</pre> <pre><span class="lnum"> </span> }</pre> <pre><span class="lnum"> </span>}</pre> <pre><span class="lnum"> </span> </pre> <pre><span class="lnum"> </span>[VisualStateGroup]</pre> <pre><span class="lnum"> </span><span class="kwrd">public</span> PanelState Panel2</pre> <pre><span class="lnum"> </span>{</pre> <pre><span class="lnum"> </span> get { <span class="kwrd">return</span> _panel2; }</pre> <pre><span class="lnum"> </span> set</pre> <pre><span class="lnum"> </span> {</pre> <pre><span class="lnum"> </span> _panel2 = <span class="kwrd">value</span>;</pre> <pre><span class="lnum"> </span> FirePropertyChanged(<span class="str">"Panel2"</span>);</pre> <pre><span class="lnum"> </span> }</pre> <pre><span class="lnum"> </span>}</pre> </div> <p>For both panels (Panel1 and Panel2) we have their own properties of type PanelState, that fire the PropertyChanged event when set. However, we are using the [VisualStateGroup] attribute to mark these enums as ones that have (or should have) a VisualStateGroup counterpart. Here is what the visual states look in Blend:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_10.png"><img width="244" height="233" title="image" style="display: inline;border-width: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_thumb_4.png" /></a> </p> <p>As you can see, we have a VisualStateGroup for each PanelState property, The states themselves are called Panel1_On, Panel1_Off, Panel2_On, Panel2_Off. These state names are calculated by concatenating the enum property’s name (which has the VisualStateGroup attribute), an underscore and the name of the enum value:</p> <p><PropertyName>_<ValueName>. </p> <p>After this has been set up, all we have to do is to add the VSMChanger behavior to the Control that has the states we would like to change from the ViewModel:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_12.png"><img width="244" height="118" title="image" style="display: inline;border-width: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_thumb_5.png" /></a> </p> <p>From this point on, the behavior automatically changes the visual state of the UserControl as the enum values change within the ViewModel. This even includes state changes where the change is animated, as in the case in this simple demo. However, when the state transition is not instantaneous, the developer of the ViewModel may want to be notified when the transition has finished. For this, VSMChangerBehavior includes a callback mechanism. Simply name your callback method <PropertyName>TransitionComplete, and the method gets called when the transition has finished. For example, to show a MessageBox whenever Panel2 has been completely shown or hidden, have this in the ViewModel:</p> <div class="csharpcode"> <pre><span class="lnum"> </span><span class="kwrd">public</span> <span class="kwrd">void</span> Panel2TransitionComplete()</pre> <pre><span class="lnum"> </span>{</pre> <pre><span class="lnum"> </span> MessageBox.Show(<span class="str">"Panel2 Transition complete"</span>);</pre> <pre><span class="lnum"> </span>}</pre> </div> <style type="text/css"> .csharpcode { BACKGROUND-COLOR: #ffffff; FONT-FAMILY: consolas, "Courier New", courier, monospace; COLOR: black; FONT-SIZE: small } .csharpcode PRE { BACKGROUND-COLOR: #ffffff; FONT-FAMILY: consolas, "Courier New", courier, monospace; COLOR: black; FONT-SIZE: small } .csharpcode PRE { 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; MARGIN: 0em; WIDTH: 100% } .csharpcode .lnum { COLOR: #606060 } </style> <p>There is one big problem with this behavior, though. Just like in the case of the CallDataContextmethodAction, the designer has to type in the names of the visual states groups and states. As we are wiring up things based on convention, If he/she makes a mistake, the state change will not happen. To help ease this pain, I have added a “VerboseInitialization” property to the behavior.</p> <p>If it is on, the behavior will write detailed information to the output stream (unfortunately this stream can only be viewed from Visual Studio):</p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_14.png"><img width="724" height="118" title="image" style="display: inline;border-width: 0px;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_thumb_6.png" /></a> </p> <p>This should help debugging typos and missing states / groups until I figure out how to bend Blend to my will add add a proper designer experience for this behavior.</p> <h3></h3> <h3>Summary</h3> <p>So, there you have it. A designer-friendly way to wire up the View and the ViewModel. User gestures can be turned into commands via the CallDataContextMethodAction, and internal states and state changes of the ViewModel can be easily reflected via the VSMChangerBehavior. The later can also be used to disable / enable / hide UI elements in a declarative way that gives much more freedom to the designer than the CanExecute approach. Please let me know what you think in the comments! </p> <p>You can download the solution with code <a href="http://www.silverlightshow.net/Storage/Sources/DesignerFriendlyMVVM.zip">here</a>. You are free to do whatever you want with it, except say it is yours :)</p> http://www.silverlightshow.net/items/A-Designer-friendly-Approach-to-MVVM-Part-I.aspx editorial@silverlightshow.net (András Velvárt ) http://www.silverlightshow.net/items/A-Designer-friendly-Approach-to-MVVM-Part-I.aspx#comments http://www.silverlightshow.net/items/A-Designer-friendly-Approach-to-MVVM-Part-I.aspx Fri, 12 Mar 2010 10:04:00 GMT Transforming an Ugly Duckling into a Graceful Swan With Expression Blend and Silverlight - Part 2 Intro Animation <p>This is part<strong> 2</strong><strong> </strong><strong>of the series “Transforming an Ugly Duckling to a Graceful Swan with Expression Blend and Silverlight”.</strong></p> <h3>Introduction</h3> <p>In the <a href="http://www.silverlightshow.net/items/Transforming-an-Ugly-Duckling-to-a-Graceful-Swan-with-Expression-Blend-and-Silverlight-Part-I.aspx" target="_blank">first part of the series</a>, I introduced the application, and created the “ugly duckling” version, where the end user could already browse the and watch the videos. In this part, I am going to add some bling to the app – namely the Intro animation, the ability to skip it, and to replay it. The Intro animation itself is not created with Silverlight, so I will just use it as a video. This part takes heavy use of Visual States, Behaviors and Easings. </p> <h2></h2> <h2></h2> <h2>Visual States</h2> <p>The application builds on Sample Data for displaying the videos’ metadata, and it uses Visual States to differentiate between the states of the application. For example, Visual States are used to show the intro animation, the details (in a later screencast), buffering states, some mouseover effects, and so on.</p> <h2>Behaviors</h2> <p>Expression Blend 3 introduced the concept of Behaviors, Actions and Triggers (commonly called Behaviors). Behaviors are a way to empower designers to add functionality to the application without the need to write code. Of course, Behaviors are actually code written by developers, but they can be reused from project to project, and they can have parameters that help designers fine tune the behavior of Behaviors, and increase reusability. </p> <p>In this part (and the entire project in fact), I am using quite a lot of behaviors. The ones used in this screencast are:</p> <ul> <li><strong>GotoStateAction</strong> – Built into Blend, this Action makes the target user control to a specified Visual State. In the screencast it is used to get the application to start up in the "PlayingIntro” state, switch back to the PostIntroUIState, skip the intro and when the mouse is hovered over the “Replay intro” cube. </li> <li>Rick Keeney’s <a href="http://gallery.expression.microsoft.com/en-us/EndCueTrigger" target="_blank">EndCueTrigger</a> to trigger a state change 2 seconds before the intro animation ends </li> <li><strong>MediaElementStateToVSMBehavior</strong> – This behavior can be attached to a MediaElement, and as the playback state of the MediaElement changes (for example, there are states like “Opening”, “Playing”, “Buffering”, the behavior sets the Visual States for a Control as the designer specified. In the project, we are using this behavior to show and hide the media playback status displays. </li> <li><strong>DisplayMediaStatusBehavior – </strong>Again, a behavior that can be attached to a MediaElement that can translate the Playing, Buffering, etc states into text and display it in a TextBlock. </li> <li><strong>MouseOverOpacityBehavior</strong> – when applied to a FrameworkElement, the opacity of the element changes when the mouse is over the element. Designers can specify the transition time and the values for the opacity when the mouse is over the element and when it is not. Used on the skip button to light it up and emphasize the interactive nature of the button. </li> </ul> <h2>Easings</h2> <p>Easings are used to make animations more natural by having a gradual start and stop for the movements on the screen.</p> <h2></h2> <h2></h2> <h2>The glow effect</h2> <p>Silverlight does not have a Glow BitmapEffect, but with some change to the parameters of the drop shadow effect, it can actually be used as a glow effect. </p> <h2>Screencast contents</h2> <p><a href="http://www.silverlightshow.net/shows/The-Ugly-Duckling-Part-2.aspx">Watch the screencast</a>.</p> <p>Here is what happens in the screencast:</p> <table width="679" border="0" cellspacing="0" cellpadding="2"> <tbody> <tr> <td valign="top" style="width: 114px;"><strong>Time</strong></td> <td valign="top" style="width: 563px;"><strong>Content</strong></td> </tr> <tr> <td valign="top" style="width: 114px;">@ 0:00</td> <td valign="top" style="width: 563px;">Introduction and showing off what we are building in this screencast</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 1:40</td> <td valign="top" style="width: 563px;">Adding the intro animation – preparation</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 2:40</td> <td valign="top" style="width: 563px;">Adding the intro animation - MediaElement</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 3:47</td> <td valign="top" style="width: 563px;">Visual State for playing the intro and transition between PlayingIntro and ShowingUIAfterIntro states</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 4:57</td> <td valign="top" style="width: 563px;">Make the App start up in the PlayingIntro state</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 6:07</td> <td valign="top" style="width: 563px;">Adding the EndCueTrigger</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 9:40</td> <td valign="top" style="width: 563px;">Adding the playback status display</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 12:50</td> <td valign="top" style="width: 563px;">Adding IntroStatusVisible and IntroStatusHidden states and transitions</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 14:38</td> <td valign="top" style="width: 563px;">Creating the MediaElementStateToVSMBehavior</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 16:18</td> <td valign="top" style="width: 563px;">Using the MediaElementStateToVSMBehavior to show and hide the video status display</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 19:08</td> <td valign="top" style="width: 563px;">Creating the DisplayMediaStatusBehavior</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 21:00</td> <td valign="top" style="width: 563px;">Using the DisplayMediaStatusBehavior to set the text for the video status display</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 22:30</td> <td valign="top" style="width: 563px;">Adding the skip intro button</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 24:30</td> <td valign="top" style="width: 563px;">Adding a glow effect to the skip intro button</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 25:50</td> <td valign="top" style="width: 563px;">Creating MouseOverOpacityBehavior</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 28:14</td> <td valign="top" style="width: 563px;">Applying the MouseOverOpacityBehavior to the skip intro button</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 29:35</td> <td valign="top" style="width: 563px;">Making the skip intro button skip the intro</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 31:30</td> <td valign="top" style="width: 563px;">Replay Intro – creating the highlight on the box</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 33:20</td> <td valign="top" style="width: 563px;">Creating ReplayIntroVisible and ReplayIntroHidden states and transitions</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 38:10</td> <td valign="top" style="width: 563px;">Adding some code to the skip intro and replay intro features</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 41:30</td> <td valign="top" style="width: 563px;">Summing up</td> </tr> </tbody> </table> <p>Thank you for watching and good-bye until the next episode!</p> <a href="http://www.silverlightshow.net/Storage/Sources/uxoutsidetheBoxSLPart2.zip">Download Solution</a> http://www.silverlightshow.net/items/Transforming-an-Ugly-Duckling-into-a-Graceful-Swan-With-Expression-Blend-and-Silverlight-ndash-Part-2-ndash-Intro-Animation.aspx editorial@silverlightshow.net (András Velvárt ) http://www.silverlightshow.net/items/Transforming-an-Ugly-Duckling-into-a-Graceful-Swan-With-Expression-Blend-and-Silverlight-ndash-Part-2-ndash-Intro-Animation.aspx#comments http://www.silverlightshow.net/items/Transforming-an-Ugly-Duckling-into-a-Graceful-Swan-With-Expression-Blend-and-Silverlight-ndash-Part-2-ndash-Intro-Animation.aspx Fri, 05 Mar 2010 08:18:00 GMT Transforming an Ugly Duckling to a Graceful Swan with Expression Blend and Silverlight - Part I <p>This is part<strong> 1</strong><strong> </strong><strong>of the series “Transforming an Ugly Duckling to a Graceful Swan with Expression Blend and Silverlight”.</strong></p> <h3>Introduction</h3> <p>As I promised earlier on Silverlight Show, this screencast series will show how to create the showcase application shown on <a href="http://www.response.hu/">www.response.hu</a> (you may want to read the <a href="http://www.silverlightshow.net/ItemView.aspx?urlTitle=Silverlight-MVP-Andr-s-Velv-rt-tells-the-story-behind-the-creation-of-his-portal-www.response.hu-and-two-of-his-award-winning-projects" target="_blank">interview</a> to get some background information on the project). The screencast series shows a real life example of how designers can add value to a project, and how a developer can support this effort by creating small, reusable behaviors that allow the designer to tweak things to shape the end result to be exactly as he wanted it. </p> <p>The series is broken into four screencasts. In the first one, I will create the “ugly duckling” version of the application. The next one will add the Intro animation, related functionality and Blend behaviors. The third part will show how to style and animate the video list, and the last part will add the details view with the 3D transition effect.</p> <p>During the series, I will introduce some important concepts of working with Expression Blend on Silverlight applications. These concepts include:</p> <ul> <li>Working with Sample Data </li> <li>Creating a master-detail view </li> <li>Creating and using Behaviors and Actions </li> <li>Playing videos, displaying playback status information </li> <li>Using Visual States to add interactivity </li> <li>Customizing the look and behavior of a ListBox through ItemTemplate, ItemContainerStyle, ItemsPanelTemplate and ControlTemplate </li> <li>Extracting style to a resource </li> </ul> <h2>Screencast #1 – The Ugly Duckling</h2> <p><em>Note: I recommend watching the screencast in full screen.</em></p> <p><strong><a href="http://www.silverlightshow.net/shows/The-Ugly-Duckling.aspx" target="_blank">Watch the screencast</a></strong></p> <p><img alt="" width="240" height="182" title="image_thumb20" style="margin: 0px 10px 0px 0px; display: inline; float: left;border: 0px solid;" src="http://www.silverlightshow.net/Storage/Users/emil/image_thumb20_510214b7-57d6-474f-aba1-3347e70e3779.png" />The first screencast shows how to create the ugly version that I am going to work from in the later parts of the series. The ugly version lists all the videos (or ReferenceItems), and allows the user to see the explanation and play back the showcase videos.</p> <p>The videos (or ReferenceItems) have a title, a thumbnail picture, a description, a video URL and a link where additional information can be read. The application uses Expression Blend’s Sample Data feature to populate the data source that contains the videos and the associated data. After creating the data source,  I show how the thumbnails can be displayed in a ListBox, and how a master-detail view can be created in Blend using Element-to-Element databinding. As the first screencast is finished, the reference items are listed as thumbnails and the details of the selected video can be read, and the video can be played back.</p> <p>Here is what happens in the screencast:</p> <table width="679" border="0" cellspacing="0" cellpadding="2"> <tbody> <tr> <td valign="top" style="width: 114px;"><strong>Time</strong></td> <td valign="top" style="width: 563px;"><strong>Content</strong></td> </tr> <tr> <td valign="top" style="width: 114px;">@ 0:00</td> <td valign="top" style="width: 563px;">Introduction and showing off the finished application</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 1:59</td> <td valign="top" style="width: 563px;">Creating the application in Blend</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 2:50</td> <td valign="top" style="width: 563px;">Using Blend’s Sample Data feature to store the data for the video</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 6:58</td> <td valign="top" style="width: 563px;">Displaying the sample data in a ListBox</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 8:37</td> <td valign="top" style="width: 563px;">Creating the Details view with title, description, video and the more information link</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 13:33</td> <td valign="top" style="width: 563px;">Running the project for the first time, master-detail scenario works</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 14:39</td> <td valign="top" style="width: 563px;">Importing the videos into the project</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 15:42</td> <td valign="top" style="width: 563px;">Importing the thumbnail images to the project</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 16:20</td> <td valign="top" style="width: 563px;">Replacing the sample data with real data</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 17:20</td> <td valign="top" style="width: 563px;">Running the Ugly Duckling application with the real data</td> </tr> <tr> <td valign="top" style="width: 114px;">@ 19:10</td> <td valign="top" style="width: 563px;">Wrapping up</td> </tr> </tbody> </table> <p>I hope you found this screencast useful. Feel free to grab the attached source code. You may reuse the source code in any way you see fit. I have also provided the sample videos and thumbnails in the project, but the images and videos in the attached solution may only be used to follow the tutorial and to run the project as they represent the work of <a href="http://www.response.hu/" target="_blank">Response</a>, and contain trademarks and logos from Response and its clients.</p> <p>Please let me know in the comments if you like the screencast format, if it is too fast or too slow, and generally any opinion you may have about the screencast!</p> <p><a href="http://www.silverlightshow.net/Storage/Sources/UXOutsideTheBoxSL.zip" target="_blank">Download solution</a></p> http://www.silverlightshow.net/items/Transforming-an-Ugly-Duckling-to-a-Graceful-Swan-with-Expression-Blend-and-Silverlight-Part-I.aspx editorial@silverlightshow.net (András Velvárt ) http://www.silverlightshow.net/items/Transforming-an-Ugly-Duckling-to-a-Graceful-Swan-with-Expression-Blend-and-Silverlight-Part-I.aspx#comments http://www.silverlightshow.net/items/Transforming-an-Ugly-Duckling-to-a-Graceful-Swan-with-Expression-Blend-and-Silverlight-Part-I.aspx Thu, 11 Feb 2010 09:58:00 GMT Implicit Styles in Silverlight <h3></h3> <h3><strong><em><span style="font-size: 11pt; line-height: 115%; font-family: calibri, sans-serif;">This article is compatible with the latest version of Silverlight.</span></em><br /> </strong></h3> <div><strong><em><span style="font-size: 11pt; line-height: 115%; font-family: calibri, sans-serif;"><br /> </span></em></strong></div> <h3><strong>Introduction</strong></h3> <p>Only three months after the release of the latest official version of Silverlight 3, a new beta version – Silverlight 4 is already a fact. There are a lot of new things, which deserve to be mentioned, such as Rich Text, drop target, webcam, microphone, etc. Check out the <a href="http://www.silverlight.net/getstarted/silverlight-4/#whatsnew">official Silverlight site</a> for more information. However, in this article I decided to show you one very interesting feature, which is taken from WPF, namely it is the <strong>implicit styles</strong> feature.<br /> What was the situation till now? Whenever you’ve created a style  in Silverlight, you were obligated to specify the <strong>TargetType </strong>as well as an unique <strong>Key/Name</strong> for the style. You should also explicitly set the <strong>Style</strong> property of the desired element.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;background-color: #f4f4f4; font-family: 'courier new', courier, monospace; text-align: left;"> <div id="codeSnippet" style="padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Style</span> <span style="color: #ff0000;">x:Key</span><span style="color: #0000ff;">="ButtonStyle"</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="Button"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Background"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="Red"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Foreground"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="Black"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="FontSize"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="16"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Height"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="55"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Width"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="140"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Margin"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="8"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="RenderTransformOrigin"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="0.5,0.5"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="RenderTransform"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">RotateTransform</span> <span style="color: #ff0000;">Angle</span><span style="color: #0000ff;">="-15"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Style</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;">.................</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">StackPanel</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="button1"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="First Button"</span> <span style="color: #ff0000;">Style</span><span style="color: #0000ff;">="{StaticResource ButtonStyle}"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="button2"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Second Button"</span> <span style="color: #ff0000;">Style</span><span style="color: #0000ff;">="{StaticResource ButtonStyle}"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">StackPanel</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>This is also known as a <em>named style</em>.</p> <p style="text-align: center;"> <img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/Implicit%20Stlyes%20in%20Silverlight%204/ImplicitStyles-010.png" /></p> <h3> <p><span style="font-size: 16px;">But not any more! Silverlight 4 gives you the ability to create implicit styles.</span></p> <strong>Creating Implicit Styles</strong></h3> <p>If you omit the <strong>Style</strong>’s <strong>Key</strong> and specify only the <strong>TargetType</strong>, then the <strong>Style </strong>is automatically applied to all elements of that target type within the same scope (it is <strong>implicitly applied</strong>). This is typically called a <em>typed style</em> as opposed to a <em>named style</em>, which is the only kind of <strong>Style </strong>we’ve seen so far.</p> <p style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/Implicit%20Stlyes%20in%20Silverlight%204/ImplicitStyles-020.png" /></p> <p>The following example demonstrates you how to create an implicit style, which will be applied to all <strong>Buttons</strong> in the <strong>Application</strong> scope.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;background-color: #f4f4f4; font-family: 'courier new', courier, monospace; text-align: left;"> <div id="codeSnippet" style="padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Style</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="Button"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Background"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="Red"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Foreground"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="Black"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="FontSize"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="16"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Height"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="55"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Width"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="140"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Margin"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="8"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="RenderTransformOrigin"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="0.5,0.5"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="RenderTransform"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">RotateTransform</span> <span style="color: #ff0000;">Angle</span><span style="color: #0000ff;">="-15"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter.Value</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"></</span><span style="color: #800000;">Setter</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Style</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;">.............</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">StackPanel</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="button1"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="First Button"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="button2"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Second Button"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">StackPanel</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p> Note, you shouldn't specify the <strong>Button</strong>'s <strong>Style</strong> property.</p> <p style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/Implicit%20Stlyes%20in%20Silverlight%204/ImplicitStyles-030.png" /> </p> <p>In such an application, all Buttons get this style by default. But each Button can still override its appearance by explicitly setting a different Style or explicitly setting properties.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="button2"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Second Button"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="Green"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--></div> </div> <p style="text-align: center;"> <img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/Implicit%20Stlyes%20in%20Silverlight%204/ImplicitStyles-040.png" /></p> <p>Also, any Button can restore its default <strong>Style </strong>by setting its <strong>Style</strong> property to <strong>null</strong>.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="button2"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Second Button"</span> <span style="color: #ff0000;">Style</span><span style="color: #0000ff;">="{x:Null}"</span><span style="color: #0000ff;">/></span></pre> <div style="text-align: center;"><span style="color: #0000ff;"> <p><span><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/Implicit%20Stlyes%20in%20Silverlight%204/ImplicitStyles-050.png" /></span></p> </span><br /> </div> <!--CRLF--></div> </div> <h3><strong>The Target Element Must Match Exactly the TargetType</strong></h3> <p>Note, that the <strong>TargetType</strong> must match exactly for a typed style to be applied. For example, if you specify the <strong>Style</strong>’s <strong>Key</strong>, then it’s ok for the target element to be a subclass of the <strong>TargetType</strong>. But a typed style typically gets applied to elements which type matches exactly! This is done to prevent surprises. For example, you might have created a <strong>Style</strong> for all <strong>ToggleButton</strong>s in your application and you don’t want this style to be applied to any <strong>CheckBoxe</strong>s (which derives from the ToggleButton).</p> <h3></h3> <h3><strong>Where is the Key for the Keyless Resource?</strong></h3> <p>So far so good, but you may wonder how it is possible a <strong>Style</strong> to get away with being a member of a <strong>ResourceDictionary</strong> without having a key. It actually <strong>does</strong> have a key – it’s just set implicitly. And the implicit key is simply the value of the <strong>TargetType </strong>(at least this is the situation in WPF, probably it is also true for Silverlight!?!).</p> <h3><strong>Implicit Styles and BasedOn</strong></h3> <p>If you have multiple implicit styles relating to a particular control, then they do not magically combine. For example, if you have the following two styles:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Style</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="Button"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="FontSize"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="16"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Style</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Style</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="Button"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Background"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="Red"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Foreground"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="Black"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Style</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>they won’t get combined. Something more - this will result in a run-time error. However, implicit styles can still use <strong>BasedOn</strong>. After the refactoring of the previous example it should look like the code below:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Style</span> <span style="color: #ff0000;">x:Key</span><span style="color: #0000ff;">="BasedStyle"</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="Button"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="FontSize"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="16"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Style</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">Style</span> <span style="color: #ff0000;">TargetType</span><span style="color: #0000ff;">="Button"</span> <span style="color: #ff0000;">BasedOn</span><span style="color: #0000ff;">="{StaticResource BasedStyle}"</span><span style="color: #0000ff;">></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Background"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="Red"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Setter</span> <span style="color: #ff0000;">Property</span><span style="color: #0000ff;">="Foreground"</span> <span style="color: #ff0000;">Value</span><span style="color: #0000ff;">="Black"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow-x: visible; overflow-y: visible; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">Style</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>Undoubtedly, this is a great addition to the Silverlight styling. You can define implicit styles at any level of your application. Additionally you have the ability to override at any time the implicit style or even to reset it. </p> http://www.silverlightshow.net/items/Implicit-Styles-in-Silverlight-4.aspx editorial@silverlightshow.net (Pencho Popadiyn ) http://www.silverlightshow.net/items/Implicit-Styles-in-Silverlight-4.aspx#comments http://www.silverlightshow.net/items/Implicit-Styles-in-Silverlight-4.aspx Tue, 24 Nov 2009 07:14:00 GMT