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) Designer-friendly MVVM for XAML Windows Store applications <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/Designer-friendly-MVVM-for-XAML-Windows-Store-applications.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/Designer-friendly-MVVM-for-XAML-Windows-Store-applications.aspx" data-count="horizontal" data-text="Check @vbandi's article: Designer-friendly #MVVM for #XAML #WindowsStore apps! #win8dev" data-url="http://slshow.net/UDWOe4">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Designer-friendly-MVVM-for-XAML-Windows-Store-applications.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <h1>Introduction</h1> <p>It was almost three years ago that I published my company’s preferred <a href="http://www.silverlightshow.net/items/A-Designer-friendly-Approach-to-MVVM-Part-I.aspx">approach to MVVM with Silverlight</a>. Time sure flies, and now I can say that the basic ideas and general way of thinking outlined in that article stood the test of time – we created dozens of applications that used that approach, many of them ended being in the top 5 apps in the Windows Phone Store in their own categories. </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: 0px; padding-left: 20px; font-size: 12px;"> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/news/Free-SilverlightShow-Webinar-Applied-MVVM-in-Windows-8-apps.aspx">Join our webinar on Feb 26: Applied MVVM in Win8 Apps</a></li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/video/MVVM-in-Win8-Webinar.aspx">Recording of webinar: MVVM in Windows 8</a></li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/win8_8tricks.aspx">Samidip Basu's Win8 ebook</a>:</li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/win8_8tricks.aspx"><img style="width: 80px; height: 113px; border-width: 0px; border-style: solid;" alt="Windows 8 Apps - 8 Must-Know Tricks: Ebook" src="http://www.silverlightshow.net/Storage/Ebooks/win8_tricks.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>And then, WinRT happened. WinRT (or Windows 8 Store application) development does not support Behaviors, Actions or Triggers, which were the foundation of the two key pieces of our MVVM puzzle: CallDataContextMethodAction and VSMChangerBehavior. We found that we had to write a lot of repetitive code in the codebehind, and often could not avoid littering it with some business logic that belonged in the ViewModel instead. </p> <p><em>Note: I am not an MVVM purist – I think that using code behind is fine when it comes to manipulating the UI itself, and not the data that drives the UI. However, a lot of this functionality could be abstracted and reused with Behaviors – e.g. you could write a behavior that selected the content of an entire TextBox when it got focus, making it easier to replace the text within. Sadly, this is not really an option with WinRT without proper tool support.</em></p> <p>After gaining enough experience with WinRT development, I set out to port over our proven approach to WinRT. A lot had to be changed since we could not take advantage of Behaviors, but the basics remained the same. This article introduces the WinRT version of the Designer-friendly MVVM Helpers library. </p> <h2>A Word about MVVM</h2> <p>Discussing what MVVM is and why it’s useful is waaaay beyond the scope of this article. I am assuming that You already know what it is, at least on a conceptual level. If not, please read <a href="http://www.silverlightshow.net/items/A-Designer-friendly-Approach-to-MVVM-Part-I.aspx">the original Silverlight version of this article</a>, which discusses the most important things about MVVM, and also gives you pointers for further reading.</p> <h1>Goals of the Designer-friendly MVVM Helpers</h1> <p>The goals are mostly the same as they were in the Silverlight / Windows Phone version. </p> <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 and lack of Behaviors) </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 XAML </li> <li>Create a 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/">MVVM Light Toolkit</a></li> </ul> <h1>Using the Designer-friendly MVVM Helpers</h1> <p>When discussing the relationship between a ViewModel and a View, XAML technologies use two key concepts:</p> <ul> <li>Data binding – to get data from the VM to the View and vice versa </li> <li>Commanding – to notify the VM of the user’s actions, such as the pressing of a button</li> </ul> <p>Our library extends data binding by creating a bi-directional link between a View’s Visual States and an Enum in the ViewModel, and also provides a way for the View to call ViewModel methods upon user interactions. This covers 90% of the use cases for a typical, well architected MVVM app. For the rest, we are still relying on code behind, and desperately wait for the arrival of Behaviors in an upcoming WinRT / Blend release.</p> <p>First, let’s see how the VM can be notified of user interactions.</p> <h2>The CallVMMethod Attached Property</h2> <p>For the <a href="http://www.silverlightshow.net/items/A-Designer-friendly-Approach-to-MVVM-Part-I.aspx">Silverlight / Windows Phone version</a>, this used to be the CallDataContextMethodAction. With Triggers, you had a very flexible way of specifying when the VM method should be called. While a similar approach could be used for WinRT using third party Behavior libraries, due to the lack of Blend support, these result in a ton of XAML code you had to write, making the solution designer-unfriendly. I looked at our usage of this pattern in our projects, and found that 98% of the time, we are just using a simple EventTrigger to trigger the CallDataContextMethodAction. So, for Windows 8, I focused on this use case, and I went for the most fluid experience I could achieve (leaving the other 2% to codebehind solutions). </p> <h3>Basic Example</h3> <p>Our first example simply shows the content of a TextBox in a dialog. Showing a MessageDialog from a ViewModel is not a good practice (beats testability and also separation of concerns), but I am using it as an example here to illustrate that the VM did receive a message. </p> <p>The entire Page has a DataContext (MainVM), defined as follows:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd"><</span><span class="html">Page.DataContext</span><span class="kwrd">></span> </pre> <pre><span class="lnum"> 2: </span> <span class="kwrd"><</span><span class="html">df:MainVM</span><span class="kwrd">></</span><span class="html">df:MainVM</span><span class="kwrd">></span></pre> <pre class="alt"><span class="lnum"> 3: </span><span class="kwrd"></</span><span class="html">Page.DataContext</span><span class="kwrd">></span></pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <pre></pre> <p>Here is the relevant code snippet from the ViewModel: </p> <pre> </pre> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">string</span> Message { get; set; }</pre> <pre><span class="lnum"> 2: </span> </pre> <pre class="alt"><span class="lnum"> 3: </span><span class="kwrd">public</span> <span class="kwrd">void</span> ShowMessage()</pre> <pre><span class="lnum"> 4: </span>{</pre> <pre class="alt"><span class="lnum"> 5: </span> <span class="kwrd">string</span> msg = Message ?? <span class="str">"Enter something in the textbox"</span>;</pre> <pre><span class="lnum"> 6: </span> MessageDialog dialog = <span class="kwrd">new</span> MessageDialog(msg, <span class="str">"Dialog from ViewModel"</span>);</pre> <pre class="alt"><span class="lnum"> 7: </span> dialog.ShowAsync();</pre> <pre><span class="lnum"> 8: </span>}</pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>The UI for this sample looks like this:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/_image_2.png"><img width="321" height="72" title="image" style="display: inline; border-width: 0px; border-style: solid;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/_image_thumb.png" /></a> </p> <p>And the XAML is:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd"><</span><span class="html">TextBox</span> <span class="attr">Text</span><span class="kwrd">="{Binding Message, Mode=TwoWay}"</span><span class="kwrd">/></span></pre> <pre><span class="lnum"> 2: </span><span class="kwrd"><</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">="Message!"</span> <span class="attr">df:CallVMMethod</span>.<span class="attr">Click</span><span class="kwrd">="ShowMessage"</span><span class="kwrd">/></span></pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <pre></pre> <p>The ViewModel learns about the content of the TextBox with a simple binding –0 no surprises here. The more interesting part is the second line, where the new attached property is used to call the ShowMessage method of the ViewModel (or technically, the DataContext of the Button), when the Button’s Click event is fired.</p> <p>When you are typing the above line, Intellisense helps you as much as possible. Here is what it looks like: </p> <p><a href="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_4.png"><img width="622" height="259" title="image" style="display: inline; border-width: 0px; border-style: solid;" alt="image" src="http://www.silverlightshow.net/Storage/Users/andrasvelvart/image_thumb_1.png" /></a> </p> <p>As you can see, the most used event handlers are available – and if the one you are looking for is not, you can easily add a new one. </p> <h3>Using from an ItemTemplate</h3> <p>This is all nice, but often you want to call a VM method from a list. E.g. the VM should know when you selected an item, or clicked the “Delete” button next to an item. </p> <p>Suppose we have a list of strings, and want the user to choose one of those. Here is the VM (again, simplified to focus on the main point of the article):</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> MainVM()</pre> <pre><span class="lnum"> 2: </span>{</pre> <pre class="alt"><span class="lnum"> 3: </span> SomeStrings = <span class="kwrd">new</span> ObservableCollection<<span class="kwrd">string</span>>();</pre> <pre><span class="lnum"> 4: </span> <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i < 10; i++)</pre> <pre class="alt"><span class="lnum"> 5: </span> SomeStrings.Add(Guid.NewGuid().ToString());</pre> <pre><span class="lnum"> 6: </span>}</pre> <pre class="alt"><span class="lnum"> 7: </span> </pre> <pre><span class="lnum"> 8: </span><span class="kwrd">public</span> ObservableCollection<String> SomeStrings { get; <span class="kwrd">private</span> set; }</pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>We have a ListView in the View to display these strings. Pretty straightforward so far:</p> <pre class="csharpcode"><span class="kwrd"><</span><span class="html">ListView</span> <span class="attr">ItemsSource</span><span class="kwrd">="{Binding SomeStrings}"</span> <span class="attr">ItemTemplate</span><span class="kwrd">="{StaticResource DataTemplate1}"</span><span class="kwrd">/></span></pre> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>You could bind the SelectedItem to a property in the VM and handle selection in the property setter, but the setter does not get called if you click on the item already selected. Instead, you could do something like this in the ItemTemplate:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd"><</span><span class="html">DataTemplate</span> <span class="attr">x:Key</span><span class="kwrd">="DataTemplate1"</span><span class="kwrd">></span> </pre> <pre><span class="lnum"> 2: </span> <span class="kwrd"><</span><span class="html">TextBlock</span> <span class="attr">TextWrapping</span><span class="kwrd">="Wrap"</span> <span class="attr">Text</span><span class="kwrd">="{Binding}"</span> <span class="attr">df:CallVMMethod</span>.<span class="attr">Tapped</span><span class="kwrd">="StringSelected"</span><span class="kwrd">/></span></pre> <pre class="alt"><span class="lnum"> 3: </span><span class="kwrd"></</span><span class="html">DataTemplate</span><span class="kwrd">></span></pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <pre></pre> <p>This would call the StringSelected method of the DataContext, except… the DataContext of the DataTemplate in this case is just a String, which does not have such a method. What happens in this case, is that the CallVMMethod <strong>starts to traverse the Visual Tree</strong>. If the DataContext of the TextBlock does not have a StringSelected method, maybe its parent does. Or maybe the parent of that… and so on, and so on, until the method with the right signature is found (see below), or the top of the Visual Tree is reached (in which case you get an ArgumentException).</p> <p>This way, as we go up, we reach the parent ListBox, the DataContext of which does have the StringSelected method defined in the MainVM class:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">void</span> StringSelected(<span class="kwrd">string</span> dataContext)</pre> <pre><span class="lnum"> 2: </span>{</pre> <pre class="alt"><span class="lnum"> 3: </span> MessageDialog msgd = <span class="kwrd">new</span> MessageDialog(<span class="str">"Selected: "</span> + dataContext);</pre> <pre><span class="lnum"> 4: </span> msgd.ShowAsync();</pre> <pre class="alt"><span class="lnum"> 5: </span>}</pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <pre></pre> <p> This StringSelected method excepts a single parameter, with the type of String. This is important – since we have traversed up the Visual Tree until the point where the original DataContext of the tapped TextBlock is no longer visible, we have to have a way for the StringSelected method to know which string was tapped on. This technique can also be used to pass a business object, such as a Person or Company to the VM.</p> <h3>Method signatures</h3> <p>As you saw above, there are several ways you can define the methods in the ViewModel to be called by CallVMMethod. Here is a reference table of all the supported signatures:</p> <p><strong>MethodName()</strong><br /> No parameters, no data passed to the method</p> <p><strong>MethodName(T dataContext)</strong><br /> If the DataContext of the source FrameworkElement mathes the type T (or can be assigned to a variable of type T), this method is a match. The value passed is the DataContext of the source FrameworkElement</p> <p><strong>MethodName(T dataContext, Targs args)</strong><br /> It is rare, but sometimes you may want to pass the original event’s arguments to the ViewModel. If so, this signature is understood by CallVMMethod and invoked.</p> <p>The CallVMMethod will look for all these methods in the DataContext of the source FrameworkElement and its parents’ DataContext until it finds a suitable method or reaches the top of the tree.</p> <h3>Adding more events</h3> <p>You may find that the events implemented by CallVMMethod does not include the event you want to use. Luckily, it is easy to expand the list of events: open the CallMVVMMethodHandledEvents.tt file (which is a <a href="http://msdn.microsoft.com/en-us/library/bb126445.aspx">T4 template</a>), and add your event to the others by listing the event name, event handler type and event argument type. For example, this is what the first few events look like in the template:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">string</span>[] handledEvents = <span class="kwrd">new</span> <span class="kwrd">string</span>[] {</pre> <pre><span class="lnum"> 2: </span> </pre> <pre class="alt"><span class="lnum"> 3: </span><span class="str">"Click,RoutedEventHandler,RoutedEventArgs"</span>,</pre> <pre><span class="lnum"> 4: </span><span class="str">"DoubleTapped,DoubleTappedEventHandler,DoubleTappedRoutedEventArgs"</span>,</pre> <pre class="alt"><span class="lnum"> 5: </span><span class="str">"DragEnter,DragEventHandler,DragEventArgs"</span>,</pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>The T4 code generator will take care of the rest.</p> <h2>The EnumToVisualState Control</h2> <p>The other piece of the designer-friendly MVVM puzzle was the VSMChangerBehavior, which <strong>mapped ViewModel enums to Visual States in the View</strong>. Again, due to the lack of Behavior support in WinRT, this had to be rewritten, but the basic idea remained the same. </p> <p>The sample I am going to show for the EnumToVisualState control is a simple one: the ViewModel controls whether a panel is to be open or closed via a simple Toggle method. </p> <h3>Configuration</h3> <p>Let’s define a simple enum for the panel’s two states: On and Off:</p> <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">enum</span> PanelState { Off, On }</pre> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>…and use it in the ViewModel:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">private</span> PanelState _panel = PanelState.Off;</pre> <pre><span class="lnum"> 2: </span><span class="kwrd">public</span> PanelState Panel</pre> <pre class="alt"><span class="lnum"> 3: </span>{</pre> <pre><span class="lnum"> 4: </span> get { <span class="kwrd">return</span> _panel; }</pre> <pre class="alt"><span class="lnum"> 5: </span> set</pre> <pre><span class="lnum"> 6: </span> {</pre> <pre class="alt"><span class="lnum"> 7: </span> _panel = <span class="kwrd">value</span>;</pre> <pre><span class="lnum"> 8: </span> <span class="kwrd">if</span> (PropertyChanged != <span class="kwrd">null</span>)</pre> <pre class="alt"><span class="lnum"> 9: </span> PropertyChanged(<span class="kwrd">this</span>, <span class="kwrd">new</span> PropertyChangedEventArgs(<span class="str">"Panel"</span>));</pre> <pre><span class="lnum"> 10: </span> }</pre> <pre class="alt"><span class="lnum"> 11: </span>}</pre> <pre><span class="lnum"> 12: </span> </pre> <pre class="alt"><span class="lnum"> 13: </span><span class="kwrd">public</span> <span class="kwrd">void</span> TogglePanel(<span class="kwrd">object</span> dataContext, TappedRoutedEventArgs args)</pre> <pre><span class="lnum"> 14: </span>{</pre> <pre class="alt"><span class="lnum"> 15: </span> Panel = Panel == PanelState.Off ? PanelState.On : PanelState.Off;</pre> <pre><span class="lnum"> 16: </span>}</pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <pre></pre> <p>You can use a more sophisticated method for raising the PropertyChanged event, but it is important that you do perform this call. </p> <p>Next, you need to define the Visual States that correspond to the enum values and property names above. For this example, we need to define a Visual State Group called “Panel”, and two states within it: “Panel_On” and “Panel_Off”. Here is an example for a panel that slides in from the left:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd"><</span><span class="html">VisualStateManager.VisualStateGroups</span><span class="kwrd">></span></pre> <pre><span class="lnum"> 2: </span> <span class="kwrd"><</span><span class="html">VisualStateGroup</span> <span class="attr">x:Name</span><span class="kwrd">="Panel"</span><span class="kwrd">></span></pre> <pre class="alt"><span class="lnum"> 3: </span> <span class="kwrd"><</span><span class="html">VisualStateGroup.Transitions</span><span class="kwrd">></span></pre> <pre><span class="lnum"> 4: </span> <span class="kwrd"><</span><span class="html">VisualTransition</span> <span class="attr">GeneratedDuration</span><span class="kwrd">="0:0:0.5"</span><span class="kwrd">></span></pre> <pre class="alt"><span class="lnum"> 5: </span> <span class="kwrd"><</span><span class="html">VisualTransition.GeneratedEasingFunction</span><span class="kwrd">></span></pre> <pre><span class="lnum"> 6: </span> <span class="kwrd"><</span><span class="html">CircleEase</span> <span class="attr">EasingMode</span><span class="kwrd">="EaseInOut"</span><span class="kwrd">/></span></pre> <pre class="alt"><span class="lnum"> 7: </span> <span class="kwrd"></</span><span class="html">VisualTransition.GeneratedEasingFunction</span><span class="kwrd">></span></pre> <pre><span class="lnum"> 8: </span> <span class="kwrd"></</span><span class="html">VisualTransition</span><span class="kwrd">></span></pre> <pre class="alt"><span class="lnum"> 9: </span> <span class="kwrd"></</span><span class="html">VisualStateGroup.Transitions</span><span class="kwrd">></span></pre> <pre><span class="lnum"> 10: </span> <span class="kwrd"><</span><span class="html">VisualState</span> <span class="attr">x:Name</span><span class="kwrd">="Panel_On"</span><span class="kwrd">/></span></pre> <pre class="alt"><span class="lnum"> 11: </span> <span class="kwrd"><</span><span class="html">VisualState</span> <span class="attr">x:Name</span><span class="kwrd">="Panel_Off"</span><span class="kwrd">></span></pre> <pre><span class="lnum"> 12: </span> <span class="kwrd"><</span><span class="html">Storyboard</span><span class="kwrd">></span></pre> <pre class="alt"><span class="lnum"> 13: </span> <span class="kwrd"><</span><span class="html">DoubleAnimation</span> <span class="attr">Duration</span><span class="kwrd">="0"</span> <span class="attr">To</span><span class="kwrd">="-340"</span> <span class="attr">Storyboard</span>.<span class="attr">TargetProperty</span><span class="kwrd">="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"</span> <span class="attr">Storyboard</span>.<span class="attr">TargetName</span><span class="kwrd">="grid1"</span> <span class="attr">d:IsOptimized</span><span class="kwrd">="True"</span><span class="kwrd">/></span></pre> <pre><span class="lnum"> 14: </span> <span class="kwrd"></</span><span class="html">Storyboard</span><span class="kwrd">></span></pre> <pre class="alt"><span class="lnum"> 15: </span> <span class="kwrd"></</span><span class="html">VisualState</span><span class="kwrd">></span></pre> <pre><span class="lnum"> 16: </span> <span class="kwrd"></</span><span class="html">VisualStateGroup</span><span class="kwrd">></span></pre> <pre class="alt"><span class="lnum"> 17: </span><span class="kwrd"></</span><span class="html">VisualStateManager.VisualStateGroups</span><span class="kwrd">></span></pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <pre></pre> <p>The last step is to add an EnumToVisualState control to your Page:</p> <pre class="csharpcode"><span class="kwrd"><</span><span class="html">df:EnumToVisualState</span> <span class="attr">Opacity</span><span class="kwrd">="0"</span> <span class="attr">VerboseInitialization</span><span class="kwrd">="True"</span> <span class="attr">ElementWithVisualStates</span><span class="kwrd">="{Binding ElementName=grid}"</span> <span class="kwrd">/></span></pre> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>The control is invisible. It has three important properties:</p> <p><strong>DataContext</strong><br /> The ViewModel where the enums are defined. Since DataContext is inherited in the Visual Tree, most of the time you can leave it as is – however, if you need to, you can bind it to something else, using the full binding arsenal of WinRT</p> <p><strong>ElementWithVisualStates</strong><br /> This is the FrameworkElement the Visual States of which we want to control. </p> <p><strong>VerboseInitialization</strong><br /> Set this to true to have EnumToVisualState write detailed initialization information to the Debug output window. This will show you what kind of properties and methods the control is looking for in the ViewModel, and help hunt down typos.</p> <p>Finally, we can add a Button to the UI to toggle the panel by calling the TogglePanel VM method using the CallVMMethod technique:</p> <pre class="csharpcode"><span class="kwrd"><</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">="Toggle Panel"</span> <span class="attr">df:CallVMMethod</span>.<span class="attr">Tapped</span><span class="kwrd">="TogglePanel"</span> <span class="kwrd">/></span></pre> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <p>Tapping the button now invokes the TogglePanel VM method, which in turn changes the PanelState enum, which causes the Visual State to change and the animation to be played. </p> <h3>Conventions</h3> <p>EnumToVisualState uses a convention-based approach. This means that instead of using a lot of binding, you only have to make sure that the enums in the ViewModel and the state names in the View match to work. Here are the naming conventions you have to follow:</p> <ul> <li>To map a Visual State Group to an enum, all you have to do is make sure they both have the same name. </li> <li>To map a Visual State to a value of an enum, you have to name the Visual State correctly: <Enum variable name>_<enum value name>. </li> <li>To get notified in the ViewModel when a visual state transition is finished, you need to have a method called <VisualStateGroup name>TransitionComplete() with no parameters.</li> </ul> <p>So, if you have an enum called PanelState, which has the possible values of “Off” and “On”, and you have a ViewModel property called “Panel”, you need to call your Visual State Group “Panel”, and the states withing it “Panel_Off” and “Panel_On”.</p> <h3>Callbacks</h3> <p>Since Visual States can have transition animations which can take a while to finish, it is sometimes useful to know when the user actually sees the final scene. EnumToVisualState provides you with this information: if you have a method called “PanelTransitionComplete”, this method will be called every time the “Panel” Visual State Group finishes a transition animation. Here is an example:</p> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">void</span> PanelTransitionComplete()</pre> <pre><span class="lnum"> 2: </span>{</pre> <pre class="alt"><span class="lnum"> 3: </span> MessageDialog msgd = <span class="kwrd">new</span> MessageDialog(<span class="str">"Panel transition to "</span> + Panel.ToString() + <span class="str">" complete!"</span>);</pre> <pre><span class="lnum"> 4: </span> msgd.ShowAsync();</pre> <pre class="alt"><span class="lnum"> 5: </span>}</pre> </div> <style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .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; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <pre></pre> <p>The new state is not passed to this method, it can be determined from the value of the corresponding enum.</p> <h3>Initial State</h3> <p>You can also set an initial state for the enums in the VM, and the Visual States will be initialized in that state. For example, if you set the Panel to PanelState.Off, the Panel will not be visible when the Page first shows up. While this is achieved without a visible transition animation, the TransitionComplete method is still invoked.</p> <h1>Download</h1> <p>Finally, you can download <a href="http://sdrv.ms/WLPOqC">the entire demo project here</a>. You will need to copy four files to your project: CallVMMethod.cs, CallVMMethodHandledEvents.tt, EnumToVisualState.cs, and also . I will also prepare a Nuget package, and will upload it soon after this article is published.</p> <h1>Summary</h1> <p>Porting our tried and proven Behaviors to WinRT was not a simple task. However, I believe that in the end, the core values of the original solution are preserved despite the different architecture. Please let me know if you find this library useful, or if you have any feedback!</p> http://www.silverlightshow.net/items/Designer-friendly-MVVM-for-XAML-Windows-Store-applications.aspx editorial@silverlightshow.net (András Velvárt ) http://www.silverlightshow.net/items/Designer-friendly-MVVM-for-XAML-Windows-Store-applications.aspx#comments http://www.silverlightshow.net/items/Designer-friendly-MVVM-for-XAML-Windows-Store-applications.aspx Thu, 07 Feb 2013 13:49:00 GMT 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 Windows 8 Metro Apps: The 8 Must-Know Tricks! Day 3 <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-3.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-3.aspx" data-count="horizontal" data-text="Reading @samidip's article '#Windows8 Metro Apps: The 8 Must-Know Tricks! Day 3' #win8 #win8dev" data-url="http://slshow.net/NYdmsy">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-3.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p>This is Day # 3 in the Windows 8 development article series on common tips & tricks towards real-world Metro apps.  We’ve gotten past our initial idea & layout hurdles and your first Windows 8 Metro app is slowly coming together.  Time to give your Metro app some typical Windows 8 character & its own brand. 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 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 /> <a href="http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-2.aspx" target="_blank">Day 2: Layout, Navigation & Visual States</a> <br /> <strong>Day 3: Semantic Zoom</strong> <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></p> <h4>Day 3: Semantic Zoom</h4> <p><span style="font-size: 16px;">The Collections View:</span></p> <p>Let’s take a good look at the Windows 8 Start screen; then at the Windows 8 Store Metro app. Also, try out some of the many RSS/news/aggregator type apps available now. Do you see a common trend? They all present a ton of information without making the end-user experience seem too busy. Just because we have a bigger form factor, does not mean that we will fill up all the available space with content. In Metro design language, white space is our friend – it provides for breathing room for a smooth UX. So, many of the Windows 8 Metro UIs which present a lot of content revert to using <em>GridView</em> type layouts: long list of well-spaced rectangles with inviting content & an overlay text at the bottom with some description. We usually get to pan around horizontally to discover more content. Let’s take our little demo SilverlightShow Article app as an example. This is the kind of UI you would see a lot when the data being presented is a collection of items:</p> <p> </p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/SemanticZoomIn_2.png"><img title="SemanticZoomIn" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="SemanticZoomIn" src="http://www.silverlightshow.net/Storage/Users/samidip/SemanticZoomIn_thumb.png" width="644" height="364" /></a></p> <p>This type of UI could also be generalized when presenting any type of repeated or similar controls in a Metro app. Say, you have a list of User Controls in your page, which is making for a busy UI. Or a BookShelf of items. Or a virtual Shopping Cart full of items, ready for review or checkout.</p> <p> </p> <p><span style="font-size: 16px;">The Discoverability Problem:</span></p> <p>As nice as it is to pan around for discoverability when content is presented as above, there is one little glitch. What if the collection of items being displayed is huge? Envision the above screen when bound to hundreds or more items in the collection. Even if we took the last 100 articles published by SilverlightShow, it would possibly take 20-25 horizontal swipes to get to the 100th article. One could argue that the collection of items could be grouped based on some parameter, as in the article topic above. But even with that, we are literally presenting a large number of items in each group, resulting in a lot of panning around to discover content. Clearly not optimal.</p> <p> </p> <p><span style="font-size: 16px;">The Solution:</span></p> <p>Windows 8 presents a new UX paradigm to get around the discoverability problem when presented with a large collection of items. Logically thinking would lead us to group the items into buckets, based on some criteria, so that it is a little easier to find a specific item. Now, if the data is being grouped in logical units, why not the UI? Check out the same screen of SilverlightShow articles above, this time grouped into article categories and only the high-level groups showing:</p> <p> </p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/SemanticZoomOut_2.png"><img title="SemanticZoomOut" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="SemanticZoomOut" src="http://www.silverlightshow.net/Storage/Users/samidip/SemanticZoomOut_thumb.png" width="644" height="364" /></a></p> <p>This is what Windows 8 calls<em> Semantic Zooming</em>. A new UX paradigm, particularly suited for touch-based PCs. How do we get from the busy layout to the zoomed-out view of grouped categories? Simple – Pinch in with two fingers on screen; Pinch out to go back to normal layout. In a PC with traditional keyboard & mouse setup, hold down CTRL key & scroll mouse wheel up/down or use CTRL plus +/- to achieve the same result. Semantic zoom is quite different from optical zoom; unlike changing magnification, it shows a different slice of grouped data.</p> <p>So, it is pretty clear that Semantic Zoom uses data grouping into buckets & simply flips the view to alter the level of detail shown. This is visually delightful UX, if done right and aids big time towards discoverability of content. Zoom out to a high-level view, pick what interests you & dive back in exactly where you desire.  In case you did not know & found your Windows 8 Start screen starting to get cluttered, just use Semantic Zooming to organize your Tiles. Each group can actually be named for easy of organization & personalization, as evident below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/StartZoomedIn_2.png"><img title="StartZoomedIn" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="StartZoomedIn" src="http://www.silverlightshow.net/Storage/Users/samidip/StartZoomedIn_thumb.png" width="644" height="364" /></a></p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/StartZoomedOut_4.png"><img title="StartZoomedOut" style="display: inline; background-image: none; border-width: 0px; border-style: solid;" alt="StartZoomedOut" src="http://www.silverlightshow.net/Storage/Users/samidip/StartZoomedOut_thumb_1.png" width="644" height="364" /></a></p> <p><span style="font-size: 16px;">Implementing Semantic Zoom:</span></p> <p>So, enough descriptive talk; let’s see how we can enable Semantic Zooming in our applications. Let’s take the example of the SilverlightShow Article app and walk you through the few steps it takes to get this working.</p> <p>First, the data. Your custom objects, of which you would have a collection of. Let’s define a simple class for articles:</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;">public</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span> SLShowArticle</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: #0000ff;">public</span> <span style="color: #0000ff;">int</span> ArticleID { get; set; }</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;">public</span> <span style="color: #0000ff;">string</span> ArticleName { get; set; }</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> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> ArticleTopic { get; set; }</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;">public</span> <span style="color: #0000ff;">string</span> AuthorName { get; set; }</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;">public</span> DateTime PublishDate { get; set; }</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> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> DisplayablePublishDate</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> {</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> get</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> {</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> <span style="color: #0000ff;">return</span> PublishDate.ToString(<span style="color: #006080;">"MM/dd/yyyy"</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> }</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--></div> </div> <p>Next is grouping. Remember we need to categorize our data in buckets for easy finding? So, let’s define our class to hold a collection of grouped articles:</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;">public</span> <span style="color: #0000ff;">class</span> SLShowGroupedArticles : BindableBase</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: #cc6633;">#region</span> <span style="color: #006080;">"Members"</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>  </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> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> _SLShowArticleGroupName;</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;">int</span> _SLShowArticleGroupCount;</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;">private</span> ObservableCollection<SLShowArticle> _articleCollection;</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: #cc6633;">#endregion</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: #cc6633;">#region</span> <span style="color: #006080;">"Properties"</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;">public</span> <span style="color: #0000ff;">string</span> SLShowArticleGroupName</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> get { <span style="color: #0000ff;">return</span> _SLShowArticleGroupName; }</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> set { SetProperty(<span style="color: #0000ff;">ref</span> _SLShowArticleGroupName, <span style="color: #0000ff;">value</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--> <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>  </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> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> SLShowArticleGroupCount</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> get { <span style="color: #0000ff;">return</span> _SLShowArticleGroupCount; }</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> set { SetProperty(<span style="color: #0000ff;">ref</span> _SLShowArticleGroupCount, <span style="color: #0000ff;">value</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> }</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>  </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> <span style="color: #0000ff;">public</span> ObservableCollection<SLShowArticle> ArticleCollection</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> {</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> get { <span style="color: #0000ff;">return</span> _articleCollection; }</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> set { SetProperty(<span style="color: #0000ff;">ref</span> _articleCollection, <span style="color: #0000ff;">value</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="lnum30" style="color: #606060;"> 30:</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="lnum31" style="color: #606060;"> 31:</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="lnum32" style="color: #606060;"> 32:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> ImageURI</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="lnum33" style="color: #606060;"> 33:</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="lnum34" style="color: #606060;"> 34:</span> get</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="lnum35" style="color: #606060;"> 35:</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="lnum36" style="color: #606060;"> 36:</span> <span style="color: #0000ff;">string</span> imageUri = <span style="color: #0000ff;">string</span>.Empty;</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="lnum37" style="color: #606060;"> 37:</span> <span style="color: #0000ff;">switch</span> (SLShowArticleGroupName)</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="lnum38" style="color: #606060;"> 38:</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="lnum39" style="color: #606060;"> 39:</span> <span style="color: #0000ff;">case</span> <span style="color: #006080;">"Windows 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: #f4f4f4;"><span id="lnum40" style="color: #606060;"> 40:</span> imageUri = <span style="color: #006080;">"/Assets/Windows8.png"</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="lnum41" style="color: #606060;"> 41:</span> <span style="color: #0000ff;">break</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="lnum42" style="color: #606060;"> 42:</span> <span style="color: #0000ff;">case</span> <span style="color: #006080;">"Interviews"</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="lnum43" style="color: #606060;"> 43:</span> imageUri = <span style="color: #006080;">"/Assets/Interview.png"</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="lnum44" style="color: #606060;"> 44:</span> <span style="color: #0000ff;">break</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="lnum45" style="color: #606060;"> 45:</span> <span style="color: #0000ff;">case</span> <span style="color: #006080;">"Windows Phone"</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="lnum46" style="color: #606060;"> 46:</span> imageUri = <span style="color: #006080;">"/Assets/WindowsPhone.png"</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="lnum47" style="color: #606060;"> 47:</span> <span style="color: #0000ff;">break</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="lnum48" style="color: #606060;"> 48:</span> <span style="color: #0000ff;">case</span> <span style="color: #006080;">"Silverlight"</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="lnum49" style="color: #606060;"> 49:</span> imageUri = <span style="color: #006080;">"/Assets/Silverlight.png"</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="lnum50" style="color: #606060;"> 50:</span> <span style="color: #0000ff;">break</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="lnum51" style="color: #606060;"> 51:</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="lnum52" style="color: #606060;"> 52:</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="lnum53" style="color: #606060;"> 53:</span> <span style="color: #0000ff;">return</span> imageUri;</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="lnum54" style="color: #606060;"> 54:</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="lnum55" style="color: #606060;"> 55:</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="lnum56" style="color: #606060;"> 56:</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="lnum57" style="color: #606060;"> 57:</span> <span style="color: #cc6633;">#endregion</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="lnum58" style="color: #606060;"> 58:</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="lnum59" style="color: #606060;"> 59:</span> <span style="color: #cc6633;">#region</span> <span style="color: #006080;">"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="lnum60" style="color: #606060;"> 60:</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="lnum61" style="color: #606060;"> 61:</span> <span style="color: #0000ff;">public</span> SLShowGroupedArticles()</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="lnum62" style="color: #606060;"> 62:</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="lnum63" style="color: #606060;"> 63:</span> ArticleCollection = <span style="color: #0000ff;">new</span> ObservableCollection<SLShowArticle>();</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="lnum64" style="color: #606060;"> 64:</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="lnum65" style="color: #606060;"> 65:</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="lnum66" style="color: #606060;"> 66:</span> <span style="color: #cc6633;">#endregion</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="lnum67" style="color: #606060;"> 67:</span> }</pre> <!--CRLF--></div> </div> <p>Did you notice the use of <em>BindableBase</em>? This is nothing but an <em>ObservableCollection</em> wrapper that makes it even easier to mark properties for <em>INotifyPropertyChanged</em> event bubbling.  This is just to take advantage of data-binding so that we can change the underlying collection and the UI updates itself. So, every article group is given a group name, a count for number of articles in the group, an <em>ArticleCollection</em> to actually hold the child articles and an <em>ImageURI</em> tied to the type of group. We’ll do all our data binding to the UI based on this class.</p> <p>So, now that we have the containers laid out, let’s get the data. This is where you get to write your custom logic to build a collection of items. Get it from the web or read from some database – your needs dictate how the collection is hydrated. In our case, we’ll have a collection of latest articles from SilverlightShow. Next, let’s define a collection of grouped article sets to hold our categorized buckets of items and see how we actually group the articles:</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: #008000;">// Defined for global access in app.</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="lnum2" style="color: #606060;"> 2:</span> <span style="color: #0000ff;">private</span> ObservableCollection<SLShowArticle> _articleCollection = <span style="color: #0000ff;">new</span> ObservableCollection<SLShowArticle>();</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: #0000ff;">private</span> ObservableCollection<SLShowGroupedArticles> _groupedArticleCollection;</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>  </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> <span style="color: #0000ff;">public</span> ObservableCollection<SLShowArticle> ArticleCollection</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> get { <span style="color: #0000ff;">return</span> _articleCollection; }</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> set { _articleCollection = <span style="color: #0000ff;">value</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>  </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> <span style="color: #0000ff;">public</span> ObservableCollection<SLShowGroupedArticles> GroupedArticleCollection</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> {</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> get</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> (_groupedArticleCollection == <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> _groupedArticleCollection = <span style="color: #0000ff;">new</span> ObservableCollection<SLShowGroupedArticles>();</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> <span style="color: #008000;">// Put Articles into Grouped buckets based on Topic.</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> var query = from individualArticle <span style="color: #0000ff;">in</span> ArticleCollection</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> orderby individualArticle.ArticleTopic</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> group individualArticle by individualArticle.ArticleTopic into g</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> select <span style="color: #0000ff;">new</span> SLShowGroupedArticles</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> {</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> SLShowArticleGroupName = g.Key,</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> SLShowArticleGroupCount = g.Count(),</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> ArticleCollection = <span style="color: #0000ff;">new</span> ObservableCollection<SLShowArticle>(g.ToList())</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> };</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>  </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> _groupedArticleCollection = <span style="color: #0000ff;">new</span> ObservableCollection<SLShowGroupedArticles>(query.ToList());</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="lnum30" style="color: #606060;"> 30:</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="lnum31" style="color: #606060;"> 31:</span> <span style="color: #0000ff;">return</span> _groupedArticleCollection;</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="lnum32" style="color: #606060;"> 32:</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="lnum33" style="color: #606060;"> 33:</span> set</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="lnum34" style="color: #606060;"> 34:</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="lnum35" style="color: #606060;"> 35:</span> _groupedArticleCollection = <span style="color: #0000ff;">value</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="lnum36" style="color: #606060;"> 36:</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="lnum37" style="color: #606060;"> 37:</span> }</pre> <!--CRLF--></div> </div> <p>Simple LINQ, right? Now that we have grouped data, let’s hand it off to our UI as is. But how about the smooth interaction of zooming in & out? Thankfully, there is a Metro control that has all that built in. Enter the <em>Semantic Zoom</em> control! Works on <em>GridView</em> or <em>ListView</em> that is bound to grouped data. We need to do two little things – define the <em>zoomed in</em> & <em>zoomed out</em> view of the data; the control would take care of the rest. A smooth cross-fade and scale animation is used for the transition from one semantic zoom level to another. This is the default Windows touch behavior and cannot be customized. Essentially, this is what we need to fill in:</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> <SemanticZoom></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> <SemanticZoom.ZoomedOutView></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> <!-- Put the GridView/Listview to make the zoomed-<span style="color: #0000ff;">out</span> view here. --> </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> </SemanticZoom.ZoomedOutView></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> <SemanticZoom.ZoomedInView></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> <!-- Put the GridView/Listview to make the zoomed-<span style="color: #0000ff;">in</span> view here. --> </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> </SemanticZoom.ZoomedInView></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>  </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> </SemanticZoom></pre> <!--CRLF--></div> </div> <p> </p> <p>Now, before we step into that, let's look at one other control, which doesn’t have an UI but is super helpful. That is the <em>CollectionViewSource</em>. A container to hold our grouped items collection. 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> <Page.Resources></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> <!-- Collection of grouped Articles displayed by <span style="color: #0000ff;">this</span> page --></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> <CollectionViewSource</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> x:Name=<span style="color: #006080;">"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: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span> Source=<span style="color: #006080;">"{Binding GroupedArticles}"</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> IsSourceGrouped=<span style="color: #006080;">"true"</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> ItemsPath=<span style="color: #006080;">"ArticleCollection"</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> </Page.Resources></pre> <!--CRLF--></div> </div> <p>Notice the <em>ItemsPath</em> .. it points to the same named collection of articles as in our <em>SLShowGroupedArticles</em> class. So, if this control is bound to the collection of grouped articles, it will keep track of each article group, as well as the articles inside each group. If this could be reused across pages, you could consider defining it in <em>App.xaml</em> for global accessibility. So, how do we feed data to this control? </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> OnNavigatedTo(NavigationEventArgs 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: #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: #0000ff;">base</span>.OnNavigatedTo(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: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</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> <span style="color: #008000;">// Set the Data-Binding context to the Grouped Article collection.</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;">this</span>.DefaultViewModel[<span style="color: #006080;">"GroupedArticles"</span>] = ((App)Application.Current).GroupedArticleCollection;</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: #008000;">// Support zoomed-out semantics.</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> var groupedArticles = groupedItemsViewSource.View.CollectionGroups;</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> (Zoomer.ZoomedOutView <span style="color: #0000ff;">as</span> ListView).ItemsSource = groupedArticles;</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--></div> </div> <p>As you can see, in the code behind & at run-time, we are handing off our data to the <em>CollectionViewSource</em> XAML control on the page and also to the zoomed-out view of the Semantic Zoom(<em>Zoomer</em>) . Also, notice the <em>DefaultViewModel</em> used in the hand-off? This little bit of magic comes as a benefit from the common <em>LayoutAwarePage</em> – take a peek in it to realize how every page is being wired up to have a default view model that acts as the <em>DataContext</em> for it’s UI. Next check the top of your XAML page, for a tiny bit of wire-up:</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> <common:LayoutAwarePage</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> x:Name=<span style="color: #006080;">"pageRoot"</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> x:Class=<span style="color: #006080;">"SilverLightShowDemo.ArticleList"</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> DataContext=<span style="color: #006080;">"{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"</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> .....</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--></div> </div> <p>Now, we are one step closer to using the grouped data in our Semantic Zoom control. First, let’s define the zoomed in view. Here’s some XAML:</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> <SemanticZoom.ZoomedInView></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> <GridView</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;">"itemGridView"</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;">"ItemGridView"</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> 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: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span> Margin=<span style="color: #006080;">"20,0,40,46"</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> 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: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span> ItemTemplate=<span style="color: #006080;">"{StaticResource SLShow250x100ArticleTemplate}"</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> <GridView.ItemsPanel></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> <ItemsPanelTemplate></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> <VirtualizingStackPanel 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: white;"><span id="lnum13" style="color: #606060;"> 13:</span> </ItemsPanelTemplate></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> </GridView.ItemsPanel></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> <GridView.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="lnum16" style="color: #606060;"> 16:</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="lnum17" style="color: #606060;"> 17:</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="lnum18" style="color: #606060;"> 18:</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="lnum19" style="color: #606060;"> 19:</span> <Grid Margin=<span style="color: #006080;">"1,0,0,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: #f4f4f4;"><span id="lnum20" style="color: #606060;"> 20:</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: white;"><span id="lnum21" style="color: #606060;"> 21:</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: #f4f4f4;"><span id="lnum22" style="color: #606060;"> 22:</span> <TextBlock Text=<span style="color: #006080;">"-"</span> Style=<span style="color: #006080;">"{StaticResource SubheaderTextStyle}"</span> VerticalAlignment=<span style="color: #006080;">"Top"</span> Margin=<span style="color: #006080;">"5,0,5,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="lnum23" style="color: #606060;"> 23:</span> <TextBlock Text=<span style="color: #006080;">"{Binding SLShowArticleGroupCount}"</span> Style=<span style="color: #006080;">"{StaticResource SubheaderTextStyle}"</span> VerticalAlignment=<span style="color: #006080;">"Top"</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> </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="lnum25" style="color: #606060;"> 25:</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="lnum26" style="color: #606060;"> 26:</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="lnum27" style="color: #606060;"> 27:</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="lnum28" style="color: #606060;"> 28:</span> <GroupStyle.Panel></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> <ItemsPanelTemplate></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="lnum30" style="color: #606060;"> 30:</span> <VariableSizedWrapGrid Orientation=<span style="color: #006080;">"Vertical"</span> Margin=<span style="color: #006080;">"0,0,100,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="lnum31" style="color: #606060;"> 31:</span> </ItemsPanelTemplate></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="lnum32" style="color: #606060;"> 32:</span> </GroupStyle.Panel></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="lnum33" style="color: #606060;"> 33:</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: #f4f4f4;"><span id="lnum34" style="color: #606060;"> 34:</span> </GridView.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="lnum35" style="color: #606060;"> 35:</span> </GridView></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="lnum36" style="color: #606060;"> 36:</span> </SemanticZoom.ZoomedInView></pre> <!--CRLF--></div> </div> <p>Let’s highlight a few things. First, the GridView’s <em>ItemSource</em> is actually bound to our <em>CollectionViewSource</em> defined before. Group headers can be custom constructed in the <em>GridView.GroupStyle</em>. How about the actual binding & rendering of individual items? This is done in the <em>ItemTemplate</em> as usual and is defined in the <em>StandardStyles.xaml</em> file for consistency & reusability. Here’s what I use; notice how the template starts out as a copy of the default template, but everything is customizable:</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> <!-- Zoomed-<span style="color: #0000ff;">in</span> Article List View --></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;">"SLShow250x100ArticleTemplate"</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 HorizontalAlignment=<span style="color: #006080;">"Left"</span> Width=<span style="color: #006080;">"250"</span> Height=<span style="color: #006080;">"100"</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 Orientation=<span style="color: #006080;">"Vertical"</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> Margin=<span style="color: #006080;">"5,5,15,2"</span> VerticalAlignment=<span style="color: #006080;">"Top"</span> TextWrapping=<span style="color: #006080;">"Wrap"</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> <TextBlock Text=<span style="color: #006080;">"{Binding ArticleTopic}"</span> Foreground=<span style="color: #006080;">"Orange"</span> Margin=<span style="color: #006080;">"5,0,15,10"</span> VerticalAlignment=<span style="color: #006080;">"Top"</span> FontSize=<span style="color: #006080;">"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: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</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="lnum9" style="color: #606060;"> 9:</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: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span> <StackPanel VerticalAlignment=<span style="color: #006080;">"Bottom"</span> Background=<span style="color: #006080;">"{StaticResource ListViewItemOverlayBackgroundThemeBrush}"</span> Height=<span style="color: #006080;">"30"</span> 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: white;"><span id="lnum11" style="color: #606060;"> 11:</span> <TextBlock Text=<span style="color: #006080;">"{Binding AuthorName}"</span> Foreground=<span style="color: #006080;">"{StaticResource ListViewItemOverlayForegroundThemeBrush}"</span> Style=<span style="color: #006080;">"{StaticResource TitleTextStyle}"</span> Margin=<span style="color: #006080;">"5,0,15,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="lnum12" style="color: #606060;"> 12:</span> <TextBlock Text=<span style="color: #006080;">"{Binding DisplayablePublishDate}"</span> Foreground=<span style="color: #006080;">"{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}"</span> Style=<span style="color: #006080;">"{StaticResource CaptionTextStyle}"</span> TextWrapping=<span style="color: #006080;">"NoWrap"</span> Margin=<span style="color: #006080;">"15,0,15,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: white;"><span id="lnum13" style="color: #606060;"> 13:</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="lnum14" style="color: #606060;"> 14:</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: white;"><span id="lnum15" style="color: #606060;"> 15:</span> </DataTemplate></pre> <!--CRLF--></div> </div> <p>And now, let’s define the zoomed-out view to show the group categories with overlay text:</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> <SemanticZoom.ZoomedOutView></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> <ListView VerticalAlignment=<span style="color: #006080;">"Center"</span> ItemTemplate=<span style="color: #006080;">"{StaticResource SLShow250x250ArticleTemplate}"</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> <ListView.ItemsPanel></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> <ItemsPanelTemplate></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 Orientation=<span style="color: #006080;">"Horizontal"</span> VerticalAlignment=<span style="color: #006080;">"Center"</span> Margin=<span style="color: #006080;">"30,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> </ItemsPanelTemplate></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> </ListView.ItemsPanel></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> </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="lnum9" style="color: #606060;"> 9:</span> </SemanticZoom.ZoomedOutView></pre> <!--CRLF--></div> </div> <p>The <em>ItemTemplate</em> is again abstracted out to <em>StandardStyles.xaml</em> for reusability:</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> <!-- Zoomed-<span style="color: #0000ff;">out</span> Article List View --></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;">"SLShow250x250ArticleTemplate"</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 HorizontalAlignment=<span style="color: #006080;">"Left"</span> Width=<span style="color: #006080;">"250"</span> Height=<span style="color: #006080;">"250"</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;">"{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}"</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> <Image Source=<span style="color: #006080;">"{Binding Group.ImageURI}"</span> Stretch=<span style="color: #006080;">"UniformToFill"</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> </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="lnum7" style="color: #606060;"> 7:</span> <StackPanel VerticalAlignment=<span style="color: #006080;">"Bottom"</span> Background=<span style="color: #006080;">"{StaticResource ListViewItemOverlayBackgroundThemeBrush}"</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 Group.SLShowArticleGroupName}"</span> Foreground=<span style="color: #006080;">"{StaticResource ListViewItemOverlayForegroundThemeBrush}"</span> Style=<span style="color: #006080;">"{StaticResource TitleTextStyle}"</span> Height=<span style="color: #006080;">"60"</span> Margin=<span style="color: #006080;">"15,0,15,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> </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="lnum10" style="color: #606060;"> 10:</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: white;"><span id="lnum11" style="color: #606060;"> 11:</span> </DataTemplate></pre> <!--CRLF--></div> </div> <p>Voila! Your data is now grouped into buckets & semantic zoom control is data bound and ready to delight the end user.</p> <h4>Conclusion</h4> <p>That’s it for today. The crux of this article was to talk about the need for Semantic Zooming in Windows 8 Metro apps and how to implement one in your application. We ended with ways you could customize the data templates to give your semantic zooming it’s own brand for a delightful UX.</p> <p>See you next time as we dive into some more controls & custom styling in Windows 8 Metro apps. Thanks for reading!</p> <p> </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-3.aspx editorial@silverlightshow.net (Samidip Basu ) http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-3.aspx#comments http://www.silverlightshow.net/items/Windows-8-Metro-Apps-The-8-Must-Know-Tricks-Day-3.aspx Mon, 23 Jul 2012 11:59: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 Windows 8 XAML Metro Apps with OData - 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/Windows-8-XAML-Metro-Apps-with-OData.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.aspx" data-count="horizontal" data-text="Reading the article 'Win8 XAML Metro Apps with OData - Part 1' by @samidip" data-url="http://slshow.net/tJIMTd">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData.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! 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>. </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> 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: <p> </p> <ul> <li><strong>Part 1 – Handling of OData from our XAML Metro App [Consumption & Updates to OData source]</strong></li> <li><strong></strong><a href="http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData-Part-2.aspx" target="_self"><strong>Part 2</strong> – How to make your XAML App a well-behaved Windows 8 citizen [Artwork, Snapped Views, Contracts, Application Bar etc]</a></li> </ul> <p>As always, the demo solution, along with all code samples is available for download through the link below:</p> <a href="http://www.silverlightshow.net/Storage/Sources/TeamMetro.zip"> <h4>Download Source Code</h4> </a> <p> </p> <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. </p> We could obviously talk a lot about Windows 8; but for the sake of the length of this blog post, let me refer you to 2 valuable resources: <p> </p> <ol> <li><em>BUILD</em> Website @ <a href="http://www.buildwindows.com/" title="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 href="http://msdn.microsoft.com/en-us/windows/home" title="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>Also, check out the overall technology stack in Windows 8 below: [Source: Doug Seven’s <a href="http://dougseven.com/2011/09/15/a-bad-picture-is-worth-a-thousand-long-discussions/" target="_blank">Post</a>]</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Windows%208%20Stack_2.png"><img width="644" height="364" title="Windows 8 Stack" style="border: 0px solid; background-image: none; display: inline;" alt="Windows 8 Stack" src="http://www.silverlightshow.net/Storage/Users/samidip/Windows%208%20Stack_thumb.png" /></a></p> <p>A lot has been written in the past few months about Win RT & the development stack in Windows 8 .. simple web searches should get us lots of resources. For this article & the demo app, we will stick to the managed world of XAML UI & C# code running on .NET 4.5 on top of Win RT. There might be some rough edges .. but we are all trying to learn, right? <img class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/_wlEmoticon-smile_2.png" /></p> <ol></ol> <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> <p> </p> <h2>The Data</h2> <p>Let’s try building a data-driven Metro App, shall we? For Demo purposes, I’m going to use a simple relational DB called “<em>Demo</em>” hosted in SQL Azure with just one table called “<em>Team</em>”, as shown below with schema/data:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/DataTable_2.png"><img width="644" height="351" title="DataTable" style="border: 0px solid; background-image: none; display: inline;" alt="DataTable" src="http://www.silverlightshow.net/Storage/Users/samidip/DataTable_thumb.png" /></a></p> <p>So essentially, we want to keep track of Team Members with Names & TwitterHandles. How can we get this data easily into a Windows 8 Metro App? Why off course, <em><strong>OData</strong></em> !!</p> <p>You may learn more about OData from <a href="http://www.odata.org/" title="http://www.odata.org/">http://www.odata.org/</a>. I already have an OData Service built on top of our DB to expose the Team table data as an OData feed for consumption. Need to expose your data as OData? – Check out Michael Crump’s great series on <a href="http://www.silverlightshow.net/items/Producing-and-Consuming-OData-in-a-Silverlight-and-Windows-Phone-7-application.aspx" target="_blank">Producing & Consuming OData in Silverlight & Windows Phone Applications</a>. </p> <p>Also, remember my article on <a href="http://www.silverlightshow.net/items/Connecting-Azure-Windows-Phone-through-OData.aspx" target="_blank">Connecting Azure & Windows Phone through OData</a> ? In that article, we talked about consuming OData from the same SQL Azure DB Table & also easily performing CRUD operations against data source through OData from a Windows Phone application. So essentially, we want to take the Windows Phone Demo application handling OData & port it over to being a Windows 8 Metro App in XAML & C#. You’ll soon realize that while we have to accommodate the UI having a lot more real estate in Windows 8, a lot of the coding artifacts are very similar or can be reused in the Windows 8 world with minor changes. If you have done Windows Phone Development, you should feel right at home in doing XAML Metro Apps!</p> <p>So, here’s the OData service endpoint which provides access to our Table data in AtomPub (default) or JSon format: </p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/OData%20Service_2.png"><img width="644" height="351" title="OData Service" style="border: 0px solid; background-image: none; display: inline;" alt="OData Service" src="http://www.silverlightshow.net/Storage/Users/samidip/OData%20Service_thumb.png" /></a></p> <h2>The Metro App</h2> <p>So, now that we have a data source & an OData service on top of it exposing the data, let’s see how we may consume it in a Windows 8 Metro App. Let’s fire up Visual Studio 11 & make our appropriate selections as below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Project%20Template_2.png"><img width="644" height="447" title="Project Template" style="border: 0px solid; background-image: none; display: inline;" alt="Project Template" src="http://www.silverlightshow.net/Storage/Users/samidip/Project%20Template_thumb.png" /></a></p> <p>The above selection gets us into a mode for building Metro Apps with XAML UI & C# code in a managed runtime. Just like in Windows Phone, the templates provided are your friends, as they get us a long way towards achieving Metro UI look & feel in our applications. For our demo, we shall choose to start with an empty application canvas & focus on fetching data into our app.</p> <p>Now, since we have an OData service, it’ll be nice to Add a Service Reference to the service in our project so that we know the backend entities & can refer to them in code. Ouch – too soon <img class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/_wlEmoticon-smile_2.png" /> The automatic proxy building against an OData service by adding a Service Reference isn’t quite ready in the Windows 8 tooling yet! So, we revert to the old-school way of adding our service reference into the project:</p> <pre><em><code>DataSvcUtil.exe /uri:Your_OData_Endpoint/out:TeamModel.cs /Version:2.0 /DataServiceCollection</code></em></pre> <p> </p> <p>As you could see, we used the DataSvcUtil tool (tucked away in your .NET Framework folder) to generate a proxy class which has all the entity bindings .. now we could simply drop the generated file into our project. Our project structure looks something like this .. the “Package.appxmanifest” file quite simply houses all your App configuration:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Project%20Stucture.png"><img width="304" height="389" title="Project Stucture" style="border: 0px solid; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="Project Stucture" src="http://www.silverlightshow.net/Storage/Users/samidip/Project%20Stucture_thumb.png" /></a></p> <h2>The UI</h2> <p>Don’t you wish you were working with a Team where every member is a Ninja? Well, let’s say that’s the case & we shall shoot for our Metro App UI to be something simple, like this:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Team%20List_2.png"><img width="644" height="364" title="Team List" style="border: 0px solid; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="Team List" src="http://www.silverlightshow.net/Storage/Users/samidip/Team%20List_thumb.png" /></a></p> <p>The above screenshot is our Demo app running in the normal full-screen immersive UI mode. Notice how it is completely Chrome-free & puts content first.  Just because we can clutter the UI with all kinds of controls, doesn’t mean that we should, right?</p> <p>So, in our app, there is one & only XAML page that does the above rendering, that being <em>MainPage.xaml</em>. Here’s the XAML that drives the UI:</p> <div id="codeSnippetWrapper" 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;"> <div id="codeSnippet" 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;"> <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> <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: 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 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: #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> <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="lnum15" style="color: #606060;"> 15:</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="lnum16" style="color: #606060;"> 16:</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: 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> <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: #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> <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: 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> <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: #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> <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: 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></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> </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="lnum23" style="color: #606060;"> 23:</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="lnum24" style="color: #606060;"> 24:</span> </ListBox></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></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>  </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> </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="lnum28" style="color: #606060;"> 28:</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="lnum29" style="color: #606060;"> 29:</span> </UserControl></pre> <!--CRLF--></div> </div> <p>So, we essentially defined a ListBox & we are expecting it to be bound to some collection of Team members with appropriate property values. Did you notice that except for a few namespaces, the XAML markup is very similar to what we are used to seeing in Windows Phone & Silverlight applications? This is what should make you feel right at home .. there are off course, some Windows 8 specific UI controls, which can cover in a subsequent blog post. </p> <p>Another point to note is that the XAML markup for Windows 8 Metro apps can be borrowed to a large extent if you have existing Windows Phone or Silverlight applications. In fact, if you have a a Windows Phone app in the Marketplace and simply want to port to over to the Windows 8 App Store, there are a fixed set of guidelines to do so, as explained <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465136(v=VS.85).aspx" target="_blank">here</a>. However, we might need to be wary of a plain port-over & the UX of our Metro apps, since the Windows 8 tablet form factor will have substantially more real estate, which should absolutely be utilized. In our demo app, you see a simple list of data items consuming OData; while ok for a demo (see I excuse myself <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/_wlEmoticon-smile_2.png" />), you ideally want to provide your users with a richer experience.</p> <h2>Fetching the Data</h2> <p>Now, this will be very interesting. One of the buzz terms with Windows Phone/Silverlight and now heavily so with Windows 8 is “<em>fast & fluid</em>” – which essentially means that your App may be doing some expensive operation; but to the end user interacting through Touch, it should always seem responsive. Asynchronous Programming is certainly not new & Windows Phone development very much enforces that; however, it may be a little painful at times, specially if you are marshaling data between threads or writing callback after callback.</p> <p>Win RT enforces that any operation that might take more than 50 ms be done asynchronously, and this off course, extends to every web request our app might make. So, we are looking to fetch the OData feed asynchronously without blocking the UI thread.</p> <p>Now, C# 5.0 running on .NET 4.5 framework tries to make it easy for us developers to do asynchronous programming through <em><strong>Async-Await</strong></em> patterns, so that we can get around not writing callback after callback  or have to deal with thread marshaling. This however is a wider topic than this post – so please allow me to point you to some resources that should help understand this better:</p> <ul> <li><a href="http://msdn.microsoft.com/en-us/library/hh191443(v=VS.110).aspx">http://msdn.microsoft.com/en-us/library/hh191443(v=VS.110).aspx</a> </li> <li><a href="http://msdn.microsoft.com/en-us/vstudio/async.aspx">http://msdn.microsoft.com/en-us/vstudio/async.aspx</a> </li> <li><a href="http://msdn.microsoft.com/en-us/magazine/hh456402.aspx">http://msdn.microsoft.com/en-us/magazine/hh456402.aspx</a> </li> </ul> <p>I was intrigued about Asynchrony and wrote a lengthy post; if interested, you’ll find it <a href="http://samidipbasu.com/2011/10/10/asynchrony-for-the-wpsilverlight-developer/" target="_blank">HERE</a>. So, let’s look at a few ways we can fetch data:</p> <h5>The Pure HTTP Way</h5> <p>In this approach, we make a basic HTTP Get call to our OData service endpoint & fetch data as Atom. This is simple, but we would have to manually parse the response to pluck out the data contents for binding to UI. Here’s some sample code .. watch the use of async-await to achieve asynchrony:</p> <div id="codeSnippetWrapper" 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;"> <div id="codeSnippet" 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;"> <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> async <span style="color: #0000ff;">void</span> LoadTeamThruXML()</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: #008000;">// Get Atom over HTTP.</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> var client = <span style="color: #0000ff;">new</span> HttpClient();</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> Uri teamDataURI = <span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"Your_OData_Endpoint"</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>  </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;">try</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> HttpResponseMessage response = await client.GetAsync(teamDataURI);</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;">string</span> xmlResponse = response.Content.ReadAsString();</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> XDocument xDoc = XDocument.Parse(xmlResponse);</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> <span style="color: #008000;">// Do appropriate parsing.</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;">// LINQ to XML.</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> IEnumerable<Team> teamCollection = from teamMember <span style="color: #0000ff;">in</span> xDoc.Descendants(<span style="color: #006080;">"Entry"</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> select <span style="color: #0000ff;">new</span> Team</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> Name = teamMember.Element(<span style="color: #006080;">"Name"</span>).ToString(),</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> TwitterHandle = teamMember.Element(<span style="color: #006080;">"TwitterHandle"</span>).ToString()</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> };</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>  </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> <span style="color: #008000;">// Bind 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="lnum24" style="color: #606060;"> 24:</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="lnum25" style="color: #606060;"> 25:</span> <span style="color: #0000ff;">catch</span> (Exception ex)</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> {</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> <span style="color: #008000;">// Oopsie</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> }</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> }</pre> <!--CRLF--></div> </div> <h5>The Threaded Way</h5> <p>One important aspect about Asynchrony is that it does not always mean multi-threading, as in parallelism. All the goodness of the <em>Task Parallel Library</em> is now built in and as we await on a <em>Task</em>, the underlying implementation may or may not spin up a new thread based on computing cycles needed. The point is, you should not have to care as a developer. However, if using <em>Task.Factory</em>, you are essentially carrying out synchronous operations on a worker thread without blocking the UI. So, here’s another way to fetch data .. notice how we can return a strongly-typed collection of <em>Team</em> members:</p> <div id="codeSnippetWrapper" 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;"> <div id="codeSnippet" 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;"> <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> async <span style="color: #0000ff;">void</span> LoadTeamThruOData()</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> var client = <span style="color: #0000ff;">new</span> Demo(<span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"Your_OData_Endpoint"</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> var results = await Task<IEnumerable<Team>>.Factory.StartNew(() => FetchOData());</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;">// This fires only after we have a response back. </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>.ParseAndBindData(results);</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>  </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;">private</span> IEnumerable<Team> FetchOData()</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> Demo client = <span style="color: #0000ff;">new</span> Demo(<span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"Your_OData_Endpoint"</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> <span style="color: #0000ff;">return</span> client.Teams.Execute();</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--></div> </div> <h5>Wrapped APM Way</h5> <p>Asynchronous Programming Model (<em>APM</em>) is the traditional way of doing asynchrony through <em>BeginXX/EndXX</em> patterns; but this lead us to write a lot of callbacks. In the new world, APM calls can be wrapped inside an Async-Await pattern to make asynchronous requests. Let’s look at some code:</p> <div id="codeSnippetWrapper" 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;"> <div id="codeSnippet" 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;"> <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> async <span style="color: #0000ff;">void</span> LoadTeamThruOData()</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> var client = <span style="color: #0000ff;">new</span> Demo(<span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"Your_OData_Endpoint"</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> var results = await Task<IEnumerable<Team>>.Factory.FromAsync(client.Teams.BeginExecute(AnotherEndContinuation, client), ContinuationDelegate);</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;">// This fires only after we have a response back. </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>.ParseAndBindData(results);</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>  </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> Func<IAsyncResult, IEnumerable<Team>> ContinuationDelegate = EndContinuation;</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: #0000ff;">private</span> <span style="color: #0000ff;">static</span> IEnumerable<Team> EndContinuation(IAsyncResult result)</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> Demo client = (Demo)result.AsyncState; </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: #0000ff;">return</span> client.Teams.EndExecute(result);</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> }</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>  </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> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> AnotherEndContinuation(IAsyncResult result)</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> <span style="color: #008000;">// Do nothing here.</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> }</pre> <!--CRLF--></div> </div> <p>Now, the above code might look a little clunky, but the wrapping of the APM methods can be done through an Extension method to make reuse easier. Eventually with future updates, if we have a method <em>Foo</em> in our custom WCF Service, proxy integration should generate three method endpoints – <em>BeginFoo</em>, <em>EndFoo</em> & <em>FooAsync</em>. It is the last that we shall use comfortably with Async-Await patterns. </p> <h2></h2> <h2></h2> <h2>Data Updates?</h2> <p>So, by now we know how to fetch OData into a Windows 8 Metro app using XAML/C# and bind the results to a simple list. But what if we wanted to perform updates against the data source? That is absolutely possible since we are dealing with an OData service here. Unless blocked at the service side, OData will support full CRUD operations through the <em>DataServiceContext</em> & <em>DataServiceCollection</em> classes.</p> <p>Now, let’s think about the UI for second. Just because we can put buttons & controls for data updates all over, doesn’t mean that we should. Common tasks should be presented in a minimalist fashion & accessible when needed. Accordingly, we revert to using the Windows 8 Metro Application Bar to add some metro buttons for allowing data manipulation. Let’s shoot for a UI like below .. we shall talk more about the Application Bar in the next article:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/TeamList%20%20with%20App%20Bar_2.png"><img width="644" height="364" title="TeamList with App Bar" style="border: 0px solid; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="TeamList with App Bar" src="http://www.silverlightshow.net/Storage/Users/samidip/TeamList%20%20with%20App%20Bar_thumb.png" /></a></p> <p>So, what happens when the user hits the Application Bar buttons? Simple – just like in Windows Phone, you can have event handlers assigned to each. Let’s see how we may delete a record & have it reflected in the OData data source, that is our Table data in SQL Azure. Here’s some code:</p> <div id="codeSnippetWrapper" 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;"> <div id="codeSnippet" 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;"> <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> DeleteButton_Click(<span style="color: #0000ff;">object</span> sender, RoutedEventArgs e)</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> Team selectedTeamMember = (Team)<span style="color: #0000ff;">this</span>.fullTeamList.SelectedItem;</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;">// LINQ to Context.</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> var client = <span style="color: #0000ff;">new</span> Demo(<span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"Your_OData_Endpoint"</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> var teamMemberToDelete = (from TeamMember <span style="color: #0000ff;">in</span> client.Teams</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: #0000ff;">where</span> TeamMember.Name == selectedTeamMember.Name</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> select TeamMember).First();</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: #008000;">// Delete backend entity.</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> client.DeleteObject(teamMemberToDelete);</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> client.BeginSaveChanges(<span style="color: #0000ff;">new</span> AsyncCallback(SaveDoneCB), client); </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> }</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> }</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> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> SaveDoneCB(IAsyncResult asyncResult)</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--> <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> <span style="color: #008000;">// Any error handling.</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> }</pre> <!--CRLF--></div> </div> <p>What about adding/editing records? Exactly the same way. Off of our “<em>client</em>” object above (which is in essence the <em>DataServiceContext</em>), you’ll see methods like <em>AddObject</em> & <em>UpdateObject</em> to insert/manipulate table records and then you simply need to call <em>SaveChanges</em> asynchronously to update the backend DB. You’ll see some sample code in the downloadable solution; but why not give it a shot yourself? You can get a lot of hints about how to perform CRUD operations against OData from a Windows Phone application from mine & Michael Crump’s articles <a href="http://www.silverlightshow.net/items/Connecting-Azure-Windows-Phone-through-OData.aspx" target="_blank">HERE</a> & <a href="http://www.silverlightshow.net/items/Producing-and-Consuming-OData-in-a-Silverlight-and-Windows-Phone-7-application-Part-4.aspx" target="_blank">HERE</a>. So, go ahead & throw in a fresh XAML page to capture inserts/edits & fire away <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/_wlEmoticon-smile_2.png" />.</p> <h2>Summary</h2> <p>In this 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. 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 the next part of article, we shall talk 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><a href="http://www.silverlightshow.net/Storage/Users/samidip/_ActualPic.jpg"><img width="104" height="126" title="ActualPic" style="border: 0px solid; background-image: none; margin: 0px 15px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; padding-top: 0px;" alt="ActualPic" src="http://www.silverlightshow.net/Storage/Users/samidip/_ActualPic_thumb.jpg" /></a>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.aspx editorial@silverlightshow.net (Samidip Basu ) http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData.aspx#comments http://www.silverlightshow.net/items/Windows-8-XAML-Metro-Apps-with-OData.aspx Wed, 07 Dec 2011 09:59:00 GMT 10 Laps around Silverlight 5 (Part 8 of 10) <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.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/10-Laps-around-Silverlight-5-Part-8-of-10.aspx" data-count="horizontal" data-text="Reading SilverlightShow article '10 Laps around Silverlight 5 (Part 8 of 10)' by @mbcrump #sl5" data-url="http://slshow.net/tf6K6i">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <div style="border:1px solid #dddddd;border-image: initial; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px; text-align: center;"><em><strong>This article is sponsored by <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Click&Mode=HTML&SiteID=1&PageID=41808" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Get&Mode=HTML&SiteID=1&PageID=41808" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik RadControls for Silverlight</a>. For similarly awesome content check out <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Click&Mode=HTML&SiteID=1&PageID=3019" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Get&Mode=HTML&SiteID=1&PageID=3019" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik XAMLflix</a>, your step-by-step guide to Telerik Silverlight and WPF controls. Get access to video tutorials, written tutorials, and tons of code! </strong></em></div> <p> To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</p> <p>This article is Part 8 of the series “10 Laps around Silverlight 5.” If you have missed any other section then please see the Roadmap below. <br /> <br /> </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/news/Free-Silverlight-Show-Webinar-Introduction-to-XAML-Development-on-Windows-8.aspx">Upcoming Webinar on Nov 29th: XAML Development on Windows 8</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; border-image: initial;" 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></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> To refresh your memory on what Silverlight is: <p>Microsoft Silverlight is an application framework for writing Rich Internet Applications. </p> The run-time environment is available as a plug-in for most web browsers and works on a variety of operating systems including Windows, Mac and Linux. <p>To recap what we learned in the previous section:</p> <ul> <li>We learned how you could specify a default filename when using the SaveFileDialog prompt. We also discussed how you could run the application in elevated trust to prevent the security warning from being displayed.  </li> <li>We then took a look at 64-bit browser support that is included with Silverlight 5 and learned that if your user is using a 64-bit browser then they will be redirected to a location to download the Silverlight 5 x64 runtime.  </li> <li>We wrapped up a short section on new and improved power awareness for media applications. </li> </ul> <p>In this article, I am going to discuss productivity and performance enhancements in Silverlight 5 including: XAML Binding Debugging, Parser Performance Improvements and Multi-core JIT for improved start-up time. Please review the Roadmap for the series before going any further.</p> <h3>The Roadmap for this Series</h3> <p>I’ve included the Roadmap for the series below as you may want to visit other sections as you learn Silverlight 5. I picked the following features as I thought that you may find them useful in your day-to-day work. If you want a specific topic covered then please leave it in the comments below.</p> <p>1) <strong><a href="http://www.silverlightshow.net/items/Silverlight-5-Part-1-of-10.aspx">Introduction to SL5 – This post which provides a brief history of Silverlight and relevant links.</a></strong> </p> <p>2) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-2-of-10.aspx">Binding- Ancestor Relative Source Binding and Implicit Data Templates.</a></strong></p> <p>3) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-3.aspx" target="_self"><strong>Graphics</strong> <strong>–XNA 3D API and Improved Graphics Stack</strong>.</a></p> <p>4) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-4-of-10.aspx">Media - Low-Latency Sound using XNA and Remote Control and Media Command (Keys) Support.</a></strong></p> <p>5) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx">Text - Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions.</a></strong></p> <p>6) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx">Operating System Integration - Part 1 - P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust.</a></strong></p> <p>7) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.aspx">Operating System Integration - Part 2 - Default Filename for SaveFileDialog, 64-bit browser support and Power Awareness.</a></strong></p> <p>8) <strong>Productivity and Performance [This post] - </strong>XAML Binding Debugging, Parser Performance Improvements and Multi-core JIT for improved start-up time.</p> <p>9) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-9-of-10.aspx">Controls - Double and Triple click support, PivotViewer and ComboBox Type-Ahead.</a></strong></p> <p>10) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-10-of-10.aspx" target="_self"><strong>Other items</strong> - In-Browser HTML, PostScript and Tasks for TPL.</a></p> <h3></h3> <h3>XAML Binding Debugging</h3> <p>XAML Binding Debugging, is one of the most important features in the Silverlight 5. We have all been stuck with Binding expressions at one point or another and wanted an easier way to debug them. Now anywhere that you see a {<strong>Binding</strong>} expression you can put a break point on it just like your typical C# code. Let’s take a look at a sample:</p> <p>Fire up a new Silverlight 5 project and give it any name that you want. </p> <p>Go ahead and add a new class to the project named <strong>Podcast.cs</strong> and add the following code.</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;">public</span> <span style="color: #0000ff;">class</span> Podcast</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> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Description { get; set; }</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> <span style="color: #0000ff;">public</span> DateTime ReleaseDate { get; set; }</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> <span style="color: #0000ff;">public</span> Uri Link { get; set; }</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="lnum6" style="color: #606060;"> 6:</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="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;">public</span> Podcast(<span style="color: #0000ff;">string</span> description, DateTime releasedate, Uri link)</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="lnum8" style="color: #606060;"> 8:</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="lnum9" style="color: #606060;"> 9:</span> Description = description;</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="lnum10" style="color: #606060;"> 10:</span> ReleaseDate = releasedate;</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="lnum11" style="color: #606060;"> 11:</span> Link = link;</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="lnum12" style="color: #606060;"> 12:</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="lnum13" style="color: #606060;"> 13:</span> }</pre> <!--CRLF--></div> </div> <p>Let’s switch back over to the MainPage.xaml.cs and add the following code:</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;">public</span> MainPage()</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> InitializeComponent();</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> Loaded += <span style="color: #0000ff;">new</span> RoutedEventHandler(MainPage_Loaded);</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> }</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="lnum6" style="color: #606060;"> 6:</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="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;">void</span> MainPage_Loaded(<span style="color: #0000ff;">object</span> sender, RoutedEventArgs e)</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="lnum8" style="color: #606060;"> 8:</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="lnum9" style="color: #606060;"> 9:</span> <span style="color: #0000ff;">this</span>.DataContext =</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="lnum10" style="color: #606060;"> 10:</span> <span style="color: #0000ff;">new</span> Podcast(<span style="color: #006080;">"This Developer's Life - Criticism"</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="lnum11" style="color: #606060;"> 11:</span> <span style="color: #0000ff;">new</span> DateTime(2011, 4, 21),</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="lnum12" style="color: #606060;"> 12:</span> <span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"http://thisdeveloperslife.com/post/2-0-1-criticism"</span>, UriKind.Absolute)</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="lnum13" style="color: #606060;"> 13:</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="lnum14" style="color: #606060;"> 14:</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="lnum15" style="color: #606060;"> 15:</span> }</pre> <!--CRLF--></div> </div> <p>Switch back over to the MainPage.xaml and add in the following code replacing the current Grid:</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;">Grid</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="LayoutRoot"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="White"</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;">StackPanel</span> <span style="color: #ff0000;">Orientation</span><span style="color: #0000ff;">="Vertical"</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;">TextBlock</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding Description}"</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="lnum4" style="color: #606060;"> 4:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="txtReleaseDate"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding ReleaseDate}"</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="lnum5" style="color: #606060;"> 5:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">HyperlinkButton</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Listen to this Episode"</span> <span style="color: #ff0000;">NavigateUri</span><span style="color: #0000ff;">="{Binding Lik}"</span> <span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="_blank"</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="lnum6" style="color: #606060;"> 6:</span> <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 id="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>While here, go ahead and put a break point on the “Hyperlink" button line, which you can do by clicking outside its margin as shown below:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_______1_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="1" alt="1" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_______1_thumb.png" width="596" height="199" /></a></p> <p>Notice the Red Circle and the highlighted “<strong>Binding</strong>” word? The Visual Studio 2010 debugger will stop once the XAML parser hits that line. </p> <p><em>Please note that if you try to put a breakpoint on any line outside of the “Binding” keyword, then you will get a message saying, “This is not a valid location for a breakpoint” at the bottom of your screen:</em></p> <p>We are now ready to begin debugging, so, press “F5” on your keyboard to begin. You will notice that the Binding breakpoint was hit. If you examine your <strong>Locals window</strong> then you will see the following: </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_________2_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="2" alt="2" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_________2_thumb.png" width="655" height="167" /></a></p> <p>It looks like we have an error in our Binding statement that is telling us the property <strong>‘Lik’</strong> does not exist on the class called Podcast. If you continue running the application then you will quickly notice that the webpage launches but the “Listen to this Episode” hyperlink does not work. </p> <p>If we take a quick look at our <strong>Podcast</strong> class then we will notice that the property is actually called <strong>Link</strong>. If we go back to our MainPage.xaml and change </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;">HyperlinkButton</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Listen to this Episode"</span> <span style="color: #ff0000;">NavigateUri</span><span style="color: #0000ff;">="{Binding Lik}"</span> <span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="_blank"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--></div> </div> <p>to</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;">HyperlinkButton</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Listen to this Episode"</span> <span style="color: #ff0000;">NavigateUri</span><span style="color: #0000ff;">="{Binding Link}"</span> <span style="color: #ff0000;">TargetName</span><span style="color: #0000ff;">="_blank"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--></div> </div> and run our application again it will work properly. <p>It is very easy to debug Binding expressions now with that feature. Another undocumented feature is that if you have Silverlight 5 installed then you can also<span style="text-decoration: underline;"> debug your</span> <span style="text-decoration: underline;">Silverlight 4 binding statements</span>! Sweet!</p> <h3>Productivity and Performance Improvements</h3> <br /> Silverlight 5 contains many additional performance improvements that you may not be aware of. I have decided to create a short list here: <br /> <br /> <ul> <li>Reduced network latency by using a background thread for networking. </li> <li>Hardware acceleration is enabled in windowless mode with Internet Explorer 9. </li> <li>XAML parser improvements that speed up startup and runtime performance. </li> <li>Support for 64-bit operating systems as discussed in part 7 of this series. </li> <li>Multi-core JIT for improved startup time. </li> <li>Increased performance of hardware decoding and presentation of H.264 media for lower-power devices. </li> <li>Text layout performance improvements </li> </ul> <p>As you can see the Silverlight Team has been hard at work not only adding additional features to Silverlight 5 but improving performance all around.</p> <h3>Conclusion</h3> <p>At this point, we have seen how you would debug binding statements using Silverlight 5’s built-in XAML debugger. We also looked at several productivity and performance improvements in Silverlight 5. In the next part of the series, I am going to take a look at several new controls/features shipping with Silverlight 5 including : Double and Triple click support, PivotViewer and ComboBox Type-Ahead.  Again, thanks for reading and please come back for the next part.</p> <p>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</p> http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.aspx editorial@silverlightshow.net (Michael Crump ) http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.aspx#comments http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.aspx Tue, 29 Nov 2011 12:18:00 GMT OData caching in Windows Phone <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/OData-caching-in-Windows-Phone.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/OData-caching-in-Windows-Phone.aspx" data-count="horizontal" data-text="Reading SilverlightShow article 'OData caching in Windows Phone' by @samisip #wpdev" data-url="http://slshow.net/vbrKJG">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/OData-caching-in-Windows-Phone.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p><em>OData</em> seems to have a lot of promise in simplifying data access across multiple platforms by using fundamental technologies of <em>HTTP</em> and <em>Atom</em>/<em>JSon</em>. Using an OData source for data consumption/updates in your Windows Phone application? </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-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/shows/Recording-of-SilverlightShow-Webinar-by-Emil-Stoychev.aspx">Webinar recording: Building LOB apps with Silverlight and WCF Data Services</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 alt="Producing and Consuming OData in a Silverlight and WP7 App Ebook" src="http://www.silverlightshow.net/Storage/Ebooks/odata_cloud.png" style="width: 107px; height: 150px;" /></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 short article, we take a quick look at a data caching strategy in our Windows Phone applications while using an OData data source. While we talk about a Windows Phone solution in particular, these concepts are perfectly applicable when using OData on other mobile platforms. <p> </p> <p>As always, the demo solution, along with all code samples is available for download through the link below:</p> <a href="http://www.silverlightshow.net/Storage/Sources/NetflixDataHandlingDemo.zip"> <h4>Download Source Code</h4> </a> <h2> </h2> <h3>Introduction</h3> <p>The Open Data Protocol (OData) is an HTTP-based protocol for querying and updating a data source. Based on the platform or type of application we are building, we have the option of using either Atom or JSon as our feed protocol of choice and then utilize support for filtering, sorting & paging in our application. Want to learn more? <a href="http://www.odata.org/">http://www.odata.org/</a>is a great place to start. OData has now built up a nice ecosystem around it’s support, with proxy-building libraries in a variety of platforms; and it obviously lends itself very nicely to usage from mobile applications.</p> <p>Also, just about any data source that .NET runtime can connect to, can be exposed as an OData feed. It is essentially a two-step process: First – put Entity Framework type Object Relational Mapping (ORM) on top of our data source, in particular the <em>ADO.NET Entity Data Model</em>; and Second – put a <em>WCF Data Service</em> on top of the data entities to expose a read-only/updateable feed for the data. Want to try it yourself? Michael Crump’s “Producing & Consuming OData..” series <a href="http://www.silverlightshow.net/items/Producing-and-Consuming-OData-in-a-Silverlight-and-Windows-Phone-7-application.aspx" target="_blank">here</a> is a great start. Want to leverage OData as you augment your mobile application with cloud support? My last two articles <a href="http://www.silverlightshow.net/items/Connecting-Azure-Windows-Phone-through-OData.aspx" target="_blank">here</a> & <a href="http://www.silverlightshow.net/items/Azure-Services-connecting-Windows-Phone-to-Data.aspx" target="_blank">here</a> should be decent starting points.</p> <h3> </h3> <h3>The Demo </h3> <p>One of the best ways to learn more about OData is to start playing with a live OData service. And what better example than that of <em>Netfllix</em> .. we all love movies, right? <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/wlEmoticon-smile_2.png" /> Now, Netflix worked with MSFT to expose their entire Movie/Shows catalog as a live OData feed, one that you can hit through the URL below:</p> <h5><a href="http://odata.netflix.com/v2/Catalog/">http://odata.netflix.com/v2/Catalog/</a></h5> <p>Once we look up the catalog, we can see all the supported HTTP endpoints to get various information. Head over to the official Netlfix documentation <a href="http://developer.netflix.com/docs/oData_Catalog" target="_blank">here</a> to learn more about the supported Metadata, filters & formats. For our demo purpose, we shall choose to do a very simple lookup against the Netflix OData catalog .. just to get a list of <em>Genres</em>. Take a guess how many Genres Netflix knows? – Close to 400 !!</p> <p>So, we make a simple HTTP Get request through our browser to the following URI to get a list of Genres, in default Atom format. Since this is not huge amount of data, there is no continuation token & we get the whole catalog of Genres back in one request:</p> <h5><a href="http://odata.netflix.com/v2/Catalog/Genres">http://odata.netflix.com/v2/Catalog/Genres</a></h5> <p>So, let’s build a simple Windows Phone application which consumes the Netflix OData feed & pulls up the list of Genres programmatically. We begin with the default template of a Windows Phone application with a portrait page. One of the first things we do is to add a reference to the root of the Netflix OData service, so that the proxies are built & we can refer to the Netflix entities in our code. Here’s how & the resulting project structure:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Netflix%20Service%20Reference_2.png"><img width="644" height="521" title="Netflix Service Reference" style="border:0px solid; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="Netflix Service Reference" src="http://www.silverlightshow.net/Storage/Users/samidip/Netflix%20Service%20Reference_thumb.png" /></a></p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Project%20Structure.png"><img width="504" height="406" title="Project Structure" style="border:0px solid; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="Project Structure" src="http://www.silverlightshow.net/Storage/Users/samidip/Project%20Structure_thumb.png" /></a></p> <p>Next, let’s add some code to our <em>MainPage.xaml</em>’s code-behind file so we can load the list of Netflix Genres:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;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;"> <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 id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">using</span> NetflixODataService; </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> DataServiceCollection<Genre> Genres { get; set; }</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> DataServiceContext context = <span style="color: #0000ff;">new</span> DataServiceContext(<span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"http://odata.netflix.com/v2/Catalog/"</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>  </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="lnum6" style="color: #606060;"> 6:</span> <span style="color: #0000ff;">public</span> MainPage()</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="lnum7" style="color: #606060;"> 7:</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="lnum8" style="color: #606060;"> 8:</span> InitializeComponent();</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="lnum9" style="color: #606060;"> 9:</span> <span style="color: #0000ff;">this</span>.LoadAndStoreGenres();</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="lnum10" style="color: #606060;"> 10:</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="lnum11" style="color: #606060;"> 11:</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="lnum12" style="color: #606060;"> 12:</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="lnum13" style="color: #606060;"> 13:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> LoadAndStoreGenres()</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="lnum14" style="color: #606060;"> 14:</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="lnum15" style="color: #606060;"> 15:</span> <span style="color: #008000;">// Instantiates our collection.</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="lnum16" style="color: #606060;"> 16:</span> <span style="color: #0000ff;">this</span>.Genres = <span style="color: #0000ff;">new</span> DataServiceCollection<Genre>(context);</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="lnum17" style="color: #606060;"> 17:</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="lnum18" style="color: #606060;"> 18:</span> <span style="color: #008000;">// Base HTTP endpoint or custom query goes here.</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="lnum19" style="color: #606060;"> 19:</span> Uri uriQuery = <span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"/Genres()"</span>, UriKind.Relative);</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="lnum20" style="color: #606060;"> 20:</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="lnum21" style="color: #606060;"> 21:</span> <span style="color: #008000;">// Asynchronously load the result of the query.</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="lnum22" style="color: #606060;"> 22:</span> <span style="color: #0000ff;">this</span>.Genres.LoadAsync(uriQuery);</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="lnum23" style="color: #606060;"> 23:</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="lnum24" style="color: #606060;"> 24:</span> <span style="color: #0000ff;">this</span>.Genres.LoadCompleted += (sender, args) =></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="lnum25" style="color: #606060;"> 25:</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="lnum26" style="color: #606060;"> 26:</span> <span style="color: #0000ff;">if</span> (args.Error == <span style="color: #0000ff;">null</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="lnum27" style="color: #606060;"> 27:</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="lnum28" style="color: #606060;"> 28:</span> <span style="color: #008000;">// Databind.</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="lnum29" style="color: #606060;"> 29:</span> <span style="color: #0000ff;">this</span>.genreList.ItemsSource = <span style="color: #0000ff;">this</span>.Genres;</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="lnum30" style="color: #606060;"> 30:</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="lnum31" style="color: #606060;"> 31:</span> }</pre> <!--CRLF--></div> </div> <p>Now, let’s dig in, since a few interesting things happened. First, we added the reference to the Netflix Service namespace and utilized a special collection class called <em>DataServiceCollection</em>. A <em>DataServiceCollection<T></em> “represents a dynamic entity collection that provides notifications when items get added, removed, or when the list is refreshed.” So essentially, this has the features of an <em>ObservableCollection</em> built-in & the <em>INotifyPropertyChanged</em> interface makes sure that any UI bound to such a collection is informed of changes on bound property values in the collection. In addition, the DataServiceCollection has been optimized to be the representation of an OData HTTP endpoint collection and supports features like query collections, continuation tokens & tracking changes in the collection. Find out more about the DataServiceCollection <a href="http://msdn.microsoft.com/en-us/library/ee474331.aspx" target="_blank">here</a>.</p> <p>Also, we used a <em>DataServiceContext</em> which pointed to the root of the Netflix OData feed as the base context, beyond which we can do our queries/filtering/sorting. Also, once we knew exactly the query to request (in our simple demo – “/Genres()”), we used a <em>LoadAsync()</em> method off of our DataServiceCollection. This, behind the scenes, wraps up our query into an HTTP request to the OData service and does so without blocking the all-important UI thread. When the remote server responds, a <em>LoadCompleted</em> event triggers to allow us to handle the response & bind to our UI, thus automatically marshaling data back to the UI thread. </p> <p>Now, how do we display the list of Genres we are fetching? Through a very simple XAML UI as below:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;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;"> <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 id="lnum1" style="color: #606060;"> 1:</span> <ListBox Margin=<span style="color: #006080;">"15,0,15,10"</span> x:Name=<span style="color: #006080;">"genreList"</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> <ListBox.ItemTemplate></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> <DataTemplate></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> <StackPanel Margin=<span style="color: #006080;">"0,0,0,17"</span> Width=<span style="color: #006080;">"432"</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> <TextBlock Text=<span style="color: #006080;">"{Binding Name}"</span> TextWrapping=<span style="color: #006080;">"Wrap"</span> Style=<span style="color: #006080;">"{StaticResource PhoneTextExtraLargeStyle}"</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="lnum6" style="color: #606060;"> 6:</span> </StackPanel></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="lnum7" style="color: #606060;"> 7:</span> </DataTemplate></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="lnum8" style="color: #606060;"> 8:</span> </ListBox.ItemTemplate></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="lnum9" style="color: #606060;"> 9:</span> </ListBox></pre> <!--CRLF--></div> </div> <p>So, we simply want to display a list of Genres as “<em>Name</em>” as we get back from Netflix. With just the little code above added to our <em>MainPage.xaml</em> page, we can have our application fetch & display Genres as follows. Please note that is for demo only .. so no fancy progress bars, which you might want to add to indicate to the user that some web request is being served.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/samidip/Genres%20in%20App_2.png"><img width="304" height="549" title="Genres in App" style="border:0px solid; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="Genres in App" src="http://www.silverlightshow.net/Storage/Users/samidip/Genres%20in%20App_thumb.png" /></a></p> <h3>The Problem</h3> <p>Now, consider this .. let’s say the source of the OData feed does not change very often or you want this demo Netflix application to work in offline mode, after the data has been fetched at least once. Both of these indicate that we should figure out a way to not make the HTTP Get request to the OData source every time! So, the first time we fetch the data, we have to cache it in the application’s Isolated Storage, to be read on subsequence application runs until something triggers a refresh of the data feed.</p> <p>So, common sense suggests that we try to put the whole Genres DataServiceCollection in Isolated Storage & rehydrate our entity objects on successive needs for the data. Here’s the problem though – you will get strange error if you simply try to put the DataServiceCollection in Isolated Storage. Something along the lines of :</p> <p>"<em>An item could not be added to the collection. When items in a DataServiceCollection are tracked by the DataServiceContext, new items cannot be added before items have been loaded into the collection</em>."</p> <p>So, what’s happening? The problem is that DataServiceCollection<T> was not designed for serialization/deserialization. When we use the DataServiceCollection, the collection is responsible for tracking all the objects that it contains. Because the collection also has a reference to the DataServiceContext, it notifies the DataServiceContext of all changes to the collection and the entities in the collection. This means that we can just add,remove and update objects in the collection and when we want to persist the changes, we call <em>SaveChanges</em>() on the DataServiceContext.  This is the crux of the problem, since Isolated Storage requires the entities to be serialized, which triggers the object being updated events. If we create a new DataServiceCollection<T>() (constructor without parameters), it creates the collection in so called auto-tracking mode. That is the collection has tracking turned on, and in order for tracking to work correctly, we must call Load on it (this will add items and connect the collection to the right DataServiceContext which will track the items). This behavior is by design.</p> <p>Oops! So, is there no way to store away a DataServiceCollection for re-use? Thankfully – Yes!</p> <h3>The Solution</h3> <p>A new class called <em>DataServiceState</em> has been added to keep track of the state of a DataServiceCollection & it’s backend DataServiceContext. The DataServiceState simply knows how to serialize/deserialize a typed DataServiceContext with one or more DataServiceCollection objects. Essentially, during serialization through an explicit static <em>Serialize()</em> method, the whole DataServiceCollection is flattened into a string that is the XML serialized representation of the stored objects, along with support for nested collections.</p> <p>Shall we see this in action? In our case, we have a DataServiceCollection<Genre> that we would serialize & store in Isolated Storage for future use. Also, we would add a boolean flag to indicate whether we have cached data vs when we would have to refetch.  So, in our case, the moment we receive a response to our query to fetch Genres, we would serialize the collection into Isolated Storage. You may switch around where you do this for cleaner code .. but here’s the demo code that shows serialization:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;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;"> <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 id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span> MainPage : PhoneApplicationPage</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> <span style="color: #cc6633;">#region</span> <span style="color: #006080;">"Data Members"</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> DataServiceCollection<Genre> Genres { get; set; }</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="lnum6" style="color: #606060;"> 6:</span> DataServiceContext context = <span style="color: #0000ff;">new</span> DataServiceContext(<span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"http://odata.netflix.com/v2/Catalog/"</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="lnum7" style="color: #606060;"> 7:</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="lnum8" style="color: #606060;"> 8:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span> AppHasFeed { get; set; }</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="lnum9" style="color: #606060;"> 9:</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="lnum10" style="color: #606060;"> 10:</span> <span style="color: #cc6633;">#endregion</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="lnum11" style="color: #606060;"> 11:</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="lnum12" style="color: #606060;"> 12:</span> <span style="color: #cc6633;">#region</span> <span style="color: #006080;">"Constructor"</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="lnum13" style="color: #606060;"> 13:</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="lnum14" style="color: #606060;"> 14:</span> <span style="color: #0000ff;">public</span> MainPage()</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="lnum15" style="color: #606060;"> 15:</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="lnum16" style="color: #606060;"> 16:</span> InitializeComponent();</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="lnum17" style="color: #606060;"> 17:</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="lnum18" style="color: #606060;"> 18:</span> <span style="color: #0000ff;">if</span> (IsolatedStorageSettings.ApplicationSettings.Contains(<span style="color: #006080;">"AppHasFeed"</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="lnum19" style="color: #606060;"> 19:</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="lnum20" style="color: #606060;"> 20:</span> AppHasFeed = (<span style="color: #0000ff;">bool</span>)IsolatedStorageSettings.ApplicationSettings[<span style="color: #006080;">"AppHasFeed"</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="lnum21" style="color: #606060;"> 21:</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="lnum22" style="color: #606060;"> 22:</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="lnum23" style="color: #606060;"> 23:</span> <span style="color: #0000ff;">if</span> (!AppHasFeed)</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="lnum24" style="color: #606060;"> 24:</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="lnum25" style="color: #606060;"> 25:</span> <span style="color: #0000ff;">this</span>.LoadAndStoreGenres();</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="lnum26" style="color: #606060;"> 26:</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="lnum27" style="color: #606060;"> 27:</span> <span style="color: #0000ff;">else</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="lnum28" style="color: #606060;"> 28:</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="lnum29" style="color: #606060;"> 29:</span> <span style="color: #0000ff;">this</span>.HydrateFromIso();</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="lnum30" style="color: #606060;"> 30:</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="lnum31" style="color: #606060;"> 31:</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="lnum32" style="color: #606060;"> 32:</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="lnum33" style="color: #606060;"> 33:</span> <span style="color: #cc6633;">#endregion</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="lnum34" style="color: #606060;"> 34:</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="lnum35" style="color: #606060;"> 35:</span> <span style="color: #cc6633;">#region</span> <span style="color: #006080;">"Methods"</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="lnum36" style="color: #606060;"> 36:</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="lnum37" style="color: #606060;"> 37:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> LoadAndStoreGenres()</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="lnum38" style="color: #606060;"> 38:</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="lnum39" style="color: #606060;"> 39:</span> <span style="color: #008000;">// Instantiates our collection.</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="lnum40" style="color: #606060;"> 40:</span> <span style="color: #0000ff;">this</span>.Genres = <span style="color: #0000ff;">new</span> DataServiceCollection<Genre>(context);</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="lnum41" style="color: #606060;"> 41:</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="lnum42" style="color: #606060;"> 42:</span> <span style="color: #008000;">// Base HTTP endpoint or custom query goes here.</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="lnum43" style="color: #606060;"> 43:</span> Uri uriQuery = <span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"/Genres()"</span>, UriKind.Relative);</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="lnum44" style="color: #606060;"> 44:</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="lnum45" style="color: #606060;"> 45:</span> <span style="color: #008000;">// Asynchronously load the result of the query.</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="lnum46" style="color: #606060;"> 46:</span> <span style="color: #0000ff;">this</span>.Genres.LoadAsync(uriQuery);</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="lnum47" style="color: #606060;"> 47:</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="lnum48" style="color: #606060;"> 48:</span> <span style="color: #0000ff;">this</span>.Genres.LoadCompleted += (sender, args) =></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="lnum49" style="color: #606060;"> 49:</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="lnum50" style="color: #606060;"> 50:</span> <span style="color: #0000ff;">if</span> (args.Error == <span style="color: #0000ff;">null</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="lnum51" style="color: #606060;"> 51:</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="lnum52" style="color: #606060;"> 52:</span> <span style="color: #008000;">// Databind.</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="lnum53" style="color: #606060;"> 53:</span> <span style="color: #0000ff;">this</span>.genreList.ItemsSource = <span style="color: #0000ff;">this</span>.Genres;</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="lnum54" style="color: #606060;"> 54:</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="lnum55" style="color: #606060;"> 55:</span> <span style="color: #008000;">// Set & store the flag indicating we have fetched data once.</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="lnum56" style="color: #606060;"> 56:</span> AppHasFeed = <span style="color: #0000ff;">true</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="lnum57" style="color: #606060;"> 57:</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="lnum58" style="color: #606060;"> 58:</span> <span style="color: #0000ff;">if</span> (IsolatedStorageSettings.ApplicationSettings.Contains(<span style="color: #006080;">"AppHasFeed"</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="lnum59" style="color: #606060;"> 59:</span> IsolatedStorageSettings.ApplicationSettings.Remove(<span style="color: #006080;">"AppHasFeed"</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="lnum60" style="color: #606060;"> 60:</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="lnum61" style="color: #606060;"> 61:</span> IsolatedStorageSettings.ApplicationSettings.Add(<span style="color: #006080;">"AppHasFeed"</span>, AppHasFeed);</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="lnum62" style="color: #606060;"> 62:</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="lnum63" style="color: #606060;"> 63:</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="lnum64" style="color: #606060;"> 64:</span> <span style="color: #008000;">// Serialize our collection.</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="lnum65" style="color: #606060;"> 65:</span> var GenresCollection = <span style="color: #0000ff;">new</span> Dictionary<<span style="color: #0000ff;">string</span>, <span style="color: #0000ff;">object</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="lnum66" style="color: #606060;"> 66:</span> GenresCollection[<span style="color: #006080;">"Genres"</span>] = <span style="color: #0000ff;">this</span>.Genres;</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="lnum67" style="color: #606060;"> 67:</span> <span style="color: #0000ff;">string</span> GenresDataFeed = DataServiceState.Serialize(context, GenresCollection);</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="lnum68" style="color: #606060;"> 68:</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="lnum69" style="color: #606060;"> 69:</span> <span style="color: #008000;">// Store flattened data in Isolated Storage.</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="lnum70" style="color: #606060;"> 70:</span> <span style="color: #0000ff;">if</span> (IsolatedStorageSettings.ApplicationSettings.Contains(<span style="color: #006080;">"Genres"</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="lnum71" style="color: #606060;"> 71:</span> IsolatedStorageSettings.ApplicationSettings.Remove(<span style="color: #006080;">"Genres"</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="lnum72" style="color: #606060;"> 72:</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="lnum73" style="color: #606060;"> 73:</span> IsolatedStorageSettings.ApplicationSettings.Add(<span style="color: #006080;">"Genres"</span>, GenresDataFeed); </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="lnum74" style="color: #606060;"> 74:</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="lnum75" style="color: #606060;"> 75:</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="lnum76" style="color: #606060;"> 76:</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="lnum77" style="color: #606060;"> 77:</span> <span style="color: #cc6633;">#endregion</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="lnum78" style="color: #606060;"> 78:</span> }</pre> <!--CRLF--></div> </div> <p>So, our boolean flag “<em>AppHasFeed</em>” indicates whether we have fetched the Genre collection at least once .. in your actual use, you may choose to implement an explicit way to refresh the data feed. Back in our case, if we don’t have any data, we make the one-time asynchronous request to fetch OData as Atom. Next, we utilize the DataServiceState class to serialize the entire DataServiceCollection of Genres with respect to its DataServiceContext and store the resulting string XML into Isolated Storage as a key-value pair. Voila, now we are storing state and caching OData inside our application!</p> <p>One thing to note is that in our demo case, we simply put the whole DataServiceCollection in Isolated Storage for future use. If you do not want that level of persistence & are dealing with temporary data, there is a way out as well. The same techniques of serialization of a DataServiceCollection apply perfectly well when storing the resulting string in <em>PhoneApplicationService.Current.State, </em>in case you simply want the data to be available in case your application is tombstoned & you want you data entities to be rehydrated without making a fresh HTTP request.</p> <p>So, in the code above, we saw how to serialize & store a DataServiceCollection in Isolated Storage. But we also need the same data to be deserialized & re-hydrating our data entities if we are not making another fresh request. So, in our case, if the AppHasFeed flag indicates that we have fetched data already, we simply use the following deserialization technique:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;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;"> <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 id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> HydrateFromIso()</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> <span style="color: #0000ff;">if</span> (IsolatedStorageSettings.ApplicationSettings.Contains(<span style="color: #006080;">"Genres"</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> <span style="color: #008000;">// Fetch flattened data & rehydrate object model.</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="lnum6" style="color: #606060;"> 6:</span> <span style="color: #0000ff;">string</span> GenresDataFeed = IsolatedStorageSettings.ApplicationSettings[<span style="color: #006080;">"Genres"</span>].ToString();</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="lnum7" style="color: #606060;"> 7:</span> DataServiceState state = DataServiceState.Deserialize(GenresDataFeed);</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="lnum8" style="color: #606060;"> 8:</span> Dictionary<<span style="color: #0000ff;">string</span>, <span style="color: #0000ff;">object</span>> collections = state.RootCollections;</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="lnum9" style="color: #606060;"> 9:</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="lnum10" style="color: #606060;"> 10:</span> <span style="color: #008000;">// Hydrate our DataServiceCollection.</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="lnum11" style="color: #606060;"> 11:</span> <span style="color: #0000ff;">this</span>.Genres = collections[<span style="color: #006080;">"Genres"</span>] <span style="color: #0000ff;">as</span> DataServiceCollection<Genre>;</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="lnum12" style="color: #606060;"> 12:</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="lnum13" style="color: #606060;"> 13:</span> <span style="color: #008000;">// Databind.</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="lnum14" style="color: #606060;"> 14:</span> <span style="color: #0000ff;">this</span>.genreList.ItemsSource = <span style="color: #0000ff;">this</span>.Genres;</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="lnum15" style="color: #606060;"> 15:</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="lnum16" style="color: #606060;"> 16:</span> }</pre> <!--CRLF--></div> </div> <p>So essentially, we deserialize the string XML from Isolated Storage through the static <em>Deserialize()</em> method to re-instantiate a DataServiceState. Once done, the <em>RootCollections</em> property holds the individual DataServiceCollection entities, which we can use to re-hydrate our data model. Easy? <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" alt="Smile" src="http://www.silverlightshow.net/Storage/Users/samidip/wlEmoticon-smile_2.png" /> Again, where I do this in code is questionable, but this is for the sake of keeping the demo simple. You should be able to take the concept & add code to your application as & when needed to cache/uncache OData collections.</p> <p>So, after you add the above code, go ahead & run the Netflix Demo again, but this time after turning off all network connectivity for emulator or Windows Phone device. You’ll see that we have been able to serialize/deserialize the fetched OData collection and now our applications works perfectly fine in offline mode, on successive attempts!</p> <h3>Summary</h3> <p>In this article, we talked about consumption of OData from a Windows Phone application and the subsequent serialization/deserialization of data collections. These techniques should help in building lean applications which are careful about misuse of the user’s bandwidth in fetching the same data over & over again. So, what are you waiting for? Expose just about any data store as an OData feed, put appropriate security on the data & consume it responsibly from multiple mobile platforms!</p> <p>I would appreciate any comments or concerns or how things can be done better. Thanks for reading & happy coding. </p> <p>Cheers SilverlightShow!</p> <p> </p> <h3>About the Author</h3> <p><img width="129" height="157" title="ActualPic" style="border:0px solid; background-image: none; margin-top: 0px; margin-right: 10px; margin-bottom: 0px; margin-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; padding-top: 0px;" alt="ActualPic" src="http://www.silverlightshow.net/Storage/Users/samidip/_ActualPic_1.jpg" /></p> <p>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/OData-caching-in-Windows-Phone.aspx editorial@silverlightshow.net (Samidip Basu ) http://www.silverlightshow.net/items/OData-caching-in-Windows-Phone.aspx#comments http://www.silverlightshow.net/items/OData-caching-in-Windows-Phone.aspx Wed, 23 Nov 2011 03:53:00 GMT 10 Laps around Silverlight 5 (Part 7 of 10) <table width="20"> <tbody> <tr> <td> <div class="fb-like" data-show-faces="true" data-send="false" data-href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.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/10-Laps-around-Silverlight-5-Part-7-of-10.aspx" data-count="horizontal" data-text="Reading SilverlightShow article '10 Laps around Silverlight 5 (Part 7 of 10)' by @mbcrump #sl5" data-url="http://slshow.net/vuTRyo">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <div style="border:1px solid #dddddd;border-image: initial; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px; text-align: center;"><em><strong>This article is sponsored by <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Click&Mode=HTML&SiteID=1&PageID=41808" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Get&Mode=HTML&SiteID=1&PageID=41808" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik RadControls for Silverlight</a>. For similarly awesome content check out <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Click&Mode=HTML&SiteID=1&PageID=3019" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Get&Mode=HTML&SiteID=1&PageID=3019" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik XAMLflix</a>, your step-by-step guide to Telerik Silverlight and WPF controls. Get access to video tutorials, written tutorials, and tons of code! </strong></em></div> <p>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</p> <p>This article is Part 7 of the series “10 Laps around Silverlight 5.” If you have missed any other section then please see the Roadmap below. <br /> <br /> </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/news/Free-Silverlight-Show-Webinar-Introduction-to-XAML-Development-on-Windows-8.aspx">Upcoming Webinar on Nov 29th: XAML Development on Windows 8</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; border-image: initial;" 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></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> To refresh your memory on what Silverlight is: <p>Microsoft Silverlight is an application framework for writing Rich Internet Applications. </p> The run-time environment is available as a plug-in for most web browsers and works on a variety of operating systems including Windows, Mac and Linux. <p>To recap what we learned in the <a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx">previous section</a>:</p> <ul> <li>We spent some time building an application that uses P/Invoke or Platform Invocation to get familiar with Elevated Trust and Out of Browser applications.  We also reviewed that P/Invoke allows managed code to call native code. </li> <li>We then took a look at how to create a Silverlight 5 application that uses multiple windows that are separate from the main Silverlight window. We discussed how that if you close one of the newly spawned windows then it only closes that instance.  </li> <li>We wrapped up with creating an application that uses unrestricted file access to demonstrate creating a folder and placing a file inside of it with some content. </li> </ul> <p>In this article, I am going to discuss a few more operating system integration features in Silverlight 5 including: Default Filename for SaveFileDialog, 64-bit browser support and Power Awareness for Media Applications. Please review the Roadmap for the series before going any further.</p> <h3>The Roadmap for this Series</h3> <p>I’ve included the Roadmap for the series below as you may want to visit other sections as you learn Silverlight 5. I picked the following features as I thought that you may find them useful in your day-to-day work. If you want a specific topic covered then please leave it in the comments below.</p> <p>1) <strong><a href="http://www.silverlightshow.net/items/Silverlight-5-Part-1-of-10.aspx">Introduction to SL5 – This post which provides a brief history of Silverlight and relevant links.</a></strong> </p> <p>2) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-2-of-10.aspx">Binding- Ancestor Relative Source Binding and Implicit Data Templates.</a></strong></p> <p>3) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-3.aspx" target="_self"><strong>Graphics</strong> <strong>–XNA 3D API and Improved Graphics Stack</strong>.</a></p> <p>4) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-4-of-10.aspx">Media - Low-Latency Sound using XNA and Remote Control and Media Command (Keys) Support.</a></strong></p> <p>5) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx">Text - Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions.</a></strong></p> <p>6) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx">Operating System Integration - Part 1 - P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust.</a></strong></p> <p>7) <strong>Operating System</strong> <strong>Integration [This post]</strong> Part 2 - Default Filename for SaveFileDialog, 64-bit browser support and Power Awareness.</p> <p>8) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.aspx"><strong>Productivity and Performance - XAML Binding Debugging, Parser Performance Improvements and Multi-core JIT for improved start-up time.</strong></a></p> <p>9) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-9-of-10.aspx">Controls - Double and Triple click support, PivotViewer and ComboBox Type-Ahead.</a></strong></p> <p>10) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-10-of-10.aspx" target="_self"><strong>Other items - In-Browser HTML, PostScript and Tasks for TPL.</strong></a></p> <h3></h3> <h3>Default Filename for SaveFileDialog</h3> <p>In previous version of Silverlight, you could not specify the default filename for the SaveFileDialog message. In Silverlight 5 you can very easily. </p> <p>Fire up a new Silverlight 5 project and give it any name that you want. We are going to create a simple application that contains one button and when the user clicks it the SaveFileDialog will appear with a default filename. </p> <p>Switch over to the MainPage.xaml and add in the following code:</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;">StackPanel</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</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;">Button</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="btnSaveFile"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Save File Dialog"</span> <span style="color: #ff0000;">Click</span><span style="color: #0000ff;">="btnSaveFile_Click"</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;">StackPanel</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>Let’s switch back over to the MainPage.xaml.cs and add the following code to our button event handler:</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> private void btnSaveFile_Click(<span style="color: #0000ff;">object</span> sender, RoutedEventArgs e)</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> <span style="color: #0000ff;">var</span> saveFileDialog1 = new SaveFileDialog</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> Filter = "JPeg Image|*<span style="color: #cc6633;">.jpg</span>|Bitmap Image|*<span style="color: #cc6633;">.bmp</span>|Gif Image|*<span style="color: #cc6633;">.gif</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="lnum6" style="color: #606060;"> 6:</span> DefaultFileName = "YouCanNowHaveADefaultFileName<span style="color: #cc6633;">.jpeg</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="lnum7" style="color: #606060;"> 7:</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="lnum8" style="color: #606060;"> 8:</span> saveFileDialog1<span style="color: #cc6633;">.ShowDialog</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="lnum9" style="color: #606060;"> 9:</span> }</pre> <!--CRLF--></div> </div> <p>If we run the application now, we will see the following prompt.  </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/______1_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="1" alt="1" src="http://www.silverlightshow.net/Storage/Users/mbcrump/______1_thumb.png" width="400" height="172" /></a></p> <p><em>(Note: You could run this application in elevated trust to remove the security warning, see this <a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx">post</a> for details)</em></p> <p>Go ahead and select OK and you will see the following screen:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/________2_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="2" alt="2" src="http://www.silverlightshow.net/Storage/Users/mbcrump/________2_thumb.png" width="494" height="355" /></a></p> <p>You should notice that the File name field is filled in for us with a default save as type as Jpeg. Of course, if you didn’t want the user to see the security warning then you could run this application in elevated trust as mentioned under the image. </p> <h3>64-bit browser support </h3> <p>64-bit browser support is also new to Silverlight 5. If you have installed Windows 7 x64 then you already have a 64-bit version of Internet Explorer. You can find it by going to the “<strong>search program and files</strong>” prompt and typing<strong> Internet Explorer</strong> as shown below. </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_________3_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="3" alt="3" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_________3_thumb.png" width="383" height="104" /></a></p> <p>If you launch Internet Explorer x64 and visit a site built with Silverlight 5 then you will see the following message:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/5_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="5" alt="5" src="http://www.silverlightshow.net/Storage/Users/mbcrump/5_thumb_1.png" width="397" height="343" /></a></p> <p>After you click on the hyperlink then it will take you to a page that says the following: </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/6_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="6" alt="6" src="http://www.silverlightshow.net/Storage/Users/mbcrump/6_thumb_1.png" width="544" height="319" /></a></p> <p><em>(Please note this message will change after the final version of Silverlight 5 is released.)</em></p> <p>Don’t worry about this prompt, just go ahead and click “<strong>Install for Windows</strong>” and you will now be able to run Silverlight 5 applications inside of a browser running in 64-bit mode. Pretty sweet stuff!</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/___7_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="7" alt="7" src="http://www.silverlightshow.net/Storage/Users/mbcrump/___7_thumb.png" width="546" height="431" /></a></p> <h3> <br /> Power Awareness for Media Apps</h3> <p>Silverlight 5 comes with an improved power awareness feature. When you are watching a video in Silverlight 5, the screensaver will be disabled (for example, it will not kick in and distract you from your movie). It also allows the computer to sleep when the video is not playing. This is all accomplished with no additional code! You just have to be using Silverlight 5. </p> <h3>Conclusion</h3> <p>At this point, we have seen how you would use specify a default filename for SaveFileDialog, we looked at 64-bit browser support and power awareness for media applications. We have also discussed a few other features in Silverlight 5. In the next part of the series, I am going to take a look at a few productivity and performance features including : XAML Binding Debugging, Parser Performance Improvements and Multi-core JIT for improved start-up time.  Again, thanks for reading and please come back for the next part.</p> <p>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</p> http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.aspx editorial@silverlightshow.net (Michael Crump ) http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.aspx#comments http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.aspx Tue, 22 Nov 2011 10:53:00 GMT Working with Prism 4 Part 2: MVVM Basics and Commands <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-2-MVVM-Basics-and-Commands.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-2-MVVM-Basics-and-Commands.aspx" data-count="horizontal" data-text="Reading SilverlightShow article 'Working w/ Prism 4: MVVM Basics and Commands' by @briannoyes" data-url="http://slshow.net/vLP4um">Tweet</a></td> <td><g:plusone size="medium" href="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-2-MVVM-Basics-and-Commands.aspx"></g:plusone> </td> <td> </td> </tr> </tbody> </table> <p>This is Part 2 in the series Working with Prism 4.</p> <h3>Introduction</h3> <p>In the <a href="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-1-Getting-Started.aspx" target="_self">first part of this series</a>, I introduced you to the concepts of Prism 4 – what the toolkit is for, as well as what the top level features are. Additionally, I stepped through the basic setup of getting a Prism application up and running – creating the shell project, a module, declaring a region in the shell, and plugging a view into that region from the module.</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 will flesh out that application a little more and show you some of the basic support for the Model-View-ViewModel (MVVM) pattern that Prism has, as well as how to use the <strong>DelegateCommand</strong> type that Prism provides, which fits well with MVVM scenarios. An important thing to understand is that Prism is not first-and-foremost an MVVM framework. It is a toolkit for building composite applications, which may or may not choose to use the MVVM pattern. As a result, there is not a ton of framework infrastructure provided in Prism that is specifically focused on MVVM. There are other good toolkits out there, such as the <a href="http://mvvmlight.codeplex.com/" target="_blank">MVVM Light</a> or <a href="http://caliburnmicro.codeplex.com/" target="_blank">Caliburn Micro</a> toolkits that can be used in conjunction with Prism or instead of Prism if your primary goal is just to put together an MVVM application. However, I have found the combination of features of Prism for composition and MVVM to be more than sufficient for many big and small real world applications, so I usually just use Prism on its own without mixing in other toolkits, and I will keep the focus just on Prism in these articles. </p> <p>This article will build on the sample application developed in Part 1. You can <a href="http://www.silverlightshow.net/Storage/Sources/Prism101Part1.zip" target="_blank">download the starting point code from Part 1 here</a>. You can <a href="http://www.silverlightshow.net/Storage/Sources/Prism4MVVMAndCommandsSamplePart2.zip">download the finished sample for this article here</a>.</p> <h3>MVVM Basics</h3> <p>I don’t intend this article to be a starting point for learning the MVVM pattern. There are many other good resources out there for that, including the <a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx" target="_blank">excellent article by Josh Smith</a> and the two chapters we wrote in the <a href="http://my.safaribooksonline.com/book/programming/microsoft-wpf/9780735660663" target="_blank">Prism book</a> which is also <a href="http://msdn.microsoft.com/en-us/library/gg406140.aspx" target="_blank">available online in various electronic forms</a>. But just so you don’t have to go brush up on MVVM too much to follow along with what I will show in this article, here are the key essentials.</p> <p>MVVM is a UI separation pattern for keeping the structural aspects of the UI (the XAML elements that you see on the screen) separated from the state and logic that supports that view. The view is just the structure of what you see on the screen. It may contain some dynamic elements such as animations, but it has no logic defining the behavior of the application from a user interaction perspective. Ideally in an MVVM application, there is no code in the code-behind class of a XAML view, just the constructor with its <strong>InitializeComponent</strong> method call. The state (data) that is presented in the view is provided and manipulated by the view model, and interactions from the user such as selections, button presses, etc. are handled in the view model. The data that the user interacts with is stored in the model, which may not structure the data exactly as it is shown on the screen. The model data structures should be chosen based on the needs of the application as a whole. Another responsibility of the view model is to transform, as necessary, the data from the way the model wants to store and manipulate it to the shape that the view wants to see the data in.</p> <p>The basic structure of MVVM is that the view’s <strong>DataContext</strong> property at the root of the view will be set to an instance of the view model (View.DataContext = ViewModel). There is typically a 1:1 relationship of the class defined for the view and the class defined for the view model – for example a <strong>CustomerListView</strong> will have a <strong>CustomerListViewModel</strong>. But there are situations where one view model definition might support more than one view or vice versa. But at runtime, the view’s <strong>DataContext</strong> gets set to a reference to some view model instance that will provide its data and interaction logic. There are many ways the <strong>DataContext</strong> of the view can get set to an instance of a view model. In this article I will just focus on a couple of those, specifically hooking them up statically from the XAML of the view or using <strong>DataTemplates</strong>. But you can find many other variants out there in samples of ways to get the two hooked up to one another.</p> <p>To hook up a view to its view model statically from the XAML, you simply create an instance of it in the XAML like the following snippet:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><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.CustomerListView"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> ...</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="attr">xmlns:local</span><span class="kwrd">="clr-namespace:Prism101.Modules.Core"</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="alteven"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd"><</span><span class="html">local:CustomerListViewModel</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--></div> </div> <p>To use a <strong>DataTemplate</strong> to get them hooked up, you bind something in a parent view (typically a <strong>ContentControl</strong> or <strong>ItemsControl</strong>) to an instance of the view model whose view you want to render. Then you define a data template in the resources of the parent view that ties the view and view model together, and through the way <strong>DataTemplates</strong> work, sets the <strong>DataContext</strong> of the rendered view to the bound instance of the view model.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><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.ParentView"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> ...</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="attr">xmlns:local</span><span class="kwrd">="clr-namespace:Prism101.Modules.Core"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> ...<span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd"><</span><span class="html">UserControl.Resources</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd"><</span><span class="html">DataTemplate</span> <span class="attr">DataType</span><span class="kwrd">="local:CustomerListViewModel"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> <span class="kwrd"><</span><span class="html">local:CustomerListView</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> <span class="kwrd"></</span><span class="html">DataTemplate</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span> <span class="kwrd"></</span><span class="html">UserControl.Resources</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> <span class="kwrd"><</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">="LayoutRoot"</span> <span class="attr">Background</span><span class="kwrd">="White"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum11" class="lnum"> 11:</span> <span class="kwrd"><</span><span class="html">ContentControl</span> <span class="attr">Content</span><span class="kwrd">="{Binding ChildViewModel}"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> ...</pre> <!--CRLF--></div> </div> <h3>Commanding Basics</h3> <p>Commands in WPF and Silverlight are based on the <a href="http://en.wikipedia.org/wiki/Design_Patterns" target="_blank">Gang of Four</a> <a href="http://en.wikipedia.org/wiki/Command_pattern" target="_blank">Command</a> design pattern. With commands you have an invoker and a receiver and some infrastructure in between to keep those two parties decoupled from one another as much as possible. The invoker is typically a UI element of some sort like a button, menu, or possibly a <strong>ComboBox</strong> selection. The receiver is the handling code that takes some action based on the command being invoked. With traditional code-behind event handling of UI control events, the event handling code represented that receiver code, but it was tightly coupled to the UI element event and had to be co-located in the code behind of the view to work. With commands, particularly with the support of bindings in WPF and Silverlight, and with dependency injection support in Prism, you can have the command invoker and receiver be very loosely coupled from one another – often defined in separate modules that have no references to one another or knowledge of each other’s presence.</p> <p>Prism has two command types I’ll be covering in this series: the <strong>DelegateCommand</strong> type which is perfect for hooking up interaction logic between an MVVM view and its view model, and the <strong>CompositeCommand</strong>, which supports more loosely coupled, cross-module kinds of communication. Both are implementations of the <strong>ICommand</strong> interface defined in WPF and Silverlight, which defines three members: an <strong>Execute</strong> method, a <strong>CanExecute</strong> method, and a <strong>CanExecuteChanged</strong> event. The <strong>Execute</strong> method is the crux of the <strong>ICommand</strong> interface, it is what will be invoked whenever the invoker element has the triggering action happen to it (i.e. a button is clicked that has a command hooked up to it). The <strong>CanExecute</strong> method can be optionally hooked up to conditionally say whether the associated invoker should be enabled or not – for example if a document is not dirty, the Save command should be disabled. The associated <strong>CanExecuteChanged</strong> event is a way for the supporting logic that determines whether the command should be enabled to notify the invoker that it should re-evaluate the <strong>CanExecute</strong> state of the command and update the UI appropriately as things are changing behind the scenes (i.e. the document just went dirty because the user input some text or some other formatting command was invoked on the document that the Save command relates to).</p> <h3>Step 1: Getting Some Data Into the Application</h3> <p>Message boxes and Hello World prompts can only keep your attention for so long. So the first thing I am going to do is to use some Northwind data to add a little more real world structure to the application that I will be expanding on in this article. The sample code for this article includes a SQL script for creating the Northwind DB on your machine (assumes you have SQL Server on your machine in one of its forms). Additionally, the sample code has a WCF RIA Services domain service added to the host Web project to make it easy to retrieve and update the Northwind data from the Silverlight sample application. I am not going to go into any detail on the structure of how to do that since I have covered it in detail in my article series on <a href="http://www.silverlightshow.net/items/WCF-RIA-Services-Part-1-Getting-Started.aspx" target="_blank">WCF RIA Services here</a>. </p> <p>The steps I followed for the Silverlight sample application here is as follows:</p> <ul> <li>Ran the SQL script to create a clean copy of the Northwind database on my machine. </li> <li>Added an ADO.NET Entity Data Model to the Prism101.Web project from the Data project item templates in the Add New Item dialog, using the Database-first model approach to generate an entity framework model including the Customers, Orders, and Order Details tables from the Northwind database. </li> <li>Build the project so that the next step will see the EF model. </li> <li>Add a Domain Service Class to the Prism101.Web project from the Web project item templates in the Add New Item dialog, naming it <strong>CustomersDomainService</strong>. In the wizard, I selected those same three tables from the entity model. </li> <li>Build the project so that it code generates the client side support for consuming the domain service and the client side entity types. </li> </ul> <h3>Step 2: Creating a CustomerListView</h3> <p>To get started with some MVVM views, I will replace the <strong>WelcomeView</strong> view that was plugged in from the Core module in the last article with a <strong>CustomerListView</strong> with a supporting view model.</p> <p>In the Prism101.Modules.Core project, add a new Silverlight User Control to the project and name it <strong>CustomerListView</strong>. With the designer showing in the editor, bring up the Data Sources window (Data menu, Show Data Sources). This allows you to code generate user interface controls and have the bindings for them set up (at least partially) from data types in your application. I wrote about these features in details in my book <a href="http://www.amazon.com/Data-Binding-Windows-Forms-2-0/dp/032126892X" target="_blank">Data Binding with Windows Forms 2.0</a> a long time ago, but you can find a more recent coverage in this <a href="http://www.google.com/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=10&sqi=2&ved=0CHgQFjAJ&url=http%3A%2F%2Faz12722.vo.msecnd.net%2Fvs2010trainingcourse2-0%2Flabs%2Fwpf4datadrivenmasterdetailbusinessform1-1-0%2FWPF4DataDrivenMasterDetailBusinessForm.docx&ei=1bvHTqDeNuPW0QHLneUX&usg=AFQjCNHsE0J_iuJr2A3qSjUa8WW3sGAngA" target="_blank">Hands on Lab from Microsoft for WPF</a>.</p> <p>After a moment, if you have done the steps in Step 1, you should see the Data Sources window populate with the <strong>Customer</strong>, <strong>Order</strong>, and <strong>Order_Detail</strong> types.</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="244" height="182" /></a></p> <p>If you drag and drop the Customer type from this window into the Grid in the designer, it will code generate a <strong>DataGrid</strong> with the appropriate columns based on the properties of the <strong>Customer</strong> entity. Because these entities are generated by RIA Services, it will also add some additional stuff into the XAML that I stripped out to transform it into an MVVM structure, specifically a <strong>DomainDataSource</strong>. I did some other clean up in the sample code to reorder the columns from the order they were generated in. But after the cleanup, the XAML looks like that shown in the following code listing.</p> <div id="codeSnippetWrapper" class="csharpcode-wrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><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.CustomerListView"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="attr">xmlns:x</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="attr">xmlns:d</span><span class="kwrd">="http://schemas.microsoft.com/expression/blend/2008"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> <span class="attr">xmlns:mc</span><span class="kwrd">="http://schemas.openxmlformats.org/markup-compatibility/2006"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="attr">xmlns:sdk</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> <span class="attr">mc:Ignorable</span><span class="kwrd">="d"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> <span class="attr">d:DesignHeight</span><span class="kwrd">="300"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span> <span class="attr">d:DesignWidth</span><span class="kwrd">="400"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> <span class="kwrd"><</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">="LayoutRoot"</span> <span class="attr">Background</span><span class="kwrd">="White"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum11" class="lnum"> 11:</span> <span class="kwrd"><</span><span class="html">sdk:DataGrid</span> <span class="attr">ItemsSource</span><span class="kwrd">="{Binding Customers}"</span> </pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> <span class="attr">AutoGenerateColumns</span><span class="kwrd">="False"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum13" class="lnum"> 13:</span> <span class="attr">Name</span><span class="kwrd">="customerDataGrid"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> <span class="attr">RowDetailsVisibilityMode</span><span class="kwrd">="VisibleWhenSelected"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum15" class="lnum"> 15:</span> <span class="kwrd"><</span><span class="html">sdk:DataGrid.Columns</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="customerIDColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum17" class="lnum"> 17:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=CustomerID, Mode=OneWay}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> <span class="attr">Header</span><span class="kwrd">="Customer ID"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum19" class="lnum"> 19:</span> <span class="attr">IsReadOnly</span><span class="kwrd">="True"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum21" class="lnum"> 21:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="companyNameColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=CompanyName}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum23" class="lnum"> 23:</span> <span class="attr">Header</span><span class="kwrd">="Company Name"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum24" class="lnum"> 24:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum25" class="lnum"> 25:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="contactNameColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum26" class="lnum"> 26:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=ContactName}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum27" class="lnum"> 27:</span> <span class="attr">Header</span><span class="kwrd">="Contact Name"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum28" class="lnum"> 28:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum29" class="lnum"> 29:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="contactTitleColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum30" class="lnum"> 30:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=ContactTitle}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum31" class="lnum"> 31:</span> <span class="attr">Header</span><span class="kwrd">="Contact Title"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum32" class="lnum"> 32:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum33" class="lnum"> 33:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="phoneColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum34" class="lnum"> 34:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=Phone}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum35" class="lnum"> 35:</span> <span class="attr">Header</span><span class="kwrd">="Phone"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum36" class="lnum"> 36:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum37" class="lnum"> 37:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="faxColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum38" class="lnum"> 38:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=Fax}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum39" class="lnum"> 39:</span> <span class="attr">Header</span><span class="kwrd">="Fax"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum40" class="lnum"> 40:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum41" class="lnum"> 41:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="addressColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum42" class="lnum"> 42:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=Address}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum43" class="lnum"> 43:</span> <span class="attr">Header</span><span class="kwrd">="Address"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum44" class="lnum"> 44:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum45" class="lnum"> 45:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="cityColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum46" class="lnum"> 46:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=City}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum47" class="lnum"> 47:</span> <span class="attr">Header</span><span class="kwrd">="City"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum48" class="lnum"> 48:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum49" class="lnum"> 49:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="countryColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum50" class="lnum"> 50:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=Country}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum51" class="lnum"> 51:</span> <span class="attr">Header</span><span class="kwrd">="Country"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum52" class="lnum"> 52:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum53" class="lnum"> 53:</span> <span class="kwrd"><</span><span class="html">sdk:DataGridTextColumn</span> <span class="attr">x:Name</span><span class="kwrd">="postalCodeColumn"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum54" class="lnum"> 54:</span> <span class="attr">Binding</span><span class="kwrd">="{Binding Path=PostalCode}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum55" class="lnum"> 55:</span> <span class="attr">Header</span><span class="kwrd">="Postal Code"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum56" class="lnum"> 56:</span> <span class="attr">Width</span><span class="kwrd">="SizeToHeader"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum57" class="lnum"> 57:</span> <span class="kwrd"></</span><span class="html">sdk:DataGrid.Columns</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum58" class="lnum"> 58:</span> <span class="kwrd"></</span><span class="html">sdk:DataGrid</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum59" class="lnum"> 59:</span> <span class="kwrd"></</span><span class="html">Grid</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum60" class="lnum"> 60:</span> <span class="kwrd"></</span><span class="html">UserControl</span><span class="kwrd">></span></pre> <!--CRLF--></div> </div> <p>You can see that the code just contains a <strong>DataGrid</strong> and its columns for the properties of a <strong>Customer</strong>. I’ve modified it to assume that the <strong>DataContext</strong> of the view has a property called <strong>Customers</strong> that the <strong>DataGrid.ItemsSource</strong> property is bound to. There is also a Loaded event handler for the <strong>DomainDataSource</strong> that is added into the code behind of the view from the Data Sources window drag/drop operation that I stripped out after deleting the <strong>DomainDataSource</strong>.</p> <h3>Step 3: Replace WelcomeView with CustomerListView</h3> <p>Open the <strong>CoreModule</strong> class in the Prism101.Modules.Core project and replace the creation of the <strong>WelcomeView</strong> with the <strong>CustomerListView</strong>.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><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="alteven"><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="alteven"><span id="lnum5" class="lnum"> 5:</span> }</pre> <!--CRLF--></div> </div> <p>You can now delete the <strong>WelcomeView.xaml</strong> from that project. You should be able to build and run at this point and see that the grid shows up in the MainContent region in the shell now instead of the Hello Prism of the <strong>WelcomeView</strong>. This helps to emphasize that when using regions in Prism, the hosting view that contains a region does not need to be touched to completely alter its content, you just change what is being plugged into that container.</p> <h3>Step 4: Add a View Model</h3> <p>Add a class named <strong>CustomerListViewModel</strong> to the Prism101.Modules.Core project. Add the following code to that class.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">class</span> CustomerListViewModel : NotificationObject</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> CustomersDomainContext _Context = <span class="kwrd">new</span> CustomersDomainContext();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> IEnumerable<Customer> _Customers;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd">public</span> CustomerListViewModel()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> <span class="kwrd">if</span> (!DesignerProperties.IsInDesignTool)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> _Context.Load(_Context.GetCustomersQuery(), OnLoadComplete, <span class="kwrd">null</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum11" class="lnum"> 11:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum13" class="lnum"> 13:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> <span class="kwrd">public</span> IEnumerable<Customer> Customers</pre> <!--CRLF--> <pre class="alteven"><span id="lnum15" class="lnum"> 15:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> get { <span class="kwrd">return</span> _Customers; }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum17" class="lnum"> 17:</span> set</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum19" class="lnum"> 19:</span> <span class="kwrd">if</span> (_Customers != <span class="kwrd">value</span>)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum21" class="lnum"> 21:</span> _Customers = <span class="kwrd">value</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> RaisePropertyChanged(() => Customers);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum23" class="lnum"> 23:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum24" class="lnum"> 24:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum25" class="lnum"> 25:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum26" class="lnum"> 26:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum27" class="lnum"> 27:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnLoadComplete(LoadOperation<Customer> loadOp)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum28" class="lnum"> 28:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum29" class="lnum"> 29:</span> <span class="kwrd">if</span> (loadOp.HasError)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum30" class="lnum"> 30:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum31" class="lnum"> 31:</span> MessageBox.Show(loadOp.Error.Message);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum32" class="lnum"> 32:</span> loadOp.MarkErrorAsHandled();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum33" class="lnum"> 33:</span> <span class="kwrd">return</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum34" class="lnum"> 34:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum35" class="lnum"> 35:</span> Customers = _Context.Customers;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum36" class="lnum"> 36:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum37" class="lnum"> 37:</span> }</pre> <!--CRLF--></div> </div> <div>The view model provides the <strong>Customers</strong> collection of data that the view wants to bind to. It does that by having WCF RIA Services make a call to the back end and load the customer data using the <strong>CustomersDomainContext</strong> that is a member of the view model, then exposes the resulting customer data through a property on the view model that the view will bind to. The <strong>CustomersDomainContext</strong> is part of the code generated client code for RIA Services that acts as a proxy to the server side domain service. You can see that the Load call is an asynchronous service calls with a callback hooked up to the <strong>OnLoadComplete</strong> method to handle errors and to populate the Customers collection property once the call is complete.</div> <div> </div> <div>There are a couple of important things to point out about this code. One is that in the next step I will be hooking this view model up to the view statically. That means it will get created in the designer as well. The WCF RIA Service calls to load data are not going to work in the designer. Often you will have things in your view model initialization or construction that will break the designer. To guard against this, you can use the <strong>DesignerProperties</strong> class to avoid executing that code if you are in the designer. So the call to the <strong>CustomerDomainContext.Load</strong> method is only done at runtime, not at design time.</div> <div> </div> <div>Another is to notice the base class that I added to the view model class – <strong>NotificationObject</strong>. This is a base class that Prism provides that encapsulates the implementation of the <strong>INotifyPropertyChanged</strong> interface, which is important for your view models to support for the properties they expose. The base class exposes several overloaded <strong>RaisePropertyChanged</strong> methods you can call from your property set{} blocks to make sure that bindings in the view are refreshed when the underlying properties change. The call to <strong>RaisePropertyChanged</strong> in the Customers property set{} block shows that the Prism base class supporting using strongly typed lambda expressions to point to the property (Customers) itself, instead of using a string for the name of the property as is normally done when raising the <strong>PropertyChanged</strong> event directly. This makes the code more maintainable because refactoring the property name will update the <strong>RaisePropertyChanged</strong> calls as well. If declared as a string, it may not be picked up depending on what refactoring tools you use.</div> <div> </div> <h3>Step 5: Hook the view up to the view model</h3> <div>Add a XAML namespace to the <strong>CustomerListView</strong> so it has access to the types in its own assembly:</div> <div> </div> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> xmlns:local="clr-namespace:Prism101.Modules.Core"</pre> <!--CRLF--></div> </div> <p>Then set the <strong>DataContext</strong> of the view in the XAML to an instance of the view model as shown earlier:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd"><</span><span class="html">UserControl.DataContext</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="kwrd"><</span><span class="html">local:CustomerListViewModel</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd"></</span><span class="html">UserControl.DataContext</span><span class="kwrd">></span></pre> <!--CRLF--></div> </div> <div>You should now be able to run and see the data pop into the view after the asynchronous call completes.</div> <div> </div> <div><a href="http://www.silverlightshow.net/Storage/Users/brian.noyes/_Figure2_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="Figure2" alt="Figure2" src="http://www.silverlightshow.net/Storage/Users/brian.noyes/_Figure2_thumb.png" width="547" height="318" /></a></div> <div> </div> <div>This structuring of view and view model is often referred to as “view-first”, because the view is constructed, and then it constructs and wires up its own view model (either from XAML as done here or from code behind). View-first has advantages of simplicity as well as the fact that you can leverage the design time data support of Visual Studio and Expression Blend.</div> <div> </div> <h3>Step 6: Adding an Edit Command</h3> <div>To demonstrate using <strong>DelegateCommands</strong> to hook up communication between our view and view model for some interaction logic as well as navigating to another view using regions, I will modify the <strong>CustomerListView</strong> slightly to add an Edit button to the top of the form.</div> <div> </div> <div>The XAML for the button looks like this.</div> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd"><</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">="Edit"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="attr">Command</span><span class="kwrd">="{Binding EditCustomerCommand}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="attr">Height</span><span class="kwrd">="23"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Top"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="attr">Width</span><span class="kwrd">="75"</span> <span class="kwrd">/></span></pre> <!--CRLF--></div> </div> <div>Notice the binding on the <strong>Command</strong> property assumes there is a property on the <strong>DataContext</strong> (the view model) named <strong>EditCustomerCommand</strong>. Buttons in Silverlight and WPF have a <strong>Command</strong> property that can point to an instance of an <strong>ICommand</strong> object. If that is hooked up, the button will be enabled or disabled based on calls to the <strong>CanExecute</strong> method of the <strong>ICommand</strong> interface as described earlier. Additionally, when the button is clicked, it will call the <strong>Execute</strong> method of the <strong>ICommand</strong> object.</div> <div> </div> <div>Rather than implementing <strong>ICommand</strong> directly on an object, a common approach is to use an intermediary class that implements <strong>ICommand</strong> to dispatch the calls to target methods on some other object, which in this case will be our view model. The first command type that Prism provides is the <strong>DelegateCommand</strong> class. To add this support, first we declare the property that the button Command binding points to in the <strong>CustomerListViewModel</strong> class, passing the target <strong>Execute</strong> and <strong>CanExecute</strong> handling methods through <a href="http://msdn.microsoft.com/en-us/magazine/cc163970.aspx#S10" target="_blank">delegate inference</a> to the constructor.</div> <div> </div> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> DelegateCommand EditCustomerCommand { get; <span class="kwrd">private</span> set; }</pre> <!--CRLF--></div> </div> <div>Next we populate that property in the constructor of the view model class:</div> <div> </div> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> CustomerListViewModel()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> EditCustomerCommand = <span class="kwrd">new</span> DelegateCommand(OnEditCustomer, CanEditCustomer);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> ...</pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> }</pre> <!--CRLF--></div> </div> <p>Then we define the handling method that those point to.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">private</span> <span class="kwrd">bool</span> CanEditCustomer()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">return</span> <span class="kwrd">true</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnEditCustomer()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> }</pre> <!--CRLF--></div> </div> <p>At this point you should be able to build and run, set a breakpoint in the <strong>OnEditCustomer</strong> method and see that your command handler is being called. Because right now the <strong>CanEditCustomer</strong> method returns true, the command will always be enabled. I will remedy that shortly.</p> <h3>Step 7: Pushing selection state into the view model</h3> <p>An important aspect of user interaction is selection in the view. But as mentioned before, in an MVVM design, all state and state manipulation should happen in the view model, not in the view. So when the user selects something in the view, the view model needs to know about it so it can take any appropriate action at that point, as well as making that selection available to command handling logic like our edit command.</p> <p>Add the following property to the <strong>CustomerListViewModel</strong>.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> Customer _SelectedCustomer;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="kwrd">public</span> Customer SelectedCustomer</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> get { <span class="kwrd">return</span> _SelectedCustomer; }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> set</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> <span class="kwrd">if</span> (_SelectedCustomer != <span class="kwrd">value</span>)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span> _SelectedCustomer = <span class="kwrd">value</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> RaisePropertyChanged(() => SelectedCustomer);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum11" class="lnum"> 11:</span> EditCustomerCommand.RaiseCanExecuteChanged();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum13" class="lnum"> 13:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> }</pre> <!--CRLF--></div> </div> <p>Notice that in addition to doing raising the <strong>PropertyChanged</strong> event through the base class <strong>RaisePropertyChanged</strong> method, whenever the selected customer changes, the code makes a call to the <strong>EditCustomerCommand.RaiseCanExecuteChanged</strong> method. This causes the <strong>CanExecuteChanged</strong> event of the <strong>DelegateCommand’s</strong> implementation of <strong>ICommand</strong> to fire, which causes any command invoker such as our Edit button to update its enabled state by calling <strong>CanExecute</strong> again.</p> <p>Change the <strong>CanEditCustomer</strong> method to the following.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">private</span> <span class="kwrd">bool</span> CanEditCustomer()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">if</span> (SelectedCustomer == <span class="kwrd">null</span>) <span class="kwrd">return</span> <span class="kwrd">false</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">else</span> <span class="kwrd">return</span> <span class="kwrd">true</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> }</pre> <!--CRLF--></div> </div> <p>Finally, on the <strong>DataGrid</strong> in the view, bind the <strong>SelectedItem</strong> property to the <strong>SelectedCustomer</strong> property in the view model.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd"><</span><span class="html">sdk:DataGrid</span> <span class="attr">ItemsSource</span><span class="kwrd">="{Binding Customers}"</span> </pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="attr">SelectedItem</span><span class="kwrd">="{Binding Path=SelectedCustomer, Mode=TwoWay}"</span> ...<span class="kwrd">/></span></pre> <!--CRLF--></div> </div> <p>As a result of this change, the Edit button will now be disabled if there is no selection in the <strong>DataGrid</strong>. One the user selects a row in the <strong>DataGrid</strong>, the <strong>SelectedItem</strong> binding will push a reference to that Customer bound object into the <strong>SelectedCustomer</strong> property in the view model. That will fire the <strong>CanExecuteChanged</strong> event on the command, which will cause the button to requery <strong>CanExecute</strong>, and it will enable the button since the <strong>SelectedCustomer</strong> will no longer be null at that point.</p> <h3>Step 8: Define an edit view to switch to</h3> <p>As you have already seen with the <strong>MainContent</strong> region in <a href="http://www.silverlightshow.net/items/Working-with-Prism-4-Part-1-Getting-Started.aspx" target="_blank">Part 1</a>, regions in Prism allow you to plug a view into a parent view’s region for presentation. This can be used to logically navigate the user from view to view. What I want to do when the edit command is invoked is to swap out the main view from presenting a list of customers to one that presents an edit form for the selected customer. To do this, I can just plug another view into the <strong>MainContent</strong> region, replacing the list view as the active view.</p> <p>A region is a logical container for a collection of views that can be presented within that region. You can add multiple views into the region, and depending on what kind of control the region is, it can present those views either one at a time or all at once. So far I am using a <strong>ContentControl</strong> in the MainPage.xaml shell view as the <strong>MainContent</strong> region. A <strong>ContentControl</strong> can only have a single child element as its <strong>Content</strong> at one time. But the Prism <strong>IRegion</strong> abstraction can keep track of a collection of views and set the appropriate view as the <strong>Content</strong> for that control when you tell it to. This concept is called activating a view in a region in Prism. The thing that actually maps the abstract region to a concrete container control is called a region adapters. There are built in region adapters supporting <strong>ContentControl</strong>, <strong>ItemsControl</strong>, and <strong>Selector</strong> controls in Prism.</p> <p>To switch to the edit view for a customer, we first have to have one. I won’t go through all the details of defining the <strong>CustomerEditView</strong>, that is Silverlight basics and is similar to what I described earlier for creating the <strong>CustomerListView</strong>. Instead of dragging and dropping the <strong>Customer</strong> type from the Data Sources window with the default settings, you drop down the selection on the <strong>Customer</strong> type in that window and select Details. Then when you do the drag and drop onto the designer, it generates a data form for a single instance of the type instead of a data grid for a collection of the type. I again trimmed out the <strong>DomainDataSource</strong> that is added in that operation and patched up the bindings to expect a <strong>Customer</strong> property exposed from the view’s <strong>DataContext</strong> (view model) once it is hooked up. </p> <p>Notice the <strong>Button</strong> at the bottom of the listing that is bound to a <strong>SaveCommand</strong> property it also expects to be exposed from the view model. I will hook that up once I get to defining the view model for this view in the next step. Also notice that in this case I did not wire up the view model as the <strong>DataContext</strong> from the XAML. I will do that programmatically for this sample when the Edit command is invoked in the listing view.</p> <div id="codeSnippetWrapper" class="csharpcode-wrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><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</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="attr">xmlns:x</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="attr">xmlns:d</span><span class="kwrd">="http://schemas.microsoft.com/expression/blend/2008"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> <span class="attr">xmlns:mc</span><span class="kwrd">="http://schemas.openxmlformats.org/markup-compatibility/2006"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> <span class="attr">xmlns:sdk</span><span class="kwrd">="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> <span class="attr">mc:Ignorable</span><span class="kwrd">="d"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> <span class="attr">d:DesignHeight</span><span class="kwrd">="212"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span> <span class="attr">d:DesignWidth</span><span class="kwrd">="301"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> <span class="kwrd"><</span><span class="html">Grid</span> <span class="attr">x:Name</span><span class="kwrd">="LayoutRoot"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum11" class="lnum"> 11:</span> <span class="attr">Background</span><span class="kwrd">="White"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> </pre> <!--CRLF--> <pre class="alteven"><span id="lnum13" class="lnum"> 13:</span> <span class="kwrd"><</span><span class="html">Grid</span> <span class="attr">DataContext</span><span class="kwrd">="{Binding Customer}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum15" class="lnum"> 15:</span> <span class="attr">Margin</span><span class="kwrd">="12,12,0,0"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> <span class="attr">Name</span><span class="kwrd">="grid1"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum17" class="lnum"> 17:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Top"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> <span class="attr">Width</span><span class="kwrd">="272"</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum19" class="lnum"> 19:</span> <span class="kwrd"><</span><span class="html">Grid.ColumnDefinitions</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</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="alteven"><span id="lnum21" class="lnum"> 21:</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="alteven"><span id="lnum22" class="lnum"> 22:</span> <span class="kwrd"><</span><span class="html">ColumnDefinition</span> <span class="attr">Width</span><span class="kwrd">="5*"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum23" class="lnum"> 23:</span> <span class="kwrd"></</span><span class="html">Grid.ColumnDefinitions</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum24" class="lnum"> 24:</span> <span class="kwrd"><</span><span class="html">Grid.RowDefinitions</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum25" class="lnum"> 25:</span> <span class="kwrd"><</span><span class="html">RowDefinition</span> <span class="attr">Height</span><span class="kwrd">="Auto"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum26" class="lnum"> 26:</span> <span class="kwrd"><</span><span class="html">RowDefinition</span> <span class="attr">Height</span><span class="kwrd">="Auto"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum27" class="lnum"> 27:</span> <span class="kwrd"><</span><span class="html">RowDefinition</span> <span class="attr">Height</span><span class="kwrd">="Auto"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum28" class="lnum"> 28:</span> <span class="kwrd"><</span><span class="html">RowDefinition</span> <span class="attr">Height</span><span class="kwrd">="Auto"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum29" class="lnum"> 29:</span> <span class="kwrd"></</span><span class="html">Grid.RowDefinitions</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum30" class="lnum"> 30:</span> <span class="kwrd"><</span><span class="html">sdk:Label</span> <span class="attr">Content</span><span class="kwrd">="Company Name:"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum31" class="lnum"> 31:</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="0"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum32" class="lnum"> 32:</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="0"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum33" class="lnum"> 33:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum34" class="lnum"> 34:</span> <span class="attr">Margin</span><span class="kwrd">="3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum35" class="lnum"> 35:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum36" class="lnum"> 36:</span> <span class="kwrd"><</span><span class="html">TextBox</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="1"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum37" class="lnum"> 37:</span> <span class="attr">Height</span><span class="kwrd">="23"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum38" class="lnum"> 38:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum39" class="lnum"> 39:</span> <span class="attr">Margin</span><span class="kwrd">="3,3,0,3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum40" class="lnum"> 40:</span> <span class="attr">Name</span><span class="kwrd">="companyNameTextBox"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum41" class="lnum"> 41:</span> <span class="attr">Text</span><span class="kwrd">="{Binding Path=CompanyName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum42" class="lnum"> 42:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum43" class="lnum"> 43:</span> <span class="attr">Width</span><span class="kwrd">="164"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum44" class="lnum"> 44:</span> <span class="kwrd"><</span><span class="html">sdk:Label</span> <span class="attr">Content</span><span class="kwrd">="Contact Name:"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum45" class="lnum"> 45:</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="0"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum46" class="lnum"> 46:</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="1"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum47" class="lnum"> 47:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum48" class="lnum"> 48:</span> <span class="attr">Margin</span><span class="kwrd">="3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum49" class="lnum"> 49:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum50" class="lnum"> 50:</span> <span class="kwrd"><</span><span class="html">TextBox</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="1"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum51" class="lnum"> 51:</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="1"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum52" class="lnum"> 52:</span> <span class="attr">Height</span><span class="kwrd">="23"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum53" class="lnum"> 53:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum54" class="lnum"> 54:</span> <span class="attr">Margin</span><span class="kwrd">="3,3,0,3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum55" class="lnum"> 55:</span> <span class="attr">Name</span><span class="kwrd">="contactNameTextBox"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum56" class="lnum"> 56:</span> <span class="attr">Text</span><span class="kwrd">="{Binding Path=ContactName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum57" class="lnum"> 57:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum58" class="lnum"> 58:</span> <span class="attr">Width</span><span class="kwrd">="164"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum59" class="lnum"> 59:</span> <span class="kwrd"><</span><span class="html">sdk:Label</span> <span class="attr">Content</span><span class="kwrd">="Contact Title:"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum60" class="lnum"> 60:</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="0"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum61" class="lnum"> 61:</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="2"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum62" class="lnum"> 62:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum63" class="lnum"> 63:</span> <span class="attr">Margin</span><span class="kwrd">="3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum64" class="lnum"> 64:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum65" class="lnum"> 65:</span> <span class="kwrd"><</span><span class="html">TextBox</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="1"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum66" class="lnum"> 66:</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="2"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum67" class="lnum"> 67:</span> <span class="attr">Height</span><span class="kwrd">="23"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum68" class="lnum"> 68:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum69" class="lnum"> 69:</span> <span class="attr">Margin</span><span class="kwrd">="3,3,0,3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum70" class="lnum"> 70:</span> <span class="attr">Name</span><span class="kwrd">="contactTitleTextBox"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum71" class="lnum"> 71:</span> <span class="attr">Text</span><span class="kwrd">="{Binding Path=ContactTitle, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum72" class="lnum"> 72:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum73" class="lnum"> 73:</span> <span class="attr">Width</span><span class="kwrd">="164"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum74" class="lnum"> 74:</span> <span class="kwrd"><</span><span class="html">sdk:Label</span> <span class="attr">Content</span><span class="kwrd">="Phone:"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum75" class="lnum"> 75:</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="0"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum76" class="lnum"> 76:</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum77" class="lnum"> 77:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum78" class="lnum"> 78:</span> <span class="attr">Margin</span><span class="kwrd">="3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum79" class="lnum"> 79:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum80" class="lnum"> 80:</span> <span class="kwrd"><</span><span class="html">TextBox</span> <span class="attr">Grid</span>.<span class="attr">Column</span><span class="kwrd">="1"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum81" class="lnum"> 81:</span> <span class="attr">Grid</span>.<span class="attr">Row</span><span class="kwrd">="3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum82" class="lnum"> 82:</span> <span class="attr">Height</span><span class="kwrd">="23"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum83" class="lnum"> 83:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum84" class="lnum"> 84:</span> <span class="attr">Margin</span><span class="kwrd">="3,3,0,3"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum85" class="lnum"> 85:</span> <span class="attr">Name</span><span class="kwrd">="phoneTextBox"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum86" class="lnum"> 86:</span> <span class="attr">Text</span><span class="kwrd">="{Binding Path=Phone, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum87" class="lnum"> 87:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Center"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum88" class="lnum"> 88:</span> <span class="attr">Width</span><span class="kwrd">="164"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum89" class="lnum"> 89:</span> <span class="kwrd"></</span><span class="html">Grid</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum90" class="lnum"> 90:</span> <span class="kwrd"><</span><span class="html">Button</span> <span class="attr">Content</span><span class="kwrd">="Save"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum91" class="lnum"> 91:</span> <span class="attr">Command</span><span class="kwrd">="{Binding SaveCommand}"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum92" class="lnum"> 92:</span> <span class="attr">Height</span><span class="kwrd">="23"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum93" class="lnum"> 93:</span> <span class="attr">HorizontalAlignment</span><span class="kwrd">="Left"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum94" class="lnum"> 94:</span> <span class="attr">Margin</span><span class="kwrd">="162,134,0,0"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum95" class="lnum"> 95:</span> <span class="attr">VerticalAlignment</span><span class="kwrd">="Top"</span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum96" class="lnum"> 96:</span> <span class="attr">Width</span><span class="kwrd">="75"</span> <span class="kwrd">/></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum97" class="lnum"> 97:</span> <span class="kwrd"></</span><span class="html">Grid</span><span class="kwrd">></span></pre> <!--CRLF--> <pre class="alteven"><span id="lnum98" class="lnum"> 98:</span> <span class="kwrd"></</span><span class="html">UserControl</span><span class="kwrd">></span></pre> <!--CRLF--></div> </div> <h3>Step 9: Define the CustomerEditViewModel</h3> <p>When you define a view like the edit view, you quickly identify what properties are needed from your view model to support the view, in this case a <strong>Customer</strong> property and a <strong>SaveCommand</strong> property. Add a <strong>CustomerEditViewModel</strong> class to the project and add the following contents to it.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> <span class="kwrd">class</span> CustomerEditViewModel : NotificationObject</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> <span class="kwrd">public</span> CustomerEditViewModel()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> SaveCommand = <span class="kwrd">new</span> DelegateCommand(OnSave);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> <span class="kwrd">public</span> DelegateCommand SaveCommand { get; <span class="kwrd">private</span> set; }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> Customer _Customer;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum11" class="lnum"> 11:</span> <span class="kwrd">public</span> Customer Customer</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum13" class="lnum"> 13:</span> get { <span class="kwrd">return</span> _Customer; }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> set</pre> <!--CRLF--> <pre class="alteven"><span id="lnum15" class="lnum"> 15:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> <span class="kwrd">if</span> (_Customer != <span class="kwrd">value</span>)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum17" class="lnum"> 17:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> _Customer = <span class="kwrd">value</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum19" class="lnum"> 19:</span> RaisePropertyChanged(() => Customer);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum21" class="lnum"> 21:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum23" class="lnum"> 23:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum24" class="lnum"> 24:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnSave()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum25" class="lnum"> 25:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum26" class="lnum"> 26:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum27" class="lnum"> 27:</span> }</pre> <!--CRLF--></div> </div> <h3>Step 10: Switch to the edit view when the Edit command executes</h3> <p>As you learned in Part 1, the <strong>RegionManager</strong> service provides the mechanism for plugging views into regions. That means if you are going to switch to the edit view from the list view model, you will need access to that service there. To gain access, you can leverage dependency injection through MEF in your view model. Add the following property declaration in the <strong>CustomerListViewModel</strong>.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> [Import]</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="kwrd">public</span> IRegionManager RegionManager { get; set; }</pre> <!--CRLF--></div> </div> <p>This view model gets constructed from the XAML of the view, so the container is not involved and can’t do the dependency injection automatically. But thanks to the <strong>CompositionInitializer</strong> class, you can ask the container to do the injection as the view model gets constructed explicitly. Add line 7 in the the following code to the constructor of the <strong>CustomerListViewModel</strong>. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">public</span> CustomerListViewModel()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> EditCustomerCommand = <span class="kwrd">new</span> DelegateCommand(OnEditCustomer, CanEditCustomer);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> <span class="kwrd">if</span> (!DesignerProperties.IsInDesignTool)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> _Context.Load(_Context.GetCustomersQuery(), OnLoadComplete, <span class="kwrd">null</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> CompositionInitializer.SatisfyImports(<span class="kwrd">this</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span> }</pre> <!--CRLF--></div> </div> <p>That will get the <strong>IRegionManager</strong> reference injected (the set block of the property will be called to provide the reference) by the container. However, to make sure there is a single container used by both Prism and the <strong>CompositionInitializer</strong> class, you need to add one more overload to the <strong>Bootstrapper</strong> class in the Prism101 shell project. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> <span class="kwrd">protected</span> <span class="kwrd">override</span> CompositionContainer CreateContainer()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum3" class="lnum"> 3:</span> var container = <span class="kwrd">base</span>.CreateContainer();</pre> <!--CRLF--> <pre class="alteven"><span id="lnum4" class="lnum"> 4:</span> CompositionHost.Initialize(container);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd">return</span> container;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> }</pre> <!--CRLF--></div> </div> <p>This makes it so the container that Prism sets up is the one that is used by the <strong>CompositionHost</strong> that sits underneath the <strong>CompositionInitializer</strong> class.</p> <p>Now you are ready to actually do the view switching with the region manager. Modify the <strong>OnEditCustomer</strong> code with the following.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><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="alteven"><span id="lnum3" class="lnum"> 3:</span> IRegion mainContentRegion = RegionManager.Regions[<span class="str">"MainContent"</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="alteven"><span id="lnum5" class="lnum"> 5:</span> <span class="kwrd">foreach</span> (var view <span class="kwrd">in</span> mainContentRegion.Views)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum6" class="lnum"> 6:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> <span class="kwrd">if</span> (view <span class="kwrd">is</span> CustomerEditView)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span> CustomerEditViewModel viewModel = ((FrameworkElement)view).DataContext <span class="kwrd">as</span> CustomerEditViewModel;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> viewModel.Customer = SelectedCustomer;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum11" class="lnum"> 11:</span> mainContentRegion.Activate(view);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span> alreadyExists = <span class="kwrd">true</span>;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum13" class="lnum"> 13:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> }</pre> <!--CRLF--> <pre class="alteven"><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="alteven"><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="alteven"><span id="lnum19" class="lnum"> 19:</span> editView.DataContext = viewModel;</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> mainContentRegion.Add(editView);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum21" class="lnum"> 21:</span> mainContentRegion.Activate(editView);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum23" class="lnum"> 23:</span> }</pre> <!--CRLF--></div> </div> <p>If you look at what this code is doing, first it obtains a reference to the <strong>IRegion</strong> reference for the <strong>MainContent</strong> region. Then it loops through the <strong>Views</strong> collection exposed on the region to see if it contains an instance of a <strong>CustomerEditView</strong>. That would be the case if the user had already switched to the edit view at least once before. If so, it obtains a reference to the view model for that view by casting the <strong>DataContext</strong> of the view. Remember that in MVVM, View.DataContext = ViewModel. Once it has the view model reference, it can push the reference to the selected customer into the Customer property of the edit view model. Finally in that case it calls <strong>Activate</strong> on the region to get that as the currently presented view. </p> <p>If the view was not in the <strong>Views</strong> collection, it simply constructs a new instance and goes through a similar process, first calling <strong>Add</strong> before <strong>Activate</strong>. This chunk of code should only execute the first time the edit view is visited, because the region will cache the reference to the edit view in its Views collection.</p> <p>One thing to point out here is that I am kind of violating the principles of MVVM by explicitly constructing the <strong>CustomerEditView</strong> type in the list view model. Typically if you were going to do it this way you would factor this code out to a Controller that managed multiple views and their view models and use a <strong>CompositeCommand</strong> to hook things up. I’ll show that kind of structure in the next article, and in a later one I’ll highlight the newer navigation features of Prism regions that were added in Prism 4 as an even more decoupled way to switch views. But for now I wanted to show the basic view switching mechanisms of Prism regions and not have too many moving parts, so I am sacrificing a little bit of view model cleanliness for compactness for writing purposes here.</p> <p>Once you have this code in place, you should be able to build, fire up the application, select a <strong>Customer</strong> in the grid, press the Edit button and have the main view’s content switch to the edit form.</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="464" height="291" /></a></p> <p>The last piece for this article is to hook up the Save button in the edit form so that it can at least switch back to the main form. That means you need access to the region manager from that view model as well. The code there is very similar: </p> <ul> <li>Add an Import property for the <strong>IRegionManager</strong> </li> <li>Call <strong>CompositionInitializer.SatifyImports</strong> from the constructor in a guard clause checking to see if you are in the designer </li> <li>Use the region manager to activate the list view in the region </li> </ul> <p>The following code shows those changes to the <strong>CustomerEditViewModel</strong>.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" class="csharpcode"> <pre class="alteven"><span id="lnum1" class="lnum"> 1:</span> [Import]</pre> <!--CRLF--> <pre class="alteven"><span id="lnum2" class="lnum"> 2:</span> <span class="kwrd">public</span> IRegionManager RegionManager { get; set; }</pre> <!--CRLF--> <pre class="alteven"><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="alteven"><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);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum7" class="lnum"> 7:</span> <span class="kwrd">if</span> (!DesignerProperties.IsInDesignTool)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum8" class="lnum"> 8:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum9" class="lnum"> 9:</span> CompositionInitializer.SatisfyImports(<span class="kwrd">this</span>);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum10" class="lnum"> 10:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum11" class="lnum"> 11:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum12" class="lnum"> 12:</span>  </pre> <!--CRLF--> <pre class="alteven"><span id="lnum13" class="lnum"> 13:</span> <span class="kwrd">private</span> <span class="kwrd">void</span> OnSave()</pre> <!--CRLF--> <pre class="alteven"><span id="lnum14" class="lnum"> 14:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum15" class="lnum"> 15:</span> IRegion mainContentRegion = RegionManager.Regions[<span class="str">"MainContent"</span>];</pre> <!--CRLF--> <pre class="alteven"><span id="lnum16" class="lnum"> 16:</span> <span class="kwrd">foreach</span> (var view <span class="kwrd">in</span> mainContentRegion.Views)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum17" class="lnum"> 17:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum18" class="lnum"> 18:</span> <span class="kwrd">if</span> (view <span class="kwrd">is</span> CustomerListView)</pre> <!--CRLF--> <pre class="alteven"><span id="lnum19" class="lnum"> 19:</span> {</pre> <!--CRLF--> <pre class="alteven"><span id="lnum20" class="lnum"> 20:</span> mainContentRegion.Activate(view);</pre> <!--CRLF--> <pre class="alteven"><span id="lnum21" class="lnum"> 21:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum22" class="lnum"> 22:</span> }</pre> <!--CRLF--> <pre class="alteven"><span id="lnum23" class="lnum"> 23:</span> }</pre> <!--CRLF--></div> </div> At this point you have a simple but functioning example of an MVVM Prism application that uses a bit of view model base class infrastructure that Prism provides in the <strong>NotificationObject</strong> base class, <strong>DelegateCommands</strong> to communicate from the view to the view model, and regions to do the switching of views in the main window. <h3>Summary</h3> <p>You can see that it is not a lot of code, nor a lot of complexity that Prism provides  with respect to MVVM and commanding, but it provides the common pieces you need for a clean MVVM application. There is no built in implementation of the <strong>ICommand</strong> interface in Silverlight, so it provides the <strong>DelegateCommand</strong> to step in nicely for hooking up views to view model logic. There are other discrete pieces of functionality related to MVVM that Prism supports. I’ll touch on some of those when we get to the navigation services in Prism in a later article. There are also features like the <a href="http://briannoyes.net/2011/01/15/Prism4GemsRenderingHeterogeneousCollectionsWithDataTemplateSelector.aspx" target="_blank">DataTemplateSelector capabilities</a>, which are not as necessary in Silverlight 5 with the addition of implicit data templates, but can still come in handy in other scenarios. Another piece is the <a href="http://briannoyes.net/2010/11/15/PromptingTheUserFromAViewModelndashPrism4Gems.aspx" target="_blank">interaction request capabilities</a> that allow you to be more decoupled in your view model and not directly present pop ups but leave it up to the view to decide what the appearance of the notification to a user looks like.</p> <p>In the next article I will expand on the communication by looking at <strong>CompositeCommands</strong> and loosely coupled events in Prism. You can <a href="http://www.silverlightshow.net/Storage/Sources/Prism4MVVMAndCommandsSamplePart2.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/" target="_blank">IDesign</a>, a <a href="http://theregion.com/" target="_blank">Microsoft Regional Director</a>, 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 <a href="http://my.safaribooksonline.com/book/programming/microsoft-wpf/9780735660663" target="_blank">Developers Guide to Microsoft Prism 4</a>. 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-2-MVVM-Basics-and-Commands.aspx editorial@silverlightshow.net (Brian Noyes ) http://www.silverlightshow.net/items/Working-with-Prism-4-Part-2-MVVM-Basics-and-Commands.aspx#comments http://www.silverlightshow.net/items/Working-with-Prism-4-Part-2-MVVM-Basics-and-Commands.aspx Mon, 21 Nov 2011 00:13:00 GMT 10 Laps around Silverlight 5 (Part 6 of 10) <div style="border:1px solid #dddddd;border-image: initial; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px; text-align: center;"><em><strong>This article is sponsored by <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Click&Mode=HTML&SiteID=1&PageID=41808" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Get&Mode=HTML&SiteID=1&PageID=41808" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik RadControls for Silverlight</a>. For similarly awesome content check out <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Click&Mode=HTML&SiteID=1&PageID=3019" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Get&Mode=HTML&SiteID=1&PageID=3019" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik XAMLflix</a>, your step-by-step guide to Telerik Silverlight and WPF controls. Get access to video tutorials, written tutorials, and tons of code! </strong></em></div> <div style="text-align: right;"><br /> <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://slshow.net/vdiwFS" data-text="Reading SilverlightShow article '10 Laps around Silverlight 5 (Part 6 of 10)' by @mbcrump #sl5" data-count="horizontal" data-counturl="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx" data-via="silverlightshow">Tweet</a></div> <p>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</p> <p>This article is Part 6 of the series “10 Laps around Silverlight 5.” If you have missed any other section then please see the Roadmap below. <br /> <br /> To refresh your memory on what Silverlight is: </p> <p>Microsoft Silverlight is an application framework for writing Rich Internet Applications. </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/news/Free-Silverlight-Show-Webinar-Introduction-to-XAML-Development-on-Windows-8.aspx">Upcoming Webinar on Nov 29th: XAML Development on Windows 8</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; border-image: initial;" 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></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> The run-time environment is available as a plug-in for most web browsers and works on a variety of operating systems including Windows, Mac and Linux. <p>To recap what we learned in the <a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx">previous section</a>:</p> <ul> <li>We spend the entire “lap” discussing improvements in text in Silverlight 5. </li> <li>We discussed Linked and Multi-Column Text and where it might be useful in your next Silverlight application. </li> <li>We also looked at character spacing, open-type font. pixel snapped text and TextOptions. </li> </ul> <p>In this article, I am going to discuss several new operating system integration features in Silverlight 5 including: P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust. Please review the Roadmap for the series before going any further.</p> <h3>The Roadmap for this Series</h3> <p>I’ve included the Roadmap for the series below as you may want to visit other sections as you learn Silverlight 5. I picked the following features as I thought that you may find them useful in your day-to-day work. If you want a specific topic covered then please leave it in the comments below.</p> <p>1) <strong><a href="http://www.silverlightshow.net/items/Silverlight-5-Part-1-of-10.aspx">Introduction to SL5 – This post which provides a brief history of Silverlight and relevant links.</a></strong> </p> <p>2) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-2-of-10.aspx">Binding- Ancestor Relative Source Binding and Implicit Data Templates.</a></strong></p> <p>3) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-3.aspx" target="_self"><strong>Graphics</strong> <strong>–XNA 3D API and Improved Graphics Stack</strong>.</a></p> <p>4) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-4-of-10.aspx">Media - Low-Latency Sound using XNA and Remote Control and Media Command (Keys) Support.</a></strong></p> <p>5) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx">Text - Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions.</a></strong></p> <p>6) <strong>Operating System Integration [This post] </strong>- Part 1 - P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust.</p> <p>7) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.aspx" target="_self"><strong>Operating System Integration Part 2 - Default Filename for SaveFileDialog, 64-bit browser support and Power Awareness.</strong></a></p> <p>8) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.aspx"><strong>Productivity and Performance - XAML Binding Debugging, Parser Performance Improvements and Multi-core JIT for improved start-up time.</strong></a></p> <p>9) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-9-of-10.aspx">Controls - Double and Triple click support, PivotViewer and ComboBox Type-Ahead.</a></strong></p> <p>10) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-10-of-10.aspx" target="_self"><strong>Other items - In-Browser HTML, PostScript and Tasks for TPL.</strong></a></p> <h3></h3> <h3>P/Invoke or Platform Invocation</h3> <p>Before we dive into an example. Let’s first answer the question, What is it? <strong>Platform Invocation Services</strong>, commonly referred to as <strong>P/Invoke</strong>, is a feature of <a href="http://en.wikipedia.org/wiki/Common_Language_Infrastructure">Common Language Infrastructure</a> implementations, like <a href="http://en.wikipedia.org/wiki/Microsoft">Microsoft</a>'s <a href="http://en.wikipedia.org/wiki/Common_Language_Runtime">Common Language Runtime</a>, that enables <a href="http://en.wikipedia.org/wiki/Managed_code">managed code</a> to call <a href="http://en.wikipedia.org/wiki/Native_code">native code</a>.</p> <p>*Reference to Wiki</p> <p>This feature is new to Silverlight 5 and we will take a look at how to use it in your own applications.  </p> <p>In order to create a new P/Invoke application in Silverlight 5, we will need to enable “<strong>Require elevated trust</strong>” in Silverlight 5. We can also use the functionality in-browser or out-of-browser. Let’s begin. </p> <p>Fire up a new Silverlight 5 project and right click on our project and select Properties. Put a check in “<strong>Enable running application out of the browser</strong>” as shown below.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_____1_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="1" alt="1" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_____1_thumb.png" width="526" height="428" /></a></p> <p>After you put a check in “Enable running application out of the browser”, go ahead and click the button. Now put a check in “<strong>Require elevated trust when running outside the browser</strong>”.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_______2_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="2" alt="2" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_______2_thumb.png" width="388" height="497" /></a></p> <p>Switch back over to the MainPage.xaml and add in the following code:</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;">Grid</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="LayoutRoot"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="White"</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;">Button</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="23"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="169,132,0,0"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Top"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="75"</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="btnclick"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="click"</span> <span style="color: #ff0000;">Click</span><span style="color: #0000ff;">="click_Click"</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;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>This simply puts a button on our page that when the user clicks it the pc will make a beep sound. </p> <p>Go ahead and add a new class to the project named <strong>PlatformInvokeTest.cs</strong> and add the following code.</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;">using</span> System;</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;">using</span> System.Runtime.InteropServices;</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>  </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> <span style="color: #0000ff;">namespace</span> PInvoke</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> {</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="lnum6" style="color: #606060;"> 6:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> PlatformInvokeTest</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="lnum7" style="color: #606060;"> 7:</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="lnum8" style="color: #606060;"> 8:</span> [DllImport(<span style="color: #006080;">"kernel32.dll"</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="lnum9" style="color: #606060;"> 9:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">extern</span> <span style="color: #0000ff;">bool</span> Beep(<span style="color: #0000ff;">int</span> frequency, <span style="color: #0000ff;">int</span> duration);</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="lnum10" style="color: #606060;"> 10:</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="lnum11" style="color: #606060;"> 11:</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="lnum12" style="color: #606060;"> 12:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> PlaySound()</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="lnum13" style="color: #606060;"> 13:</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="lnum14" style="color: #606060;"> 14:</span> Random random = <span style="color: #0000ff;">new</span> Random();</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="lnum15" style="color: #606060;"> 15:</span> <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < 50; i++)</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="lnum16" style="color: #606060;"> 16:</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="lnum17" style="color: #606060;"> 17:</span> Beep(random.Next(10000), 100);</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="lnum18" style="color: #606060;"> 18:</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="lnum19" style="color: #606060;"> 19:</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="lnum20" style="color: #606060;"> 20:</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="lnum21" style="color: #606060;"> 21:</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="lnum22" style="color: #606060;"> 22:</span> }</pre> <!--CRLF--></div> </div> <p>Let’s switch back over to the MainPage.xaml.cs and add the following code to our button event handler:</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;">private</span> <span style="color: #0000ff;">void</span> click_Click(<span style="color: #0000ff;">object</span> sender, RoutedEventArgs e)</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> PlatformInvokeTest.PlaySound();</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--></div> </div> <p>If we run the application now, we will hear our PC beep many times.  There are many other thing you can do with P/Invoke such as Detecting if the user inserted a USK Key into their computer, opening the run dialog box and much much more! Very cool stuff!</p> <h3>Multiple Window Support</h3> <p>With Silverlight 5, we now have the ability to spawn multiple windows from an Out-of-Browser application with elevated trust with just a couple of lines of code. </p> <p>A few things to note about Multiple Window Support though: </p> <ul> <li>If the main window closes, then all spawned windows close.</li> <li>You need to be running your application “Out-of-Browser” as well as in Elevated Trust mode. </li> </ul> <p>If you followed the P/Invoke guide before then you will need to do the same thing for Multiple Window Support. That is, make this an out-of-browser application and add Elevated Trust.</p> <p>After that is complete then go ahead and double click on your MainPage.xaml.cs file and add the following code: </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;">public</span> MainPage()</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> InitializeComponent();</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> Loaded += <span style="color: #0000ff;">new</span> RoutedEventHandler(MainPage_Loaded);</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> }</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="lnum6" style="color: #606060;"> 6:</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="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;">void</span> MainPage_Loaded(<span style="color: #0000ff;">object</span> sender, RoutedEventArgs e)</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="lnum8" style="color: #606060;"> 8:</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="lnum9" style="color: #606060;"> 9:</span> <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < 5; i++)</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="lnum10" style="color: #606060;"> 10:</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="lnum11" style="color: #606060;"> 11:</span> <span style="color: #0000ff;">new</span> Window()</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="lnum12" style="color: #606060;"> 12:</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="lnum13" style="color: #606060;"> 13:</span> Height = 400,</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="lnum14" style="color: #606060;"> 14:</span> Width = 600,</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="lnum15" style="color: #606060;"> 15:</span> Top = 24,</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="lnum16" style="color: #606060;"> 16:</span> Left = 30,</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="lnum17" style="color: #606060;"> 17:</span> Title = <span style="color: #006080;">"Silverlight Show New Window"</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="lnum18" style="color: #606060;"> 18:</span> Content = <span style="color: #0000ff;">new</span> Button() { Content = <span style="color: #006080;">"Can be any Framework Element"</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="lnum19" style="color: #606060;"> 19:</span> Visibility = Visibility.Visible</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="lnum20" style="color: #606060;"> 20:</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="lnum21" style="color: #606060;"> 21:</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="lnum22" style="color: #606060;"> 22:</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="lnum23" style="color: #606060;"> 23:</span> }</pre> <!--CRLF--></div> </div> <p>This application will spawn 5 windows when you run it. Below is a sample screenshot from the application with 2 additional windows showing. The other windows are closed for demonstration purposes. </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/________3_2.png"><img style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="3" alt="3" src="http://www.silverlightshow.net/Storage/Users/mbcrump/________3_thumb.png" width="472" height="289" /></a></p> <h3>Unrestricted File System Access in Full Trust</h3> <p>Have you ever wanted to write a file anywhere on a users computer in earlier versions of Silverlight but found out that you couldn’t? Well in Silverlight 5 you can. </p> <p>Just like the earlier samples make this an out-of-browser application and add Elevated Trust. (See the P/Invoke demo at the beginning of this article for a quick-how to.)</p> <p>Switch over to the MainPage.xaml and add in the following code:</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;">Grid</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="LayoutRoot"</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="White"</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;">Button</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="23"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="169,132,0,0"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Top"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="75"</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="btnclick"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="click"</span> <span style="color: #ff0000;">Click</span><span style="color: #0000ff;">="click_Click"</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;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>Let’s switch back over to the MainPage.xaml.cs and add the following code to our button event handler:</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;">private</span> <span style="color: #0000ff;">void</span> click_Click(<span style="color: #0000ff;">object</span> sender, RoutedEventArgs e)</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> <span style="color: #008000;">// Create a Directory on the Root of C</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> var tempDirectory = <span style="color: #006080;">@"c:\michaelcrump"</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> <span style="color: #0000ff;">if</span> (!Directory.Exists(tempDirectory))</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="lnum6" style="color: #606060;"> 6:</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="lnum7" style="color: #606060;"> 7:</span> Directory.CreateDirectory(tempDirectory);</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="lnum8" style="color: #606060;"> 8:</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="lnum9" style="color: #606060;"> 9:</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="lnum10" style="color: #606060;"> 10:</span> <span style="color: #008000;">// Give it a FileName</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="lnum11" style="color: #606060;"> 11:</span> var filename = <span style="color: #0000ff;">string</span>.Format(<span style="color: #006080;">"slshowrocks.txt"</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="lnum12" style="color: #606060;"> 12:</span> var fullPath = System.IO.Path.Combine(tempDirectory, filename);</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="lnum13" style="color: #606060;"> 13:</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="lnum14" style="color: #606060;"> 14:</span> <span style="color: #008000;">// Write Something in the File!</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="lnum15" style="color: #606060;"> 15:</span> <span style="color: #0000ff;">using</span> (FileStream fs = File.Create(fullPath))</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="lnum16" style="color: #606060;"> 16:</span> <span style="color: #0000ff;">using</span> (StreamWriter sr = <span style="color: #0000ff;">new</span> StreamWriter(fs, Encoding.UTF8))</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="lnum17" style="color: #606060;"> 17:</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="lnum18" style="color: #606060;"> 18:</span> sr.WriteLine(<span style="color: #006080;">"Hello World"</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="lnum19" style="color: #606060;"> 19:</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="lnum20" style="color: #606060;"> 20:</span> }</pre> <!--CRLF--></div> </div> <p>This will create a directory on our C:\ called michaelcrump. Then it will create a file named “slshowrocks.txt” and give it some content. If you run the application and click on the button then you should have the new folder/file created on your root hard disk. </p> <p>If Visual Studio 2010 is complaining of any missing namespaces then just make sure you add the following: </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;">using</span> System.IO;</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;">using</span> System.Text;</pre> <!--CRLF--></div> </div> <p>Very easy to accomplish and it is not limited to writing files. You can also read files from anywhere on the hard disk! In the next part of this series, we will look at letting the user specify the location of the saved file. </p> <h3>Conclusion</h3> <p>At this point, we have seen how you would use P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust in your Silverlight 5 Applications. We have also discussed a few other features in Silverlight 5. In the next part of the series, I am going to take a look at more new operating system features including : Default Filename for SaveFileDialog, 64-bit browser support and Power Awareness.  Again, thanks for reading and please come back for the next part.</p> <p>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</p> http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx editorial@silverlightshow.net (Michael Crump ) http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx#comments http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx Tue, 15 Nov 2011 08:15:00 GMT 10 Laps around Silverlight 5 (Part 5 of 10) <div style="border:1px solid #dddddd;border-image: initial; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px; text-align: center;"><em><strong>This article is sponsored by <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Click&Mode=HTML&SiteID=1&PageID=41808" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Get&Mode=HTML&SiteID=1&PageID=41808" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik RadControls for Silverlight</a>. For similarly awesome content check out <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Click&Mode=HTML&SiteID=1&PageID=3019" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Get&Mode=HTML&SiteID=1&PageID=3019" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik XAMLflix</a>, your step-by-step guide to Telerik Silverlight and WPF controls. Get access to video tutorials, written tutorials, and tons of code! </strong></em></div> <div style="text-align: right;"><br /> <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://slshow.net/tf8nfb " data-text="Reading SilverlightShow article '10 Laps around Silverlight 5 (Part 5 of 10)' by @mbcrump #sl5" data-count="horizontal" data-counturl="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx" data-via="silverlightshow">Tweet</a></div> <p>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</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/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; border-image: initial;" 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></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 5 of the series “10 Laps around Silverlight 5.” If you have missed any other section then please see the Roadmap below. <br /> <br /> To refresh your memory on what Silverlight is: </p> <p>Microsoft Silverlight is an application framework for writing Rich Internet Applications. The run-time environment is available as a plug-in for most web browsers and works on a variety of operating systems including Windows, Mac and Linux.</p> <p>To recap what we learned in the <a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-4-of-10.aspx">previous section</a>:</p> <ul> <li>We discussed the new media features included with Silverlight 5. </li> <li>We looked at using Low-Latency Sound with XNA SoundEffect and SoundEffectInstance classes. </li> <li>We also learned how to use remote control and media command (keys) support.  </li> </ul> <p>In this article, I am going to discuss the new text improvements in Silverlight 5 including: Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions. Please review the Roadmap for the series before going any further.</p> <h3>The Roadmap for this Series</h3> <p>I’ve included the Roadmap for the series below as you may want to visit other sections as you learn Silverlight 5. I picked the following features as I thought that you may find them useful in your day-to-day work. If you want a specific topic covered then please leave it in the comments below.</p> <p>1) <strong><a href="http://www.silverlightshow.net/items/Silverlight-5-Part-1-of-10.aspx">Introduction to SL5 – This post which provides a brief history of Silverlight and relevant links.</a></strong> </p> <p>2) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-2-of-10.aspx">Binding- Ancestor Relative Source Binding and Implicit Data Templates.</a></strong></p> <p>3) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-3.aspx" target="_self"><strong>Graphics</strong> <strong>–XNA 3D API and Improved Graphics Stack</strong>.</a></p> <p>4) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-4-of-10.aspx">Media - Low-Latency Sound using XNA and Remote Control and Media Command (Keys) Support.</a></strong></p> <p>5) <strong>Text [This post]</strong> - Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions.</p> <p>6) <a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx" target="_self"><strong>Operating System Integration Part 1 - P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust.</strong></a></p> <p>7) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.aspx" target="_self"><strong>Operating System Integration Part 2 - Default Filename for SaveFileDialog, 64-bit browser support and Power Awareness.</strong></a></p> <p>8) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.aspx"><strong>Productivity and Performance - XAML Binding Debugging, Parser Performance Improvements and Multi-core JIT for improved start-up time.</strong></a></p> <p>9) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-9-of-10.aspx">Controls - Double and Triple click support, PivotViewer and ComboBox Type-Ahead.</a></strong></p> <p>10) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-10-of-10.aspx" target="_self">Other items - In-Browser HTML, PostScript and Tasks for TPL.</a></strong></p> <h3></h3> <h3>Linked and Multi-Column Text</h3> <p>We will use an example that I’ve demonstrated in the past that many have found helpful. The Linked and Multi-Column Text feature enables the text of a RichTextBlock control to overflow from one into the next. Multiple RichTextBlockOverflows can be chained together to spread text across a layout. Let’s go ahead and take a look at a screenshot of a RichTextBlock with a RichTextBlockOverflow working together.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/1_6.png"><img width="705" height="512" title="1" style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="1" src="http://www.silverlightshow.net/Storage/Users/mbcrump/1_thumb_2.png" /></a></p> <p>As you can see from this screenshot, we had a RichTextBlock in the upper left and its content overflowed onto the RichTextBlockOverFlow #1, #2 and #3. You can think of this as something that is similar to a newspaper article. As the browser expands or contracts the content fills the available area.</p> <p>Let’s check out the code that made it happen: </p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</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></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="White"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="0.415*"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="0.168*"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ColumnDefinition</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="0.418*"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.RowDefinitions</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RowDefinition</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="0.373*"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RowDefinition</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="0.143*"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RowDefinition</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="0.483*"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.RowDefinitions</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="Blue"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> 15:</span> <span style="color: #ff0000;">Stroke</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: #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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> 16:</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</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-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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> 17:</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">ColumnSpan</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-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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> 18:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Rectangle</span> <span style="color: #ff0000;">Fill</span><span style="color: #0000ff;">="Blue"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> 19:</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="-1,0,1,0"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> 20:</span> <span style="color: #ff0000;">Stroke</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-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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> 21:</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">RowSpan</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-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; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> 22:</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</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-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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> 23:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RichTextBlock</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="rtb1"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> 24:</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,0,5,3"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> 25:</span> <span style="color: #ff0000;">OverflowContentTarget</span><span style="color: #0000ff;">="{Binding ElementName=rtb2}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> 26:</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> 27:</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> 28:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Paragraph</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> 29:</span> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum tincidunt vestibulum. Quisque accumsan nibh nisl. Aenean eget leo enim. Aenean tincidunt nulla nec elit vestibulum sit amet posuere arcu laoreet. Curabitur diam nisi, ullamcorper vel consectetur sed, volutpat nec orci. Aenean eu purus sit amet diam sollicitudin vulputate sed in sapien. Sed pulvinar viverra sapien, a elementum arcu fringilla sed. Proin tincidunt iaculis fringilla. Proin semper venenatis nisi vel hendrerit. Etiam elementum bibendum dignissim. Integer tincidunt pharetra est, ut porttitor urna dictum at. Nulla nisi velit, consequat accumsan tincidunt id, congue vitae lacus. Donec convallis est ligula. Suspendisse fermentum pharetra cursus. Maecenas a gravida nunc. In ante lacus, sollicitudin blandit adipiscing vel, mollis sed ipsum. Nullam a est nec tortor porttitor consectetur. Aliquam consequat pharetra rutrum. Pellentesque viverra dapibus scelerisque. Praesent ullamcorper, sapien vitae facilisis varius, nibh justo luctus odio, faucibus viverra risus metus non lacus. Sed porta, magna in tincidunt fringilla, elit elit sollicitudin sem, et ornare mi nulla hendrerit augue. Vestibulum vitae mollis dolor.</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> 30:</span> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum tincidunt vestibulum. Quisque accumsan nibh nisl. Aenean eget leo enim. Aenean tincidunt nulla nec elit vestibulum sit amet posuere arcu laoreet. Curabitur diam nisi, ullamcorper vel consectetur sed, volutpat nec orci. Aenean eu purus sit amet diam sollicitudin vulputate sed in sapien. Sed pulvinar viverra sapien, a elementum arcu fringilla sed. Proin tincidunt iaculis fringilla. Proin semper venenatis nisi vel hendrerit. Etiam elementum bibendum dignissim. Integer tincidunt pharetra est, ut porttitor urna dictum at. Nulla nisi velit, consequat accumsan tincidunt id, congue vitae lacus. Donec convallis est ligula. Suspendisse fermentum pharetra cursus. Maecenas a gravida nunc. In ante lacus, sollicitudin blandit adipiscing vel, mollis sed ipsum. Nullam a est nec tortor porttitor consectetur. Aliquam consequat pharetra rutrum. Pellentesque viverra dapibus scelerisque. Praesent ullamcorper, sapien vitae facilisis varius, nibh justo luctus odio, faucibus viverra risus metus non lacus. Sed porta, magna in tincidunt fringilla, elit elit sollicitudin sem, et ornare mi nulla hendrerit augue. Vestibulum vitae mollis dolor.</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> 31:</span> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum tincidunt vestibulum. Quisque accumsan nibh nisl. Aenean eget leo enim. Aenean tincidunt nulla nec elit vestibulum sit amet posuere arcu laoreet. Curabitur diam nisi, ullamcorper vel consectetur sed, volutpat nec orci. Aenean eu purus sit amet diam sollicitudin vulputate sed in sapien. Sed pulvinar viverra sapien, a elementum arcu fringilla sed. Proin tincidunt iaculis fringilla. Proin semper venenatis nisi vel hendrerit. Etiam elementum bibendum dignissim. Integer tincidunt pharetra est, ut porttitor urna dictum at. Nulla nisi velit, consequat accumsan tincidunt id, congue vitae lacus. Donec convallis est ligula. Suspendisse fermentum pharetra cursus. Maecenas a gravida nunc. In ante lacus, sollicitudin blandit adipiscing vel, mollis sed ipsum. Nullam a est nec tortor porttitor consectetur. Aliquam consequat pharetra rutrum. Pellentesque viverra dapibus scelerisque. Praesent ullamcorper, sapien vitae facilisis varius, nibh justo luctus odio, faucibus viverra risus metus non lacus. Sed porta, magna in tincidunt fringilla, elit elit sollicitudin sem, et ornare mi nulla hendrerit augue. Vestibulum vitae mollis dolor.</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> 32:</span> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum tincidunt vestibulum. Quisque accumsan nibh nisl. Aenean eget leo enim. Aenean tincidunt nulla nec elit vestibulum sit amet posuere arcu laoreet. Curabitur diam nisi, ullamcorper vel consectetur sed, volutpat nec orci. Aenean eu purus sit amet diam sollicitudin vulputate sed in sapien. Sed pulvinar viverra sapien, a elementum arcu fringilla sed. Proin tincidunt iaculis fringilla. Proin semper venenatis nisi vel hendrerit. Etiam elementum bibendum dignissim. Integer tincidunt pharetra est, ut porttitor urna dictum at. Nulla nisi velit, consequat accumsan tincidunt id, congue vitae lacus. Donec convallis est ligula. Suspendisse fermentum pharetra cursus. Maecenas a gravida nunc. In ante lacus, sollicitudin blandit adipiscing vel, mollis sed ipsum. Nullam a est nec tortor porttitor consectetur. Aliquam consequat pharetra rutrum. Pellentesque viverra dapibus scelerisque. Praesent ullamcorper, sapien vitae facilisis varius, nibh justo luctus odio, faucibus viverra risus metus non lacus. Sed porta, magna in tincidunt fringilla, elit elit sollicitudin sem, et ornare mi nulla hendrerit augue. Vestibulum vitae mollis dolor.</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> 33:</span> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum tincidunt vestibulum. Quisque accumsan nibh nisl. Aenean eget leo enim. Aenean tincidunt nulla nec elit vestibulum sit amet posuere arcu laoreet. Curabitur diam nisi, ullamcorper vel consectetur sed, volutpat nec orci. Aenean eu purus sit amet diam sollicitudin vulputate sed in sapien. Sed pulvinar viverra sapien, a elementum arcu fringilla sed. Proin tincidunt iaculis fringilla. Proin semper venenatis nisi vel hendrerit. Etiam elementum bibendum dignissim. Integer tincidunt pharetra est, ut porttitor urna dictum at. Nulla nisi velit, consequat accumsan tincidunt id, congue vitae lacus. Donec convallis est ligula. Suspendisse fermentum pharetra cursus. Maecenas a gravida nunc. In ante lacus, sollicitudin blandit adipiscing vel, mollis sed ipsum. Nullam a est nec tortor porttitor consectetur. Aliquam consequat pharetra rutrum. Pellentesque viverra dapibus scelerisque. Praesent ullamcorper, sapien vitae facilisis varius, nibh justo luctus odio, faucibus viverra risus metus non lacus. Sed porta, magna in tincidunt fringilla, elit elit sollicitudin sem, et ornare mi nulla hendrerit augue. Vestibulum vitae mollis dolor.</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> 34:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> 35:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Paragraph</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> 36:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">RichTextBlock</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> 37:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RichTextBlockOverflow</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="rtb2"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> 38:</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</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: 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; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> 39:</span> <span style="color: #ff0000;">OverflowContentTarget</span><span style="color: #0000ff;">="{Binding ElementName=rtb3}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum40" style="color: #606060;"> 40:</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum41" style="color: #606060;"> 41:</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum42" style="color: #606060;"> 42:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RichTextBlockOverflow</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="rtb3"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum43" style="color: #606060;"> 43:</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</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-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; padding-top: 0px;border-style: none;"><span id="lnum44" style="color: #606060;"> 44:</span> <span style="color: #ff0000;">OverflowContentTarget</span><span style="color: #0000ff;">="{Binding ElementName=rtb4}"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum45" style="color: #606060;"> 45:</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum46" style="color: #606060;"> 46:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> 47:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RichTextBlockOverflow</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="rtb4"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum48" style="color: #606060;"> 48:</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</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: 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; padding-top: 0px;border-style: none;"><span id="lnum49" style="color: #606060;"> 49:</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</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-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; padding-top: 0px;border-style: none;"><span id="lnum50" style="color: #606060;"> 50:</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum51" style="color: #606060;"> 51:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum52" style="color: #606060;"> 52:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum53" style="color: #606060;"> 53:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>The key thing to remember here is that a RichTextBlock contains <em><span style="text-decoration: underline;">OverflowContentTarget</span></em> which will allow you to bind to a special control called <em><span style="text-decoration: underline;">RichTextBlockOverflow</span></em>. </p> <p><strong>NOTE: Post-beta, Microsoft changed this to use the non-editable RichTextBlock instead of RichTextBox. So a word of warning, many post-beta demos of this functionality on the web will no longer work. Good thing you are reading this guide, right? =)</strong></p> <h3> </h3> <h3></h3> <h3>Character Spacing</h3> <p>The TextBox and TextBlock controls provides a way to control the spacing of letters inside the text very easily. Let’s go ahead and take a look at a screenshot of the various character spacing inside of a TextBlock.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/______2_2.png"><img width="674" height="144" title="2" style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="2" src="http://www.silverlightshow.net/Storage/Users/mbcrump/______2_thumb.png" /></a></p> <p>Let’s look at the code: </p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</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: #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-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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> <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; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">CharacterSpacing</span><span style="color: #0000ff;">="1000"</span> <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="14"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="The quick brown fox jumps over the lazy dog"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">CharacterSpacing</span><span style="color: #0000ff;">="500"</span> <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="14"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="The quick brown fox jumps over the lazy dog"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">CharacterSpacing</span><span style="color: #0000ff;">="250"</span> <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="14"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="The quick brown fox jumps over the lazy dog"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">CharacterSpacing</span><span style="color: #0000ff;">="100"</span> <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="14"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="The quick brown fox jumps over the lazy dog"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">CharacterSpacing</span><span style="color: #0000ff;">="-100"</span> <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="14"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="The quick brown fox jumps over the lazy dog"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> <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; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>As you can see, we just set the CharacterSpacing property of the TextBlock control. Please note that you may use a negative number to “squish” text together. </p> <h3>Open-Type Font</h3> <p>Silverlight 5 provides many new options for the <strong><a href="http://msdn.microsoft.com/en-us/library/system.windows.media.typography(v=vs.96).aspx">Typography</a></strong> class inside of a TextBlock. They have so many improvements that the best way to see everything is to explore the class. Let’s look at two new features: </p> <ol> <li>ContextualAlternates - Gets or sets a value that determines whether custom glyph forms can be used based upon the context of the text being rendered. </li> <li>StylisticSets - Gets or sets a value that indicates whether a stylistic set of a font form is enabled. (20 StylisticSets are available) </li> </ol> <p>Let’s look at a sample that uses ContextualAlternates and StylisticSets. </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_______4_2.png"><img width="431" height="109" title="4" style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="4" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_______4_thumb.png" /></a></p> <p>The code looks like the following: </p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="80"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: #ff0000;">FontFamily</span><span style="color: #0000ff;">="Gabriola"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="Michael Crump"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> <span style="color: #ff0000;">Typography</span>.<span style="color: #ff0000;">ContextualAlternates</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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: #ff0000;">Typography</span>.<span style="color: #ff0000;">StylisticSet5</span><span style="color: #0000ff;">="True"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--></div> </div> <br /> <h3>Pixel Snapped Text and TextOptions</h3> <p>Silverlight 5 provides many new options for the <strong>TextOptions</strong> property inside of a TextBlock. </p> <ol> <li>TextFormattingMode – Gets the TextFormattingMode for the element </li> <li>TextHintingMode – Gets or sets a value that indicates whether text rendering is optimized for readability or animation. </li> <li>TextRenderingMode - Sets the TextRenderingMode for the element. 4 options are available: Aliased, Auto, ClearType and Grayscale. </li> </ol> <p>Let’s look at a sample that uses all of them together (Display, Fixed and Aliased).  It may be hard to see in this demo, so try this one in your own application. </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_______3_2.png"><img width="495" height="55" title="3" style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="3" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_______3_thumb.png" /></a></p> <p>The code looks like the following: </p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">FontSize</span><span style="color: #0000ff;">="30"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="The quick brown fox jumps over the lazy dog"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: #ff0000;">TextOptions</span>.<span style="color: #ff0000;">TextFormattingMode</span><span style="color: #0000ff;">="Display"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #ff0000;">TextOptions</span>.<span style="color: #ff0000;">TextHintingMode</span><span style="color: #0000ff;">="Fixed"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> <span style="color: #ff0000;">TextOptions</span>.<span style="color: #ff0000;">TextRenderingMode</span><span style="color: #0000ff;">="Aliased"</span> <span style="color: #0000ff;">/></span></pre> <!--CRLF--></div> </div> <h3>Conclusion</h3> <p>At this point, we have seen how you would use Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions in your Silverlight 5 Applications.  We have also discussed a few other features in Silverlight 5. In the next part of the series, I am going to take a look at the new operating system integrations including : P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust.  Again, thanks for reading and please come back for the next part.</p> <p>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</p> http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx editorial@silverlightshow.net (Michael Crump ) http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx#comments http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx Tue, 08 Nov 2011 20:18:00 GMT 10 Laps around Silverlight 5 (Part 4 of 10) <div style="border:1px solid #dddddd;border-image: initial; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px; text-align: center;"><em><strong>This article is sponsored by <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Click&Mode=HTML&SiteID=1&PageID=41808" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=81&Task=Get&Mode=HTML&SiteID=1&PageID=41808" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik RadControls for Silverlight</a>. For similarly awesome content check out <a href="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Click&Mode=HTML&SiteID=1&PageID=3019" target="_blank"> <img alt="" src="http://ads.silverlightshow.net/a.aspx?ZoneID=82&Task=Get&Mode=HTML&SiteID=1&PageID=3019" width="0" height="0" style="border-width: 0px;border-style: solid;" />Telerik XAMLflix</a>, your step-by-step guide to Telerik Silverlight and WPF controls. Get access to video tutorials, written tutorials, and tons of code! </strong></em></div> <p><a href="http://twitter.com/home?status=Reading+this+article+http%3A%2F%2Fslshow.net%2Fuvvy48+by+%40silverlightshow+%26+%40mbcrump%3A+10+Laps+around+%23Silverlight+5+%28Part+4+of+10%29+%23sl5+cc+%40Telerik+" target="_blank"><img style="border:0px solid; border-image: initial; margin-bottom: 10px; float: right; margin-left: 20px;" alt="Tweet This!" src="http://www.silverlightshow.net/Storage/tt-big4.png" /></a>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</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/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; border-image: initial;" 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></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 the series “10 Laps around Silverlight 5.” If you have missed any other section then please see the Roadmap below. <br /> <br /> To refresh your memory on what Silverlight is: </p> <p>Microsoft Silverlight is an application framework for writing Rich Internet Applications. The run-time environment is available as a plug-in for most web browsers and works on a variety of operating systems including Windows, Mac and Linux.</p> <p>To recap what we learned in the <a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-3.aspx">previous section</a>:</p> <ul> <li>We briefly discussed what XNA is. </li> <li>We looked at the templates available for new XNA Silverlight 5 projects. </li> <li>We dissected the 3D XNA Template to learn more about it’s makeup. </li> <li>Pointed out where other sample projects for XNA were located on your hard disk. </li> </ul> <p>In this article, I am going to discuss media features such as low-latency sound using features right out of XNA. We will also discuss Remote Control and Media Command (Keys) support using Silverlight 5. Please review the Roadmap for the series before going any further.</p> <h3>The Roadmap for this Series</h3> <p>I’ve included the Roadmap for the series below as you may want to visit other sections as you learn Silverlight 5. I picked the following features as I thought that you may find them useful in your day-to-day work. If you want a specific topic covered then please leave it in the comments below.</p> <p>1) <strong><a href="http://www.silverlightshow.net/items/Silverlight-5-Part-1-of-10.aspx">Introduction to SL5 – This post which provides a brief history of Silverlight and relevant links.</a></strong> </p> <p>2) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-2-of-10.aspx">Binding- Ancestor Relative Source Binding and Implicit Data Templates.</a></strong></p> <p>3) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-3.aspx" target="_self"><strong>Graphics</strong> <strong>–XNA 3D API and Improved Graphics Stack</strong>.</a></p> <p>4) <strong>Media <strong>[This Post]</strong></strong> - Low-Latency Sound using XNA and Remote Control and Media Command (Keys) Support.</p> <p>5) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-5-of-10.aspx" target="_self"><strong>Text - Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions.</strong></a></p> <p>6) <a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-6-of-10.aspx" target="_self"><strong>Operating System Integration Part 1 - P/Invoke, Multiple Windows and Unrestricted File System Access in Full Trust.</strong></a></p> <p>7) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-7-of-10.aspx" target="_self"><strong>Operating System Integration Part 2 - Default Filename for SaveFileDialog, 64-bit browser support and Power Awareness.</strong></a></p> <p>8) <strong></strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-8-of-10.aspx"><strong>Productivity and Performance - XAML Binding Debugging, Parser Performance Improvements and Multi-core JIT for improved start-up time.</strong></a></p> <p>9) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-9-of-10.aspx">Controls - Double and Triple click support, PivotViewer and ComboBox Type-Ahead.</a></strong></p> <p>10) <strong><a href="http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-10-of-10.aspx">Other items - In-Browser HTML, PostScript and Tasks for TPL.</a></strong></p> <h3></h3> <h3>Let’s Begin with Low-Latency Sound using XNA SoundEffect</h3> <p>A new addition to Silverlight 5 is the ability to play low-latency sounds using the XNA SoundEffect class. This is very useful for kiosk or even games that need to play a certain sound over and over.  In Silverlight 5, this is much easier than before (where people used various MediaElement hacks). You can now simply borrow the SoundEffect / SoundEffectInstance class from XNA. </p> <h3>Start with a new Silverlight 5 Project</h3> <p>Launch Visual Studio 2010 and select File –> New Project. Then select Silverlight –> Silverlight Application –> Give it a name and hit OK.</p> <p>On the New Silverlight Application Screen, you will see under “Options” that you may select which version of Silverlight that you want to use. We will select Silverlight 5 for this option. If you don’t see Silverlight 5 as an option then follow the guide <a href="http://www.silverlightshow.net/items/Silverlight-5-Part-1-of-10.aspx">here</a>. </p> <p>The first thing you are going to want to do is to find a .wav file on the net that is PCM-encoded. They are very easy to find with a quick Google search. I am not going to include one for copyright reasons. </p> <p>Now, right-click your Silverlight 5 project and select “<strong>Add</strong>”, then “<strong>Existing Item</strong>.” You can also easily access this screen by hitting “<strong>Shift-Alt-A</strong>” together.  Navigate to wherever you downloaded the .wav file and select the file. <br /> <br /> At this point, make sure the .wav file has a build action set to “<strong>Content</strong>”, as shown below.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/____1_2.png"><img width="300" height="530" title="1" style="border:0px solid; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="1" src="http://www.silverlightshow.net/Storage/Users/mbcrump/____1_thumb.png" /></a></p> <p>Once this is complete, we will need to make a minor adjustment to our MainPage.xaml file to include a button to play the file for this demo. </p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</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;">Background</span><span style="color: #0000ff;">="White"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Button"</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="23"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="0,277,0,0"</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="btnPlaySound"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Top"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="75"</span> <span style="color: #ff0000;">Click</span><span style="color: #0000ff;">="btnPlaySound_Click"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>The only thing that we added to our MainPage.xaml file was a button inside of the Grid that has an event handler when the user clicks the button. </p> <p>We can navigate over to our MainPage.xaml.cs file and add the following code snippet:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> btnPlaySound_Click(<span style="color: #0000ff;">object</span> sender, RoutedEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> var soundStream =</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> Application.GetResourceStream(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: #0000ff;">new</span> Uri(<span style="color: #006080;">"stereol.wav"</span>, UriKind.RelativeOrAbsolute));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> var effect = SoundEffect.FromStream(soundStream.Stream);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> SoundEffectInstance engineInstance = effect.CreateInstance();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span> engineInstance.IsLooped = <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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> engineInstance.Pitch = -1.0f;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> engineInstance.Volume = 0.75f;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> 15:</span> engineInstance.Play();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> 16:</span> }</pre> <!--CRLF--></div> </div> <p>In this code snippet, we are using several new features. Let’s examine the code snippet line by line: </p> <ul> <li>Lines 3-5 creates our resource stream from the wav file that added earlier.  </li> <li>Lines 7-9 is initializing the SoundEffectInstance class that is going to perform special effects for the .wav file.   </li> <li>Lines 11-13 is creating a looped wav file that sets the pitch and the volume. </li> <li>Lines 15 simply plays the files. </li> </ul> <p>Don’t forget to add the proper namespace and reference to your project. </p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">using</span> Microsoft.Xna.Framework.Audio;</pre> <!--CRLF--></div> </div> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_____2_2.png"><img width="311" height="345" title="2" style="border:0px solid; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="2" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_____2_thumb.png" /></a></p> <p>If you load the application now, you will hear your .wav file being played over and over again. The pitch and volume has also been adjusted. Easy enough! <br /> <br /> Let’s move onto Remote Control and media keys support. </p> <h3>Remote Control and Media Command (Keys) Support</h3> <p>One of the new improvements in Silverlight 5 is the ability to support Remote Control and Media Commands from various hardware manufactures. Below is a sample keyboard and remote control that has buttons for features such as (fast forward, stop, play, rewind, etc). Now we are able to make use of those buttons in Silverlight 5 with a few lines of code.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/______3_2.png"><img width="601" height="213" title="3" style="border:0px solid; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="3" src="http://www.silverlightshow.net/Storage/Users/mbcrump/______3_thumb.png" /></a></p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/______4_2.png"><img width="240" height="182" title="4" style="border:0px solid; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="4" src="http://www.silverlightshow.net/Storage/Users/mbcrump/______4_thumb.png" /></a></p> <h2>Let’s get started. </h2> <p>Launch Visual Studio 2010 and select File –> New Project. Then select Silverlight –> Silverlight Application –> Give it a name and hit OK.</p> <p>On the New Silverlight Application Screen, you will see under “Options” that you may select which version of Silverlight that you want to use. We will select Silverlight 5 for this option. If you don’t see Silverlight 5 as an option then follow the guide <a href="http://www.silverlightshow.net/items/Silverlight-5-Part-1-of-10.aspx">here</a>. </p> <p>The first thing you are going to want to do is to find a .<strong>wmv</strong> file that you can use for this application. I decided to use the <strong>wildlife.wmv</strong> file available on every Windows 7 PC. Just like before, I am not going to include it due to copyright reasons. </p> <p>Now, right-click your Silverlight 5 project and select “<strong>Add</strong>”, then “<strong>Existing Item</strong>.” You can also easily access this screen by hitting “<strong>Shift-Alt-A</strong>” together. Navigate to wherever you downloaded the .<strong>wmv</strong> file and select the file. <br /> <br /> At this point, make sure the .<strong>wmv</strong> file has a build action set to “<strong>Content</strong>”, as shown below.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_____5_2.png"><img width="295" height="518" title="5" style="border:0px solid; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="5" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_____5_thumb.png" /></a></p> <p>Once this is complete, we will need to make a few minor adjustment to our MainPage.xaml file to play a video.  </p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</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;">Background</span><span style="color: #0000ff;">="White"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">MediaElement</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="videoPlayer"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> <span style="color: #ff0000;">Source</span><span style="color: #0000ff;">="/Wildlife.wmv"</span> <span style="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-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; 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; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="txtMediaKey"</span> <span style="color: #ff0000;">Foreground</span><span style="color: #0000ff;">="Red"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Right"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Bottom"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="5"</span> <span style="color: #ff0000;">FontSize</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: #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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="FullScreen"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Bottom"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Go Full Screen"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="5"</span> <span style="color: #ff0000;">Click</span><span style="color: #0000ff;">="FullScreen_Click"</span> <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>We added the following items to our MainPage.xaml file:</p> <ul> <li>MediaElement control – This will play the video and give us the ability to stop/start/pause the video using the Media Controls on our keyboard/remote control.  </li> <li>TextBlock control – To display which MediaCommand code is being executed. (Excellent for debugging) </li> <li>Button control – To toggle between FullScreen mode. </li> </ul> <p>We can navigate over to our MainPage.xaml.cs file and add the following code snippet:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;border-image: initial; padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">public</span> MainPage()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> 3:</span> InitializeComponent();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> 4:</span> <span style="color: #0000ff;">this</span>.MediaCommand += <span style="color: #0000ff;">new</span> MediaCommandEventHandler(MainPage_MediaCommand);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> 5:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> 6:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> 7:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> MainPage_MediaCommand(<span style="color: #0000ff;">object</span> sender, MediaCommandEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> 8:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> 9:</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> 10:</span> txtMediaKey.Text = e.MediaCommand.ToString();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> 11:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> 12:</span> <span style="color: #0000ff;">switch</span> (e.MediaCommand)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> 13:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> 14:</span> <span style="color: #0000ff;">case</span> System.Windows.Media.MediaCommand.Play:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> 15:</span> videoPlayer.Play();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> 16:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> 17:</span> <span style="color: #0000ff;">case</span> System.Windows.Media.MediaCommand.Pause:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> 18:</span> videoPlayer.Pause();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> 19:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> 20:</span> <span style="color: #0000ff;">case</span> System.Windows.Media.MediaCommand.Stop:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> 21:</span> videoPlayer.Stop();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> 22:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> 23:</span> <span style="color: #0000ff;">case</span> System.Windows.Media.MediaCommand.TogglePlayPause:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> 24:</span> <span style="color: #0000ff;">if</span> (videoPlayer.CurrentState == MediaElementState.Paused ||</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> 25:</span> videoPlayer.CurrentState == MediaElementState.Stopped)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> 26:</span> videoPlayer.Play();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> 27:</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (videoPlayer.CurrentState == MediaElementState.Playing)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> 28:</span> <span style="color: #0000ff;">if</span> (videoPlayer.CanPause)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> 29:</span> videoPlayer.Pause();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> 30:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> 31:</span> <span style="color: #0000ff;">case</span> System.Windows.Media.MediaCommand.IncreaseVolume:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> 32:</span> videoPlayer.Volume += 5;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> 33:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> 34:</span> <span style="color: #0000ff;">case</span> System.Windows.Media.MediaCommand.DecreaseVolume:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> 35:</span> videoPlayer.Volume -= 5;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> 36:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> 37:</span> <span style="color: #0000ff;">case</span> System.Windows.Media.MediaCommand.ChannelUp:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> 38:</span> <span style="color: #008000;">// Channel up</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> 39:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum40" style="color: #606060;"> 40:</span> <span style="color: #0000ff;">case</span> System.Windows.Media.MediaCommand.ChannelDown:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum41" style="color: #606060;"> 41:</span> <span style="color: #008000;">// Channel down</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum42" style="color: #606060;"> 42:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum43" style="color: #606060;"> 43:</span> <span style="color: #0000ff;">default</span>:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum44" style="color: #606060;"> 44:</span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum45" style="color: #606060;"> 45:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum46" style="color: #606060;"> 46:</span> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> 47:</span>  </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum48" style="color: #606060;"> 48:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> FullScreen_Click(<span style="color: #0000ff;">object</span> sender, RoutedEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum49" style="color: #606060;"> 49:</span> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum50" style="color: #606060;"> 50:</span> Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum51" style="color: #606060;"> 51:</span> }</pre> <!--CRLF--></div> </div> <p>Let’s examine the code snippet line by line: </p> <ul> <li>Line 4 creates our MediaCommand event handler. This is going to hook up to our media commands case statement. </li> <li>Line 10 will simply display which MediaCommand the user has pressed into a TextBlock on the right hand side of the screen. This is useful for debugging applications that use the Media Features in Silverlight 5.  </li> <li>Lines 12-44  is our switch statement that will trigger the respective action on the MediaElement control. </li> <li>Lines 48-51 will simply check to see if the screen is in FullScreen mode and toggle it accordingly.  </li> </ul> <p><em>Note: I didn’t list all of the MediaCommand enums that are available. You can review a complete list </em><a href="http://msdn.microsoft.com/en-us/library/system.windows.media.mediacommand(v=vs.96).aspx"><em>here</em></a><em>.</em> </p> <p>If we run the application our video starts playing: </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/__7_2.png"><img width="421" height="352" title="7" style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="7" src="http://www.silverlightshow.net/Storage/Users/mbcrump/__7_thumb.png" /></a></p> <p>If we hit the “<strong>Play/Pause</strong>” media button on our keyboard (If your hardware supports it) then you will see the video is now paused and the word “<strong>TogglePlayPause</strong>” is located in the bottom right hand corner of our screen. </p> <p><a href="http://www.silverlightshow.net/Storage/Users/mbcrump/_____6_2.png"><img width="423" height="353" title="6" style="border:0px; border-image: initial; background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" alt="6" src="http://www.silverlightshow.net/Storage/Users/mbcrump/_____6_thumb.png" /></a></p> <p>If you hit other media keys then the MediaElement will respond accordingly. You can even try out your WMC remote control if you have one available. </p> <p><em>Please note: If you ever have an issue with the keys responding, then switch to FullScreen mode (by clicking the button) and try again. I’ve found several instances where the Silverlight application loses focus. </em></p> <p>Notice how easy it was to add support for Media Keyboards and Remotes? Silverlight is already known for having a excellent media player and this just enhances it even more!</p> <h2>Conclusion</h2> <p>At this point, we have seen how you would use Low-Latency Sound using XNA and Remote Control and Media Command (Keys) Support in your Silverlight 5 Applications.  We have also discussed a few other features in Silverlight 5. In the next part of the series, I am going to take a look at the new text improvements in Silverlight 5 including: Text Tracking and Leading, Linked and Multi-column Text, OpenType Support, Pixel Snapped Text and TextOptions.  Again, thanks for reading and please come back for the next part.</p> <p>To contact me directly please visit my blog at <a href="http://michaelcrump.net/">http://michaelcrump.net/</a> or through twitter at <a href="http://twitter.com/mbcrump">http://twitter.com/mbcrump</a>.</p> http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-4-of-10.aspx editorial@silverlightshow.net (Michael Crump ) http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-4-of-10.aspx#comments http://www.silverlightshow.net/items/10-Laps-around-Silverlight-5-Part-4-of-10.aspx Tue, 01 Nov 2011 17:58: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 Getting ready for Microsoft Silverlight Exam 70-506 (Part 4) <div style="border:1px solid #dddddd;padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px;"><strong>SilverlightShow</strong> and <strong>Gill Cleeren</strong> start a <strong>series of materials</strong> aimed at helping you get prepared for taking <a href="http://www.microsoft.com/learning/en/us/Exam.aspx?ID=70-506&Locale=en-us" target="_blank">Microsoft Silverlight Exam 70-506</a>. Through this series we will try to structure the resources available on the internet, grouping them by topic covered in the exam. <strong>Any feedback would be much appreciated</strong>! Thanks!  </div> <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/Search.aspx?q=+RichTextBox&adv=false">WCF RIA Services series</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 the series on Microsoft Silverlight Exam.</p> <p>We are making great progress in our Silverlight Exam series, we are now in the fourth part already. A quick look back on the previous parts shows that we started with a deep look at the layout and UI-related material. In the second part, we looked at enhancing the UI using features such as the Visual State Manager. In the previous part, the focus was mainly on the coding part, including topics such as dependency properties, the ICommand interface and working asynchronously with services.</p> <p>This fourth part will focus on a very important aspect: data. Not a single business application works without data and since one of the focus areas of Silverlight of LOB development, Silverlight is well-equipped to handle data. In this part, we’ll look at data binding, which is something you have to understand deeply. The data binding system is very powerful and enables the MVVM pattern. When working with data (mainly the input process), data needs to be validated as well. Silverlight 4 brings some new options, enabling a much cleaner way to perform validation on inputted data.</p> <p>For your convenience, the following list contains links to the other parts of the article series which have been finished already:</p> <ul> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-the-exams-Part-1.aspx">Laying Out a User Interface (15%)</a> </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-2.aspx">Enhancing the User Interface (14%)</a> </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-3.aspx">Implementing Application Logic (16%)</a> </li> <li><strong>Working with Data (17%) –> this part</strong> </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-5.aspx">Interacting with a Host Platform (11%)</a>  </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-6.aspx">Structuring Applications (13%)</a>  </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-7.aspx">Deploying Applications (13%)</a>  </li> </ul> <h4>Part 4: Working with data</h4> <p>As mentioned in the intro, many developers are using Silverlight to build business applications. And of course, business apps need to work with data: displaying data, accepting data input, validating input etc. While all this is very well possible to code manually (using code that looks like MyTextBlock.Text = person.FirstName), it’s prone to errors and gets tedious to write quickly. It’s certainly not the most exciting code to write, I think you’ll agree with me on that.</p> <p>Introducing data binding. It’s easily the most important topic to really grasp when learning Silverlight. The concept of data binding basically comes down to a construct that allows binding – or linking – properties of controls to properties of objects. Instead of having to write all that code manually however, the data binding engine takes a lot of the load out of our hands and lets us create binding from XAML. The data binding engine found in Silverlight is brought in from WPF. WPF’s version has still some more options, but the difference is getting smaller with every new release of Silverlight. Conceptually, data binding is nothing really new. We can do data binding in ASP.NET or WinForms as well; however the model in Silverlight (and WPF of course) is much more loosely coupled.</p> <p>Not only is data binding important to build data-driven applications, it’s also the concept that makes MVVM (Model-View-ViewModel) possible. If you know your way around the pattern, you’ll quite easily understand that the View is bound to an instance of the ViewModel (in other words, an instance of the ViewModel is set as the DataContext for the View). The ViewModel exposes properties and commands to which the elements in the View can bind. For example, a List<T> exposed on the ViewModel can be the source for a data binding on the View. Commands (which we explored in part 3) are exposed as public properties as well and using the Command property on some controls (in Silverlight 4 only on ButtonBase and controls driving from ButtonBase), we can bind an action in the ViewModel to an event in the View. As you’ll understand, the MVVM pattern really builds on the concepts introduced by data binding.</p> <h5>Implement data binding</h5> <p>In this section, we’ll look at all concepts that are linked to data binding. Many of these are closely related, so you’ll learn about them in one go I assume. </p> <p>I did a webinar with SilverlightShow where we look at many data binding topics. You can watch it on-demand from here: <a href="http://www.silverlightshow.net/shows/SilverlightShow-Webinar-Data-Binding-in-Action-by-Gill-Cleeren.aspx">http://www.silverlightshow.net/shows/SilverlightShow-Webinar-Data-Binding-in-Action-by-Gill-Cleeren.aspx</a></p> <p>If you want to read more on data binding itself, take a look at the following links:</p> <ul> <li>Data binding explained on MSDN: <a href="http://msdn.microsoft.com/en-us/library/cc278072(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/cc278072(v=vs.95).aspx</a> </li> <li><a href="http://www.silverlight.net/learn/tutorials/silverlight-4/silverlight-data-binding/">http://www.silverlight.net/learn/tutorials/silverlight-4/silverlight-data-binding/</a> </li> <li><a href="http://www.singingeels.com/Articles/Silverlight_DataBinding_Basics.aspx">http://www.singingeels.com/Articles/Silverlight_DataBinding_Basics.aspx</a> </li> </ul> <p>In the following links and topics, we’ll look at some specifics from data binding:</p> <ul> <li>Setting the data context <br /> We all know that XAML is a hierarchy. The concept of the data context is built on this. Let me explain. <br /> When creating a simple data entry form (for example to gather person data), we can use data binding. All the TextBox instances where data can be entered need to know to which property on a bound object (a Person instance) they are bound. We could do this by specifying on each TextBox the name of the property. While this is possible, it would actually be a lot of work and would perhaps take away some of the benefit we get from using data binding. <br /> The DataContext allows us to define a common source on a higher level in the XAML tree. So, assume all the TextBox instances are children of a Grid, we can set the DataContext of the Grid to be the Person object. When no source is defined on the binding expression, the data binding engine will start searching (using a process referred to as XAML tree walking) up the XAML tree to find a non-null data context. Once found, the object is used as the source for the binding. <br /> The DataContext is often used in MVVM to set a ViewModel instance as the source for the View. <ul> <li>DataContext on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.datacontext(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.datacontext(v=vs.95).aspx</a> </li> <li><a href="http://emil.silverlightshow.net/2010/04/24/data-binding-in-silverlight/">http://emil.silverlightshow.net/2010/04/24/data-binding-in-silverlight/</a> </li> <li><a href="http://www.simple-talk.com/dotnet/.net-framework/data-and-silverlight-2-data-binding/">http://www.simple-talk.com/dotnet/.net-framework/data-and-silverlight-2-data-binding/</a> </li> <li><a href="http://smehrozalam.wordpress.com/2009/03/11/beginning-mvvm-the-basics/">http://smehrozalam.wordpress.com/2009/03/11/beginning-mvvm-the-basics/</a> </li> </ul> </li> <li>Binding data sets to controls <br /> Next to binding a single object to form, we often want to bind a list of items to a list control such as a ListBox. Silverlight’s data binding engine is perfectly capable of this as well. The ItemsSource property on these controls is our friend here and be used for this exact purpose. By default however, we won’t get a good visual representation of the bound data: an item will be shown using its ToString() implementation. That’s often not what we want though. Two solutions exist. The first one is using the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.displaymemberpath.aspx">DisplayMemberPath</a> property of the ItemsControl class. This property allows us to specify which property of the bound item should be used for display (for example FirstName). The second solution is using a DataTemplate, a piece of XAML that’s generated for each item in the List. We looked at DataTemplates in part 3 of this series. <ul> <li><a href="http://msdn.microsoft.com/en-us/library/cc278072(v=vs.95).aspx#binding_to_collections">http://msdn.microsoft.com/en-us/library/cc278072(v=vs.95).aspx#binding_to_collections</a> </li> <li><a href="http://www.silverlightshow.net/items/Tip-of-the-Day-Binding-to-a-Collection.aspx">http://www.silverlightshow.net/items/Tip-of-the-Day-Binding-to-a-Collection.aspx</a> </li> <li><a href="http://www.telerik.com/help/silverlight/binding-to-collections.html">http://www.telerik.com/help/silverlight/binding-to-collections.html</a> </li> </ul> </li> <li>Binding elements to other elements <br /> Most of the time, you’ll be binding properties of controls to properties of data objects. Silverlight also supports bindings between two controls. The best example to understand this is probably binding the Value property of a Slider to the Text property of the TextBlock. <ul> <li><a href="http://www.silverlightshow.net/news/Mini-Tutorial-Element-Binding-.aspx">http://www.silverlightshow.net/news/Mini-Tutorial-Element-Binding-.aspx</a> </li> <li><a href="http://www.snowball.be/CommentView,guid,4c4eb74a-7dd6-42d9-a414-9d09bdf9414b.aspx">http://www.snowball.be/CommentView,guid,4c4eb74a-7dd6-42d9-a414-9d09bdf9414b.aspx</a> </li> </ul> </li> <li>Implementing INotifyPropertyChanged <br /> Something we haven’t talked about yet in the data binding engine is the automatic synchronization between source and target control. The data binding engine makes it possible to update the control in the UI when the source value changes. This is only supported if the source class implements the INotifyPropertyChanged interface however. Basically what happens is that when we bind to an object that implements this interface, Silverlight will listen for an event – the PropertyChanged event – being raised from the object. When this event is raised, Silverlight will update the UI accordingly. Note that this only works if the binding is a OneWay or a TwoWay binding! <ul> <li>INotifyPropertyChanged on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.95).aspx</a> </li> <li><a href="http://www.silverlightshow.net/tips/How-to-implement-INotifyPropertyChanged-interface.aspx">http://www.silverlightshow.net/tips/How-to-implement-INotifyPropertyChanged-interface.aspx</a> </li> <li><a href="http://codepronet.blogspot.com/2009/08/implementing-inotifypropertychanged.html">http://codepronet.blogspot.com/2009/08/implementing-inotifypropertychanged.html</a> </li> </ul> </li> <li>Implementing ObservableCollection <br /> Similar to the INotifyPropertyChanged but then for collections is the INotifyCollectionChanged interface. This can be used to notify the UI about changes in a collection (items being added or removed). This interface is more complicated however and therefore, a special collection type implementing this interface exists, namely the ObservableCollection. When we use this collection, we’ll see the UI stay in sync with the collection if items are added or removed from the collection. <ul> <li>ObservableCollection on MSDN: <a href="http://msdn.microsoft.com/en-us/library/ms668604(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/ms668604(v=vs.95).aspx</a> </li> <li><a href="http://weblogs.asp.net/joelvarty/archive/2008/11/17/silverlight-databinding-the-observable-collection.aspx">http://weblogs.asp.net/joelvarty/archive/2008/11/17/silverlight-databinding-the-observable-collection.aspx</a> </li> </ul> </li> <li>Setting binding modes <br /> Binding modes allow us to specify in what direction the data flows. By default the data flows from the source object to the target control. There are however two options: OneWay and OneTime. OneWay allows updating the UI when the source changes (only works if the source implements INotifyPropertyChanged however). OneTime can be used if you don’t need the synchronization. <br /> A third mode, TwoWay, allows data to flow in 2 directions: source to target and target to source. This way, we can use data binding also to capture user-entered values. <ul> <li><a href="http://msdn.microsoft.com/en-us/library/cc278072(v=vs.95).aspx#direction_of_the_data_flow">http://msdn.microsoft.com/en-us/library/cc278072(v=vs.95).aspx#direction_of_the_data_flow</a> </li> <li><a href="http://tonesdotnetblog.wordpress.com/2010/03/06/what-are-the-binding-modes-in-silverlight/">http://tonesdotnetblog.wordpress.com/2010/03/06/what-are-the-binding-modes-in-silverlight/</a> </li> <li><a href="http://johnpapa.net/all/sivlerlight-2-binding-modes-diagram/">http://johnpapa.net/all/sivlerlight-2-binding-modes-diagram/</a> </li> </ul> </li> <li>Setting a fallback value <br /> If the data binding expression fails, your application won’t explode! On the contrary, you probably won’t even get any feedback in the UI about it failing. One mechanism to make things easier here is using a fallback value. This value is displayed when the binding fails for any reason. <ul> <li><a href="http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.fallbackvalue(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.fallbackvalue(v=vs.95).aspx</a> </li> <li><a href="http://www.snowball.be/Silverlight+Advent+Calendar+December+4th+Replacing+Converters+With+New+Data+Binding+Features.aspx">http://www.snowball.be/Silverlight+Advent+Calendar+December+4th+Replacing+Converters+With+New+Data+Binding+Features.aspx</a> </li> </ul> </li> </ul> <h5>Format data</h5> <p>By default, a data binding sets the value of a property from an object as the value for control property, such as a DateTime value for a TextBlock. We however have options to hook into this process. One solution is using a Converter (see further), an easier solution is using a formatting expression on the binding.</p> <ul> <li>Formatting string values in data binding <br /> By using the StringFormat property of a data binding expression, we can specify how the value for a binding should be formatted. Several formatting strings exist, including currency and date formatting. <ul> <li><a href="http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.stringformat(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.stringformat(v=vs.95).aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/StringFormat-and-CurrentCulture-in-Silverlight.aspx">http://www.silverlightshow.net/news/StringFormat-and-CurrentCulture-in-Silverlight.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/Silverlight-4-Binding-and-StringFormat-in-XAML.aspx">http://www.silverlightshow.net/news/Silverlight-4-Binding-and-StringFormat-in-XAML.aspx</a> </li> </ul> </li> <li>Formatting culture-specific string values <ul> <li><a href="http://timheuer.com/blog/archive/2010/08/11/stringformat-and-currentculture-in-silverlight.aspx">http://timheuer.com/blog/archive/2010/08/11/stringformat-and-currentculture-in-silverlight.aspx</a> </li> </ul> </li> </ul> <h5>Value Converters</h5> <p>Converters are a great way to do anything with a value before it’s used in the data binding itself. Instead of just using the value in its original format, we can apply a conversion on it. It’s a hook in the data binding process, but it goes further than the StringFormat can go. The latter can just apply conversions on a string, while a converter can apply any transformation. </p> <p>A converter is nothing more than a class that implements the IValueConverter interface. This interface defines two methods: Convert and ConvertBack. When using a converter on a data binding, the Convert method is automatically invoked when the data flows from the source to the target. Similarly, the ConvertBack is called when data is sent from the target to the source (so when the user can enter data). In the Convert, we can for example add a currency sign to an amount to have it properly displayed. In the ConvertBack, we can remove that currency sign again to be able to save the amount back to a property on the source.</p> <p>An important feature is that there can be a difference in types between the “input” and “output” of a converter. For example, we can bind an amount (of type int) to a Background property if we apply a converter that checks if the value is greater than zero and returns a green Brush if true and a red one if false.</p> <p>Learn more about converters using the following links:</p> <ul> <li>Creating a value converter / Referencing a value converter <ul> <li>IValueConverter interface on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter(v=vs.95).aspx</a> </li> <li><a href="http://visualstudiomagazine.com/articles/2010/05/01/ask-kathleen-2-value-converters-in-silverlight.aspx">http://visualstudiomagazine.com/articles/2010/05/01/ask-kathleen-2-value-converters-in-silverlight.aspx</a> </li> <li><a href="http://www.silverlightshow.net/tips/How-to-format-a-binding-value-using-convertors.aspx">http://www.silverlightshow.net/tips/How-to-format-a-binding-value-using-convertors.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/Displaying-Images-in-Silverlight-4-DataGrid-using-Converter-.aspx">http://www.silverlightshow.net/news/Displaying-Images-in-Silverlight-4-DataGrid-using-Converter-.aspx</a> </li> <li><a href="http://weblogs.asp.net/dwahlin/archive/2009/08/15/so-what-s-a-silverlight-value-converter-anyway.aspx">http://weblogs.asp.net/dwahlin/archive/2009/08/15/so-what-s-a-silverlight-value-converter-anyway.aspx</a> </li> </ul> </li> <li>Passing parameters <ul> <li>ConverterParameter on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.binding.converterparameter(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.data.binding.converterparameter(v=vs.95).aspx</a> </li> <li><a href="http://blogs.msdn.com/b/synergist/archive/2008/07/30/using-a-converterparameter-in-a-silverlight-2-value-converter.aspx">http://blogs.msdn.com/b/synergist/archive/2008/07/30/using-a-converterparameter-in-a-silverlight-2-value-converter.aspx</a> </li> <li><a href="http://www.silverlightshow.net/tips/Tip-How-to-pass-a-parameter-to-a-value-converter.aspx">http://www.silverlightshow.net/tips/Tip-How-to-pass-a-parameter-to-a-value-converter.aspx</a> </li> <li><a href="http://blog.andrew-veresov.com/post/Binding-a-Converter-Parameter.aspx">http://blog.andrew-veresov.com/post/Binding-a-Converter-Parameter.aspx</a> </li> </ul> </li> </ul> <h5>Implement data validation</h5> <p>When using TwoWay bindings, we are basically opening up the application for users to enter data. Of course, not all users “behave” like we’d like them to: users will make errors when entering data that could cause problems in our data model. Values that are larger than a specific maximum, a string where an integer is expected… they are all common things we get to deal with in our applications. </p> <p>To counter this, we obviously have to fall back on the concept of validation. Before the entered data goes back to the source object, we can have Silverlight run validation code that checks if the value is according to one or more validation rules.</p> <p>In Silverlight 2, the available options for data binding weren’t that rich. With every release, some new options have been added. The most important one however was added with the release of version 4, where 2 new interfaces were added: IDataErrorInfo and INotifyDataErrorInfo. The first one you may know for regular .NET, the second one enables asynchronous validation in Silverlight. This is something we’ll often need: not all validation can be done purely on the client but has to call back to the server-side. A good example is checking the uniqueness of a chosen username: this is typically a check that has to be ran on the database (therefore on the server-side). Since this needs to be done using a service call that runs asynchronously, the INotifyDataErrorInfo comes in handy when we have to wait for a validation result coming back from a service call.</p> <p>To learn more about data validation, take a look at the following links:</p> <ul> <li>Implementing the IDataErrorInfo interface <ul> <li>IDataErrorInfo on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.idataerrorinfo(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.componentmodel.idataerrorinfo(v=vs.95).aspx</a> </li> <li><a href="http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-2.aspx">http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-2.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/Validating-Data-in-Silverlight-4-Applications-IDataErrorInfo-.aspx">http://www.silverlightshow.net/news/Validating-Data-in-Silverlight-4-Applications-IDataErrorInfo-.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/Enabling-Validation-in-Silverlight-4-with-IDataErrorInfo-.aspx">http://www.silverlightshow.net/news/Enabling-Validation-in-Silverlight-4-with-IDataErrorInfo-.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/IDataErrorInfo-in-an-Example-to-Stop-Last-Christmas-by-Wham.aspx">http://www.silverlightshow.net/news/IDataErrorInfo-in-an-Example-to-Stop-Last-Christmas-by-Wham.aspx</a> </li> <li><a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/11/18/silverlight-4-rough-notes-binding-and-idataerrorinfo.aspx">http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/11/18/silverlight-4-rough-notes-binding-and-idataerrorinfo.aspx</a> </li> </ul> </li> <li>Implementing the INotifyDataErrorInfo interface <ul> <li>INotifyDataErrorInfo on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifydataerrorinfo(v=vs.95).aspx</a> </li> <li><a href="http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-2.aspx">http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-2.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/INotifyDataErrorInfo-in-the-Spotlight.aspx">http://www.silverlightshow.net/news/INotifyDataErrorInfo-in-the-Spotlight.aspx</a> </li> <li><a href="http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-III.aspx">http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-III.aspx</a> </li> <li><a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/11/18/silverlight-4-rough-notes-binding-with-inotifydataerrorinfo.aspx">http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/11/18/silverlight-4-rough-notes-binding-with-inotifydataerrorinfo.aspx</a> </li> <li><a href="http://weblogs.asp.net/fredriknormen/archive/2009/11/22/silverlight-4-and-asynchronous-validation-with-inotifydataerrorinfo.aspx">http://weblogs.asp.net/fredriknormen/archive/2009/11/22/silverlight-4-and-asynchronous-validation-with-inotifydataerrorinfo.aspx</a> </li> </ul> </li> <li>Implementing data binding errors <br /> In this SilverlightShow article, I explain the several properties of validation: <a href="http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-1.aspx">http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-1.aspx</a> <ul> <li>NotifyOnValidationError <br /> NotifyOnValidationError enables us to pass errors in the hierarchy <ul> <li>NotifyOnValidationError on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.binding.notifyonvalidationerror(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.data.binding.notifyonvalidationerror(v=vs.95).aspx</a> </li> <li><a href="http://www.devproconnections.com/article/silverlight-development/Silverlight-Data-Validation.aspx">http://www.devproconnections.com/article/silverlight-development/Silverlight-Data-Validation.aspx</a> </li> <li><a href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/03/18/a-quick-look-at-silverlight-3-data-validation.aspx">http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/03/18/a-quick-look-at-silverlight-3-data-validation.aspx</a> </li> </ul> </li> <li>ValidatesOnExceptions <br /> If our setters throw an exception within the setter, we can catch this if we set the ValidatesOnExceptions to true. <ul> <li>ValidatesOnExceptions on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validatesonexceptions.aspx">http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validatesonexceptions.aspx</a> </li> <li><a href="http://www.arrangeactassert.com/validation-in-silverlight-and-wpf-using-validatesonexceptions/">http://www.arrangeactassert.com/validation-in-silverlight-and-wpf-using-validatesonexceptions/</a> </li> </ul> </li> <li>ValidatesOnDataErrors <br /> If we want to use IDataErrorInfo as our validation mechanism, we have to set ValidatesOnDataErrors to true. <ul> <li>ValidatesOnDataErrors on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validatesondataerrors(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validatesondataerrors(v=vs.95).aspx</a> </li> </ul> </li> <li>ValidatesOnNotifyDataErrors <br /> If we want to use INotifyDataErrorInfo as our validation mechanism, we have to set ValidatesOnNotifyDataErrors to true. <ul> <li>ValidatesOnNotifyDataErrors on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validatesonnotifydataerrors(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.data.binding.validatesonnotifydataerrors(v=vs.95).aspx</a> </li> </ul> </li> </ul> </li> </ul> <h4>Summary</h4> <p>In this part, we focused on the very important aspect of working with data and learning the data binding mechanism. We also looked at ways to alter the data binding process using converters and we also saw the many ways we can do validation in Silverlight 4, depending on the needs of our application.</p> <p>In the next art, we’ll be looking at how we can work together with the host platform, including COM, out-of-browser applications and working with the DOM of the surrounding page.</p> <h4>About Gill</h4> <p>Gill Cleeren is Microsoft Regional Director (<a href="http://www.theregion.com/">www.theregion.com</a>), Silverlight MVP (former ASP.NET MVP), INETA speaker bureau member and Silverlight Insider. He lives in Belgium where he works as .NET architect at Ordina. Passionate about .NET, he’s always playing with the newest bits. In his role as Regional Director, Gill has given many sessions, webcasts and trainings on new as well as existing technologies, such as Silverlight, ASP.NET and WPF at conferences including TechEd Berlin 2010, TechDays Belgium, DevDays NL, NDC Oslo Norway, SQL Server Saturday Switserland, Spring Conference UK, Silverlight Roadshow in Sweden… He’s also the author of many articles in various developer magazines and for SilverlightShow.net. He organizes the yearly Community Day event in Belgium.</p> <p>He also leads Visug (<a href="http://www.visug.be/">www.visug.be</a>), the largest .NET user group in Belgium. Gill recently published his first book: “<a href="https://www.packtpub.com/microsoft-silverlight-4-data-and-services-cookbook/book">Silverlight 4 Data and Services Cookbook</a>” (Packt Publishing). You can find his blog at <a href="http://www.snowball.be/">www.snowball.be</a>. </p> <p>Twitter: @gillcleeren</p> http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-4.aspx editorial@silverlightshow.net (Gill Cleeren ) http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-4.aspx#comments http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-4.aspx Mon, 07 Feb 2011 00:57:00 GMT Getting ready for Microsoft Silverlight Exam 70-506 (Part 3) <div style="border: 1px solid #dddddd; padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px;"><strong>SilverlightShow</strong> and <strong>Gill Cleeren</strong> start a <strong>series of materials</strong> aimed at helping you get prepared for taking <a href="http://www.microsoft.com/learning/en/us/Exam.aspx?ID=70-506&Locale=en-us" target="_blank">Microsoft Silverlight Exam 70-506</a>. Through this series we will try to structure the resources available on the internet, grouping them by topic covered in the exam. <strong>Any feedback would be much appreciated</strong>! Thanks!  </div> <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: 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/Search.aspx?q=+RichTextBox&adv=false">WCF RIA Services series</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 3 of the series on Microsoft Silverlight Exam.</p> <p>In the previous parts of this series on getting yourself ready for the Silverlight exam, we mainly looked at UI related items. In the very first part, we looked at how Silverlight could help with layout, navigation, media and the core controls. In part 2, we focused on the many features Silverlight has on board to create better user interfaces, such as the Visual State Manager, styling, templating and animations.</p> <p>This third part is going to be more aimed at the code-side of things. We’ll start our journey by looking at specifics of Silverlight such as routed events (these also exist in WPF by the way and asynchronous communication with services. We’ll look at dependency and attached properties as well, these are very important to a deeper understanding of Silverlight. We’ll look at the ICommand interface as well, which forms the base of commanding support for the MVVM-pattern in Silverlight. As you can see, we’ll be spending more time looking at C# code this time!</p> <p>For your convenience, the following list contains links to the other parts of the article series which have been finished already:</p> <ul> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-the-exams-Part-1.aspx">Laying Out a User Interface (15%)</a> </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-2.aspx">Enhancing the User Interface (14%)</a> </li> <li><strong>Implementing Application Logic (16%) -> this part</strong> </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-4.aspx">Working with Data (17%)</a>  </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-5.aspx">Interacting with a Host Platform (11%)</a>  </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-6.aspx">Structuring Applications (13%)</a>  </li> <li><a href="http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-7.aspx">Deploying Applications (13%)</a>  </li> </ul> <h4>Part 3: Implementing Application Logic</h4> <p>Do you remember the name WPF/E (the E stands for Everywhere)? It was the name Silverlight was known by before it got its final name. The reason I bring this up here is that it shows that Silverlight has inherited from WPF (Windows Presentation Foundation). The original name gives this away. Much of the core development platform we have today in Silverlight found its origin in Silverlight. Things like dependency properties and attached properties were introduced in WPF and later were ported into Silverlight. Some of these implementations are identical in the 2 technologies, others are somewhat trimmed down in Silverlight. Still, the development model available in Silverlight is solid and ready to build all types of applications on. Let’s dive into writing some code for Silverlight applications!</p> <h5>Handle events</h5> <p>Working with events in Silverlight is not very different from any other technology (note that we’re not looking at MVVM/commanding here yet). When we have some control in the designer, we can select it and select an event in the event window. Visual Studio will generate the event handler for us then as well as generate the event on the control in XAML. Not very different from ASP.NET or WinForms indeed! We can also choose to attach the event handler in code-behind using a delegate or even a lambda expression. </p> <p>Silverlight has the notion of routed events. An event raised on a control nested within another control will bubble into the parent control so this parent can handle the event. This model is easy because Silverlight promotes nesting. This way, a TextBlock and an Image inside of a container (such as a Grid), all nested within a Button, will raise the click event to the Button, instead of us having to wire the event for the Button and its children manually.</p> <p>To learn more about event handling, take a look at the following links:</p> <ul> <li>Handling routed events / Bubbling events: <br /> <em>Bubbling of an event is a type of a routed event. At the time of writing, there’s only support for bubbling events in Silverlight. WPF also supports tunneling. Bubbling can be seen as a way to send an event higher in the hierarchy. Hence the name bubbling: it will bubble up in the XAML tree. Tunneling, which is only available for WPF, does the opposite, drilling down so to say in the XAML tree. </em> <ul> <li>Routed events in Silverlight 3: <a href="http://msdn.microsoft.com/en-us/library/cc189018(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/cc189018(v=vs.95).aspx</a> (contains information on AddHandler as well) </li> <li><a href="http://www.silverlightshow.net/items/Routed-Events-in-Silverlight.aspx">http://www.silverlightshow.net/items/Routed-Events-in-Silverlight.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/Training-Session-on-Silverlight-Routed-Events.aspx">http://www.silverlightshow.net/news/Training-Session-on-Silverlight-Routed-Events.aspx</a> </li> <li>Interesting thread on the Silverlight forums: <a href="http://forums.silverlight.net/forums/p/153909/343601.aspx">http://forums.silverlight.net/forums/p/153909/343601.aspx</a> </li> <li><a href="http://www.silverlightshow.net/items/More-on-Routing-and-Bubbling.aspx">http://www.silverlightshow.net/items/More-on-Routing-and-Bubbling.aspx</a> </li> <li><a href="http://www.kirupa.com/net/event_bubbling_tunneling.htm">http://www.kirupa.com/net/event_bubbling_tunneling.htm</a> </li> <li><a href="http://rongchaua.net/blog/silverlight-routed-event/">http://rongchaua.net/blog/silverlight-routed-event/</a> </li> </ul> </li> <li>Implementing AddHandler: <br /> Using the AddHandler, we can add an event handler for a routed event to the handler collection of an element. <ul> <li><a href="http://msdn.microsoft.com/en-us/library/ms598899(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/ms598899(v=vs.95).aspx</a> </li> </ul> </li> </ul> <h5>Consume services asynchronously</h5> <p>Services are a vital building block for Silverlight applications. As business applications become more and more the focus of where Silverlight is going, data is needed in any app. Since out-of-the-box, Silverlight has no support for client-side database (I specifically said out-of-the-box, since there are some custom implementations such as Sterling database but these are not the focus for the exam), it has to access services for its data needs. Client-side databases would not be the solution for all problems either: if we build a shopping website in Silverlight, no developer would get it in his mind to transfer the entire product database to the client (let’s hope so at least!).</p> <p>Luckily, Silverlight is well-equipped for working with all kinds of services. ASMX, WCF, REST, POX and RSS pose no problem for Silverlight. We can easily say that today, the default for building new services should be WCF or REST. However, if you have an existing implementation (legacy) in ASMX (plain web services), there’s no problem to consume these from a Silverlight environment. </p> <p>When working with WCF or ASMX services, Visual Studio helps us out by generating a proxy class when adding a reference to the service. This proxy will make the actual calls to our service. This is not different from adding service references in other .NET technologies.</p> <p>One big difference however is the fact that all communication happens asynchronously in Silverlight. No service can be communicated with in a synchronous manner. This would, while the Silverlight application waits for a response, lock the UI thread and therefore also the browser. Even in WCF RIA Services, where the async behavior is somewhat abstracted away, the communication still happens asynchronously.</p> <p>(Shameless plug: in my book <a href="https://www.packtpub.com/microsoft-silverlight-4-data-and-services-cookbook/book">Silverlight 4 Data and Services Cookbook</a> (Gill Cleeren – Kevin Dockx, Packt Publishing 2010), we have a very deep coverage of all things happening around accessing services).</p> <p>Let’s look at some important information regarding working with services from Silverlight.</p> <ul> <li>Creating and adding service references / Handling asynchronous completed events <ul> <li>Services and Silverlight on MSDN: <a href="http://msdn.microsoft.com/en-us/library/cc197940(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/cc197940(v=vs.95).aspx</a> </li> <li><a href="http://www.silverlightshow.net/items/Silverlight-Data-and-Services-The-complete-story.aspx">http://www.silverlightshow.net/items/Silverlight-Data-and-Services-The-complete-story.aspx</a> </li> <li><a href="http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2">http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2</a> </li> <li><a href="http://www.silverlightshow.net/items/End-to-End-Data-Centric-Application-with-Silverlight-2.aspx">http://www.silverlightshow.net/items/End-to-End-Data-Centric-Application-with-Silverlight-2.aspx</a> </li> <li><a href="http://www.silverlightshow.net/items/Consuming-ASMX-Web-Services-with-Silverlight-2.aspx">http://www.silverlightshow.net/items/Consuming-ASMX-Web-Services-with-Silverlight-2.aspx</a> </li> <li><a href="http://www.silverlight.net/learn/quickstarts/webservices/">http://www.silverlight.net/learn/quickstarts/webservices/</a> </li> <li>Web service samples: <a href="http://code.msdn.microsoft.com/silverlightws">http://code.msdn.microsoft.com/silverlightws</a> </li> <li><a href="http://technet.microsoft.com/en-us/magazine/ff955754.aspx">http://technet.microsoft.com/en-us/magazine/ff955754.aspx</a> </li> <li><a href="http://www.dotnetfunda.com/articles/article279.aspx">http://www.dotnetfunda.com/articles/article279.aspx</a> </li> </ul> </li> <li>Configuring service endpoints <ul> <li><a href="http://wildermuth.com/2008/11/08/Controlling_Service_References_in_Silverlight_2">http://wildermuth.com/2008/11/08/Controlling_Service_References_in_Silverlight_2</a> </li> <li><a href="http://timheuer.com/blog/archive/2010/04/05/managing-service-references-in-silverlight-applications-for-different-environments.aspx">http://timheuer.com/blog/archive/2010/04/05/managing-service-references-in-silverlight-applications-for-different-environments.aspx</a> </li> </ul> </li> <li>Handling service exceptions <ul> <li><a href="http://msdn.microsoft.com/en-us/library/ee844556(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/ee844556(v=vs.95).aspx</a> </li> <li><a href="http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2#WCFSilverlightHandlingFaults">http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2#WCFSilverlightHandlingFaults</a> </li> </ul> </li> <li>Handling timeouts <ul> <li><a href="http://www.silverlightshow.net/items/Uploading-and-downloading-images-from-WCF-in-Silverlight.aspx">http://www.silverlightshow.net/items/Uploading-and-downloading-images-from-WCF-in-Silverlight.aspx</a> </li> <li><a href="http://stackoverflow.com/questions/689472/how-do-i-extend-the-timeout-for-a-web-service-in-silverlight-2-0">http://stackoverflow.com/questions/689472/how-do-i-extend-the-timeout-for-a-web-service-in-silverlight-2-0</a> </li> <li><a href="http://www.codeproject.com/KB/silverlight/DownloadingInChunks.aspx">http://www.codeproject.com/KB/silverlight/DownloadingInChunks.aspx</a> </li> </ul> </li> </ul> <h5><strong>Work with background threads</strong></h5> <p>Threading is the ability to push some long running task to a separate thread. By default, all the work is done on the single UI thread in Silverlight. If we launch for example a calculation that takes several seconds to complete in the main thread, the UI will be blocked and won’t be accepting any input until it has finished the calculation. By creating a separate thread to execute the work on, the UI thread won’t be blocked and the user can keep working with the application in the meantime. This is similar to what happens when connecting with a service: there’s also a time-consuming task that would block the UI if invoked synchronously.</p> <p>Silverlight has a threading stack on-board. While it doesn’t contain all threading options available in the full .NET framework, there’s more than enough for scenarios where Silverlight is to be used. Silverlight also contains the BackgroundWorker class which makes working with threads easier.</p> <p>One important thing concerning threading is that all code that executes on a separate thread has no access to the UI elements. It’s therefore not possible to write code in a callback that does something with a UI element (such as setting the Text of a TextBlock). There’s a workaround though in the form of the Dispatcher.BeginInvoke(), to which we can pass code that will be executed on the UI thread. </p> <p>To learn more about threading, take a look at the following links and articles:</p> <ul> <li>Spawning a background thread to execute code <ul> <li>Thread class on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.threading(v=VS.95).aspx">http://msdn.microsoft.com/en-us/library/system.threading(v=VS.95).aspx</a> </li> <li>BackgroundWorker on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=VS.95).aspx">http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=VS.95).aspx</a> and <a href="http://msdn.microsoft.com/en-us/library/cc221403(VS.95).aspx">http://msdn.microsoft.com/en-us/library/cc221403(VS.95).aspx</a> </li> <li><a href="http://10rem.net/blog/2010/04/23/essential-silverlight-and-wpf-skills-the-ui-thread-dispatchers-background-workers-and-async-network-programming">http://10rem.net/blog/2010/04/23/essential-silverlight-and-wpf-skills-the-ui-thread-dispatchers-background-workers-and-async-network-programming</a> (also contains overview of the BackgroundWorker class) </li> <li><a href="http://www.silverlight.net/learn/videos/silverlight-videos/using-multiple-threads-with-the-backgroundworker/">http://www.silverlight.net/learn/videos/silverlight-videos/using-multiple-threads-with-the-backgroundworker/</a> (video) </li> </ul> </li> <li>Returning data to the UI thread by using the dispatcher object <br /> <em>The Dispatcher allows to pass code to execute on the UI Thread. Without this, we wouldn’t be able to change anything on the UI elements from a background thread. </em> <ul> <li><a href="http://www.silverlightshow.net/items/Tip-Asynchronous-Silverlight-Execute-on-the-UI-thread.aspx">http://www.silverlightshow.net/items/Tip-Asynchronous-Silverlight-Execute-on-the-UI-thread.aspx</a> </li> <li><a href="http://wildermuth.com/2008/05/06/Executing_Code_on_the_UI_Thread_in_Silverlight_2">http://wildermuth.com/2008/05/06/Executing_Code_on_the_UI_Thread_in_Silverlight_2</a> </li> <li><a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher(v=vs.95).aspx</a> </li> </ul> </li> <li>Implementing the DispatcherTimer <br /> <em>The DispatcherTimer is a Timer which is integrated in the Dispatcher queue. It should be your default when using any timer in a Silverlight application.</em> <ul> <li>DispatcherTimer class on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer(v=vs.95).aspx</a> </li> <li><a href="http://blogs.silverlight.net/blogs/msnow/archive/2009/11/09/69731.aspx">http://blogs.silverlight.net/blogs/msnow/archive/2009/11/09/69731.aspx</a> </li> </ul> </li> </ul> <h5>Working with Dependency Properties</h5> <p>When I teach a Silverlight class, one of the hardest things to explain I think are dependency properties. Not because they’re that hard, certainly not. The thing is that dependency properties make something you know (the regular property system) to a new level. However, they do relieve us from writing a lot of code ourselves.</p> <p>Dependency properties are the enabler for data binding, styling and animations. Without them, we would have to write a lot more code to get these things working. Most properties on UI objects in Silverlight (the FontSize property on a TextBlock, the Width property of a Rectangle…) are dependency properties, so in most cases, you’ve used them without even knowing it! When you start writing your own controls, you’ll need to start creating them as well, if you want your control to be able to take part in data binding, styling… It’s certainly recommended to do so, since other users of your custom-built controls will expect your controls to behave just like the default controls of Silverlight. </p> <p>Let’s take a look at working with dependency controls:</p> <ul> <li>Creating dependency properties / Specifying dependency property metadata / Getting and setting dependency property values <br /> <em>Creating dependency properties is more complicated than writing regular properties. You have to declare the DP by registering it with the dependency property system (on the DependencyObject). Optionally, you have to write code in a PropertyChangedCallback that will trigger when the value changes. Finally, you have to write a public wrapper for your DP. You won’t be accessing the value of the DP directly: you’ll always use this wrapper which internally uses the GetValue/SetValue defined on the DependencyObject class. These methods will retrieve the exact value of the DP at the given time, taking into account all the current influences taking place on the value and their priorities.</em> <ul> <li>DependencyObject class on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject(VS.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject(VS.95).aspx</a> </li> <li>DependencyProperty class on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty(VS.95).aspx">http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty(VS.95).aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/Dependency-Property-Value-Resolution.aspx">http://www.silverlightshow.net/news/Dependency-Property-Value-Resolution.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/Demystifying-Silverlight-Dependency-Properties-.aspx">http://www.silverlightshow.net/news/Demystifying-Silverlight-Dependency-Properties-.aspx</a> </li> <li><a href="http://geekswithblogs.net/Silverlight2/archive/2008/12/24/understanding-dependency-properties-in-silverlight.aspx">http://geekswithblogs.net/Silverlight2/archive/2008/12/24/understanding-dependency-properties-in-silverlight.aspx</a> </li> <li><a href="http://www.silverlightshow.net/tips/Tip-How-to-declare-a-dependancy-property-in-Silverlight.aspx">http://www.silverlightshow.net/tips/Tip-How-to-declare-a-dependancy-property-in-Silverlight.aspx</a> </li> <li><a href="http://www.kirupa.com/blend_silverlight/dependency_properties_pg1.htm">http://www.kirupa.com/blend_silverlight/dependency_properties_pg1.htm</a> </li> <li><a href="http://jesseliberty.com/2007/09/19/dependency-properties-or-attached-properties/">http://jesseliberty.com/2007/09/19/dependency-properties-or-attached-properties/</a> </li> <li><a href="http://www.kirupa.com/blend_silverlight/dependency_properties_pg2.htm">http://www.kirupa.com/blend_silverlight/dependency_properties_pg2.htm</a> </li> </ul> </li> <li>The topic of dependency properties in Silverlight is inherited from WPF. There’s a lot of interesting material on DPs in WPF as well from the following links: <ul> <li><a href="http://msdn.microsoft.com/en-us/library/ms752914.aspx">http://msdn.microsoft.com/en-us/library/ms752914.aspx</a> </li> <li><a href="http://joshsmithonwpf.wordpress.com/2007/05/16/demystifying-dependency-properties/">http://joshsmithonwpf.wordpress.com/2007/05/16/demystifying-dependency-properties/</a> </li> <li><a href="http://www.wpftutorial.net/DependencyProperties.html">http://www.wpftutorial.net/DependencyProperties.html</a> </li> <li><a href="http://www.switchonthecode.com/tutorials/wpf-tutorial-introduction-to-dependency-properties">http://www.switchonthecode.com/tutorials/wpf-tutorial-introduction-to-dependency-properties</a> </li> <li><a href="http://www.codeguru.com/csharp/.net/net_general/netframeworkclasses/article.php/c13449">http://www.codeguru.com/csharp/.net/net_general/netframeworkclasses/article.php/c13449</a> </li> </ul> </li> </ul> <h5>Interacting with attached properties</h5> <p>Attached properties are properties defined on one control but used on a different control. Confused? Let me explain it with a simple example. Take the Row property on a Grid control. When we want to place a TextBlock in row #3 inside a Grid, we specify the Grid.Row property to have the value 3. However, the TextBlock does not have a “Grid.Row” property defined. Instead, the Grid has the Row property defined as an attached property. The attached property is defined as a global property, so that other control can use it. Most attached properties are defined on containers (Grid, Canvas…). This is because there needs to be some “communication” between the child control and the parent control. However, this is not required: your own control can too define attached properties if needed. </p> <p>To learn more about attached properties, take a look at the following articles:</p> <ul> <li>Setting attached properties in XAML <ul> <li><a href="http://www.silverlightshow.net/items/Attached-Properties-in-Silverlight.aspx">http://www.silverlightshow.net/items/Attached-Properties-in-Silverlight.aspx</a> </li> <li><a href="http://msdn.microsoft.com/en-us/library/cc265152(v=vs.95).aspx">http://msdn.microsoft.com/en-us/library/cc265152(v=vs.95).aspx</a> </li> </ul> </li> <li>Getting and setting attached properties programmatically <ul> <li><a href="http://msdn.microsoft.com/en-us/library/cc265152(v=vs.95).aspx#attached_properties_code">http://msdn.microsoft.com/en-us/library/cc265152(v=vs.95).aspx#attached_properties_code</a> </li> <li><a href="http://dotnet.dzone.com/news/custom-attached-properties">http://dotnet.dzone.com/news/custom-attached-properties</a> </li> <li><a href="http://www.silverlightshow.net/tips/Tip-How-to-declare-an-attached-property-in-Silverlight.aspx">http://www.silverlightshow.net/tips/Tip-How-to-declare-an-attached-property-in-Silverlight.aspx</a> </li> </ul> </li> </ul> <h5>Implementing ICommand</h5> <p>The MVVM pattern is something you’ve surely heard about already. The ViewModel (aka View-Model-ViewModel) pattern promotes separation of concerns. The ViewModel is an abstraction of the View: the View mostly XAML-only and it’s the place where the designer is focusing on. The ViewModel contains state and operations for the View. State can be seen as properties, operations are commands. The View falls back on the concepts of data binding and the DataContext to bind to an instance of the ViewModel.</p> <p>When executing an action in the UI, for example clicking a Button, we think of adding an event handler and writing some event handling code in the code-behind. MVVM promotes commanding, which comes down to writing a public command in the ViewModel and binding to this instance in the View. When the command fires, the related code in the ViewModel gets executed. Therefore, we don’t write an event handler, instead we create a command instance and the ViewModel and bind to it. </p> <p>Commanding is possible in Silverlight 4 because of the introduction of the ICommand interface. When creating a command implementation, we have implement the ICommand interface. Once we have our implementation, we can instantiate it, expose it as a public property on the ViewModel and bind to it in the View. In Silverlight 4, commanding is only supported on the ButtonBase class though. (Note: in many cases, we don’t implement the ICommand ourselves but we’ll use an existing implementation such as RelayCommand of MVVM Light or DelegateCommand from Prism). </p> <p>The following articles can helpful when exploring the ICommand interface:</p> <ul> <li>General implementation of ICommand: <ul> <li>ICommand interface on MSDN: <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand(v=vs.95).aspx" target="_blank">http://msdn.microsoft.com/en-us/library/system.windows.input.icommand(v=vs.95).aspx</a> </li> <li><a href="http://www.johnpapa.net/5-Simple-Steps-to-Commanding-in-Silverlight" target="_blank">http://www.johnpapa.net/5-Simple-Steps-to-Commanding-in-Silverlight</a></li> <li><a href="http://wildermuth.com/2010/01/21/New_SL4_Feature_Commanding" target="_blank">http://wildermuth.com/2010/01/21/New_SL4_Feature_Commanding</a> </li> <li><a href="http://www.silverlightshow.net/items/Silverlight-4-How-to-Command-Control.aspx">http://www.silverlightshow.net/items/Silverlight-4-How-to-Command-Control.aspx</a> </li> <li><a href="http://www.silverlightshow.net/news/Using-RelayCommands-in-Silverlight-and-WPF.aspx">http://www.silverlightshow.net/news/Using-RelayCommands-in-Silverlight-and-WPF.aspx</a> </li> <li><a href="http://www.snowball.be/2010/12/31/Working+With+The+RaiseCanExecuteChanged+In+MVVM+Light+Silverlight.aspx" target="_blank">http://www.snowball.be/2010/12/31/Working+With+The+RaiseCanExecuteChanged+In+MVVM+Light+Silverlight.aspx</a> </li> </ul> </li> <li>Implementing an ICommand <ul> <li><a href="http://www.orktane.com/Blog/post/2009/03/09/I-Command-Silverlight.aspx" target="_blank">http://www.orktane.com/Blog/post/2009/03/09/I-Command-Silverlight.aspx</a> </li> </ul> </li> <li>Binding to an ICommand: <ul> <li><a href="http://www.dotnetfunda.com/articles/article859-command-binding-in-silverlight-4-stepbystep-.aspx" target="_blank">http://www.dotnetfunda.com/articles/article859-command-binding-in-silverlight-4-stepbystep-.aspx</a> </li> </ul> </li> <li>Passing a parameter <ul> <li><a href="http://www.silverlightshow.net/news/ICommand-in-Silverlight-4-.aspx">http://www.silverlightshow.net/news/ICommand-in-Silverlight-4-.aspx</a> </li> <li><a href="http://geekswithblogs.net/HouseOfBilz/archive/2009/05/22/adventures-in-mvvm-ndash-commands-in-silverlight.aspx" target="_blank">http://geekswithblogs.net/HouseOfBilz/archive/2009/05/22/adventures-in-mvvm-ndash-commands-in-silverlight.aspx</a> </li> </ul> </li> </ul> <h4>Summary</h4> <p>In this part, we prepared ourselves for the code-side of Silverlight. Not everything is XAML so there are some really important things to understand that you need to know in this area. Aspects such as Dependency Properties, Attached Properties and the ICommand interface are tools you’ll surely want in your Silverlight toolbox!</p> <p>In part 4, data will be our focus, when we look at things like data binding and validation.</p> <h4>About Gill</h4> <p>Gill Cleeren is Microsoft Regional Director (<a href="http://www.theregion.com/">www.theregion.com</a>), Silverlight MVP (former ASP.NET MVP), INETA speaker bureau member and Silverlight Insider. He lives in Belgium where he works as .NET architect at Ordina. Passionate about .NET, he’s always playing with the newest bits. In his role as Regional Director, Gill has given many sessions, webcasts and trainings on new as well as existing technologies, such as Silverlight, ASP.NET and WPF at conferences including TechEd Berlin 2010, TechDays Belgium, DevDays NL, NDC Oslo Norway, SQL Server Saturday Switserland, Spring Conference UK, Silverlight Roadshow in Sweden… He’s also the author of many articles in various developer magazines and for SilverlightShow.net. He organizes the yearly Community Day event in Belgium.</p> <p>He also leads Visug (<a href="http://www.visug.be/">www.visug.be</a>), the largest .NET user group in Belgium. Gill recently published his first book: “<a href="https://www.packtpub.com/microsoft-silverlight-4-data-and-services-cookbook/book">Silverlight 4 Data and Services Cookbook</a>” (Packt Publishing). You can find his blog at <a href="http://www.snowball.be/">www.snowball.be</a>. </p> <p>Twitter: @gillcleeren</p> <div></div> http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-3.aspx editorial@silverlightshow.net (Gill Cleeren ) http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-3.aspx#comments http://www.silverlightshow.net/items/Getting-ready-for-Microsoft-Silverlight-Exam-70-506-Part-3.aspx Tue, 01 Feb 2011 03:39:00 GMT A classic memory game: Part 2 - The game logic, connecting the ViewModel and the View <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 2 of “A classic memory game”.</p> <p>The series is about building the following classic memory game in Silverlight, and porting it to Windows Phone 7. In the first article we started a new MVVM Light project, created the controls and designed the game-states. Now it’s time to put some code behind the game, and finish it.</p> <p>Here’s the game itself and you can <a href="http://www.silverlightshow.net/Storage/Sources/memoria_2.zip">download the source code here</a>.</p> <p style="text-align: center;"><iframe width="570" height="570" src="http://www.silverlightshow.net/Storage/demos/Memoria/MemoriaPart1.html"></iframe></p> <h3>The Game Logic</h3> <h4>MVVM Light template</h4> <h4></h4> <p>The MVVM Light project template contains a ViewModelLocator and a MainViewModel in the ViewModel folder. The ViewModelLocator’s job is to hold a reference of the ViewModels and to create them when needed. In the App.xaml there’s an instance of the ViewModelLocator, so the Views can bind to the ViewModel via this instance. </p> <p>App.xaml:</p> <div id="codeSnippetWrapper"> <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: 60.53%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; height: 99px; 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 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; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">ResourceDictionary</span><span style="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 style="color: #0000ff;"><</span><span style="color: #800000;">vm:MemoryViewModelLocator</span> <span style="color: #ff0000;">x:Key</span><span style="color: #0000ff;">="Locator"</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 style="color: #ff0000;">d:IsDataSource</span><span style="color: #0000ff;">="True"</span> <span style="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 style="color: #0000ff;"></</span><span style="color: #800000;">ResourceDictionary</span><span style="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 style="color: #0000ff;"></</span><span style="color: #800000;">Application.Resources</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>MainPage.xaml:</p> <div id="codeSnippetWrapper"> <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: 60.68%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; height: 49px; 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 style="color: #0000ff;"><</span><span style="color: #800000;">UserControl.DataContext</span><span style="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: 59.72%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; height: 16px; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;"><</span><span style="color: #800000;">Binding</span> <span style="color: #ff0000;">Path</span><span style="color: #0000ff;">="Main"</span> <span style="color: #ff0000;">Source</span><span style="color: #0000ff;">="{StaticResource Locator}"</span><span style="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: 99.81%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; height: 16px; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"></</span><span style="color: #800000;">UserControl.DataContext</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <h4>Model</h4> <p>To represent the cards, we have a MemoryCard class with the following properties:</p> <ul> <li>the <strong>ID</strong> specifies which image is on the card </li> <li>the <strong>Upside</strong> property indicates if a card is showing it’s face or back </li> <li>the <strong>Solved</strong> property is set true once the card and its pair are found </li> </ul> <p>The MemoryCard class implements the <strong>INotifyPropertyChanged</strong> interface. Classes that implement this interface must have an event delegate PropertyChangedEventHandler. Raising this event enables the View (that’s the MainPage.xaml) to track changes. So we need to raise this event when setting the Upside and the Solved properties. The ID won’t change in a MemoryCard’s lifetime so we don’t need to do anything there.</p> <p>Here’s the Upside property and the raisePropertyChanged method.</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 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 style="color: #008000;">/// The <see cref="Upside" /> property's name.</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 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 style="color: #0000ff;">public</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> UpsidePropertyName = <span style="color: #006080;">"Upside"</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;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">bool</span> _upside = <span style="color: #0000ff;">false</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;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><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 style="color: #008000;">/// Gets the Upside property.</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 style="color: #008000;">/// Changes to that property's value raise the PropertyChanged event. </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 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 style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span> Upside</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> 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;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _upside;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> 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;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_upside == <span style="color: #0000ff;">value</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;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</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;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> _upside = <span style="color: #0000ff;">value</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;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #008000;">// Update bindings, no broadcast</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;"> raisePropertyChanged(UpsidePropertyName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--></div> </div> <div id="codeSnippetWrapper"> <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: 92.1%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; height: 150px; 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 style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> PropertyChangedEventHandler PropertyChanged;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> raisePropertyChanged(<span style="color: #0000ff;">string</span> propertyName)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (PropertyChanged != <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;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.PropertyChanged(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span> PropertyChangedEventArgs(propertyName));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--></div> </div> <div> </div> <h4>The game logic</h4> <p>The logic is simple. In the MainViewModel’s constructor we’re setting up two timers (DispatcherTimers), one to turn back cards after a while and one for tracking the elapsed time. In the Start method we load the selected number of cards (based on the difficulty) and reset the score and start the elapsed timer.</p> <p>We have a few properties to store the state of the game. The most important one is the list of the cards (MemoryCardList). The MainViewModel derives from BaseViewModel that means we don’t have to explicitly implement the INotifyPropertyChanged interface because it’s already implemented in the base class as well as the RaisePropertyChanged method.</p> <p>Here’s the LoadCards method:</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 style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> LoadCards()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">int</span> cardCount = 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 style="color: #0000ff;">switch</span> (Difficulty)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">case</span> Difficulties.Easy:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> cardCount = 8;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> CardSize = 100;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">break</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 style="color: #0000ff;">case</span> Difficulties.Normal:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> cardCount = 10;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> CardSize = 78;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">break</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 style="color: #0000ff;">case</span> Difficulties.Hard:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> cardCount = 15;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> CardSize = 62;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">break</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;"> } </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #008000;">// clear</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;"> MemoryCardList.Clear();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #008000;">// add cards</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 style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < cardCount; i++)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> MemoryCardList.Add(<span style="color: #0000ff;">new</span> MemoryCard(i)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> Upside = <span style="color: #0000ff;">false</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;"> });</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> MemoryCardList.Add(<span style="color: #0000ff;">new</span> MemoryCard(i)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> Upside = <span style="color: #0000ff;">false</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;"> });</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #008000;">// shuffle them</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;"> var rand = <span style="color: #0000ff;">new</span> Random();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = MemoryCardList.Count - 1; i > 0; i--)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">int</span> n = rand.Next(i+1);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> var temp = MemoryCardList[i];</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> MemoryCardList[i] = MemoryCardList[n];</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> MemoryCardList[n] = temp;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> IsGameEnded = <span style="color: #0000ff;">false</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;">}</pre> <!--CRLF--></div> </div> <p>Note that we are adding two cards with the same ID at a time in the loop so we can pair them. After adding the cards we shuffle them. One last thing to explain: the CardSize specifies the actual size (width and height) of the cards in the View as we have smaller cards when there more. Keeping the CardSize in the ViewModel is not very elegant, it should belong to the View, I’ll probably refactor it.</p> <p>The heart of the game is the <strong>OnSelectionChanged</strong> method. First we count the upside cards, if it’s two (which is actually one plus the newly flipped) we compare the IDs. If there’s a match they are solved. We have to check if there are any unsolved cards there to track the end of the game. If two cards are already upside showing their front, the newly selected would be the third card to show it’s front, so we have to flip back everything. Here’s the code:</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 style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> OnSelectionChanged(MemoryCard lastCard)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">int</span> upsideNo = MemoryCardList.Count((m) => m.Upside); </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (upsideNo == 1)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #008000;">// one is upside + lastCard is 2, check IDs</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;"> MoveCounter++;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> var upsideCard = MemoryCardList.First((m) => m.Upside);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (upsideCard.ID == lastCard.ID)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (MemoryCardList.Count((m) => !m.Solved) == 2)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> _elapsedTimer.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;"> EndGame();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> upsideCard.SetSolved();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> lastCard.SetSolved();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> PairCounter++; </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</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;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (!_timer.IsEnabled)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> _timer.Start();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (upsideNo == 2)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #008000;">// two is already upside, hide them, lastCard will be the only upside</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;"> _timer.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;"> hideCards();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--></div> </div> <h3> </h3> <h3>Connecting the ViewModel and the View</h3> <p>After building the project the MainViewModel properties should show up in Blend’s databinding windows. We bind the MemoryCardList to the ListBox’s ItemSource. Click on the little square next to the ItemSource, choose DataBinding and select the MemoryCardList in the DataContext tab.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/binding0_thumb_2.png"><img width="804" height="124" title="binding0_thumb" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px solid;" alt="binding0_thumb" src="http://www.silverlightshow.net/Storage/Users/wildfox/binding0_thumb_thumb.png" /></a></p> <p>Now the ListBox will always display the cards in the ViewModel’s MemoryCardList property.</p> <h4>Converters</h4> <p>Blend’s databinding window shows only the compatible types by default. That means for example an IsVisible property type of bool won’t show up (by default) when you try to bind it to any element’s Visibility property, because the Visibility is type of a Visibility enum. Here enters the IValueConverter interface. When you build a class implementing this interface, you can pass it to the binding to have the data converted to compatible type.</p> <p>A classic example is the VisiblityConverter for the Solved property (so it’s working the opposite way), note that only one way is implemented, we won’t need the ConvertBack:</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 style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> VisibilityConverter : IValueConverter</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #cc6633;">#region</span> IValueConverter Members</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">object</span> Convert(<span style="color: #0000ff;">object</span> <span style="color: #0000ff;">value</span>, Type targetType, <span style="color: #0000ff;">object</span> parameter, System.Globalization.CultureInfo culture)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">value</span> == <span style="color: #0000ff;">null</span>) <span style="color: #0000ff;">return</span> Visibility.Visible;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ((<span style="color: #0000ff;">bool</span>)<span style="color: #0000ff;">value</span>) <span style="color: #0000ff;">return</span> Visibility.Collapsed;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">return</span> Visibility.Visible;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">object</span> ConvertBack(<span style="color: #0000ff;">object</span> <span style="color: #0000ff;">value</span>, Type targetType, <span style="color: #0000ff;">object</span> parameter, System.Globalization.CultureInfo culture)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> NotImplementedException();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #cc6633;">#endregion</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;">}</pre> <!--CRLF--></div> </div> <p>After build, you can set it up in Blend for the MemoryCard’s Solved property. Edit the CardList’s ItemTemplate, select the ToggleButton and bind the Visibility property:</p> <p>Switch to all properties, select the Solved property, open the dropdown at the bottom of the window, and select the VisibilityConverter as Value converter.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/binding2_thumb3_2.png"><img width="426" height="508" title="binding2_thumb3" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px solid;" alt="binding2_thumb3" src="http://www.silverlightshow.net/Storage/Users/wildfox/binding2_thumb3_thumb.png" /></a></p> <p>You can bind the Checked property to the Upside property without a converter, because both of them are a type of bool.</p> <p>Sometimes we need the ValueConverter in both ways, and sometimes we need additional parameters. To set the difficulty I needed both. There is a RadioButton for each difficulty, and we have one Difficulty property in the ViewModel type of an enum. So to make it work I needed to pass which RadioButton is the target. Here’s the code for the DifficultyConverter:</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 style="color: #0000ff;">public</span> <span style="color: #0000ff;">object</span> Convert(<span style="color: #0000ff;">object</span> <span style="color: #0000ff;">value</span>, Type targetType, <span style="color: #0000ff;">object</span> parameter, System.Globalization.CultureInfo culture)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (System.Convert.ToString(<span style="color: #0000ff;">value</span>).Equals(System.Convert.ToString(parameter)))</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</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: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</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;">}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">object</span> ConvertBack(<span style="color: #0000ff;">object</span> <span style="color: #0000ff;">value</span>, Type targetType, <span style="color: #0000ff;">object</span> parameter, System.Globalization.CultureInfo culture)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (System.Convert.ToBoolean(<span style="color: #0000ff;">value</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;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> Enum.Parse(<span style="color: #0000ff;">typeof</span>(Difficulties), System.Convert.ToString(parameter), <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;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <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;">}</pre> <!--CRLF--></div> </div> <p>And here’s the Binding for the Easy difficulty to the button’s Checked property:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/binding3_thumb2_2.png"><img width="413" height="493" title="binding3_thumb2" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px solid;" alt="binding3_thumb2" src="http://www.silverlightshow.net/Storage/Users/wildfox/binding3_thumb2_thumb.png" /></a></p> <p>Another converter was needed for displaying the images based on the ID. The <strong>ImageConverter</strong> takes the ID and converts it to an ImageSource by resolving a naming convention.</p> <h4>Formatting text</h4> <p>Converters are often used to format text, for example converting a number to string in a desired format. Silverlight 4 however introduced the StringFormat extension. Unfortunately I couldn’t find any Blend support here, so we have to dive into code to make it working. The following code formats the move counter to a 2-digit style:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/formatting_thumb1_2.png"><img width="475" height="67" title="formatting_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px solid;" alt="formatting_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/formatting_thumb1_thumb.png" /></a></p> <p>You can find a good summary about StringFormat on <a href="http://www.designersilverlight.com/2010/05/28/silverlight-4-binding-and-stringformat-in-xaml/">DesignerSilverlight</a>.</p> <h4>CallDatacontextMethodAction</h4> <p>We have to connect not just the data in the ViewModel to the View, but user-actions too. The standard way for the View to notify the ViewModel that something is happened is by commands. A simpler and more designer friendly approach is the CallDatacontextMethodAction behavior by <a href="http://dotneteers.net/blogs/vbandi/">András Velvárt</a>. You might have already read the article about it: <a href="http://www.silverlightshow.net/items/A-Designer-friendly-Approach-to-MVVM-Part-I.aspx">A Designer-friendly Approach to MVVM</a>.</p> <p>After adding it to the project and building it we can add it to our Start button to call the Start method on the ViewModel.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/wildfox/calldatacontextmethod0_thumb1_2.png"><img width="247" height="418" title="calldatacontextmethod0_thumb1" style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px solid;" alt="calldatacontextmethod0_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/calldatacontextmethod0_thumb1_thumb.png" /></a>    <a href="http://www.silverlightshow.net/Storage/Users/wildfox/calldatacontextmethod1_thumb1_2.png"><img width="484" height="280" title="calldatacontextmethod1_thumb1" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;border: 0px solid;" alt="calldatacontextmethod1_thumb1" src="http://www.silverlightshow.net/Storage/Users/wildfox/calldatacontextmethod1_thumb1_thumb.png" /></a></p> <h4></h4> <h4>Delaying an action</h4> <p>For the MemoryCard I had to delay the effect of setting the Solved property to true. What happened is by setting the card to solved it immediately disappeared, even before the control would arrive to the Checked state. This was clearly not okay, the player couldn’t see the card before it was marked as solved and disappeared.  That’s why I introduced the SetSolved method that starts a timer and only after 1.5 seconds sets the Solved property to true thus making the card disappear.</p> <h4>The Messenger class</h4> <p>The ViewModel sends a signal to the View once all of the cards are collected by using <a href="http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx">MVVM Light Messenger class</a>. The View then moves into the EndState:</p> <div id="codeSnippetWrapper"> <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;">Messenger.Default.Register<<span style="color: #0000ff;">string</span>>(<span style="color: #0000ff;">this</span>, (msg) =></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (Constants.EndGameMessage == msg)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: #f4f4f4; margin: 0em; padding-left: 0px; 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> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'courier new', courier, monospace; direction: ltr; color: black; font-size: 8pt; padding-top: 0px;border-style: none;"> VisualStateManager.GoToState(<span style="color: #0000ff;">this</span>, EndState.Name, <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;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; background-color: white; margin: 0em; padding-left: 0px; 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> <!--CRLF--></div> </div> <h3> </h3> <p>The Messenger is used in the MemoryCard class as well. When the card is flipped it notifies the MainViewModel and that is when the OnSelectionChanged method runs, which is the heart of the game.</p> <h3>Summary</h3> <p>In this article we inspected the development aspects of a game leveraging on MVVM using bindings, visual states, transitions and behaviors. Expression Blend turned out to be a really powerful tool as for the whole game we needed only little coding.</p> <p>In the final article of the series I will port this game to Windows Phone 7, exploring performance optimizations, phone-specific UI, and tombstoning. Don’t hesitate to drop a comment if you have questions or want to see something specific in the next article.</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-2-The-game-logic-connecting-the-ViewModel-and-the-View.aspx editorial@silverlightshow.net (Levente Mihály ) http://www.silverlightshow.net/items/A-classic-memory-game-Part-2-The-game-logic-connecting-the-ViewModel-and-the-View.aspx#comments http://www.silverlightshow.net/items/A-classic-memory-game-Part-2-The-game-logic-connecting-the-ViewModel-and-the-View.aspx Fri, 21 Jan 2011 09:54:00 GMT The validation story in Silverlight (Part 2) <p><strong>This article is compatible with the latest version of Silverlight.</strong></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; 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/Search.aspx?q=gill+cleeren&adv=true&ro=0&t=3&r=10&o=1">Recordings of Gill's webinars</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/The-duplex-story-looking-at-duplex-communication-in-Silverlight-4-Part-1.aspx">Gill's duplex story series</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/validation.aspx">The Validation series is now available as a fully offline resource: </a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/validation.aspx"><img style="border:0px solid;" alt="The validation story in Silverlight Ebook" src="http://www.silverlightshow.net/Storage/validation_ebook_thumb0.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($0.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 2 of the series “The validation story in Silverlight”.</p> <p>In the <a href="http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-1.aspx">previous part of this series</a>, we looked at the basic validation options we have available Silverlight (since version 3). The problem with the solutions we looked at is that they are mostly based on client-side validations. As you saw, the validation code, such as the attributes, assumes that all our validation needs are fulfilled with these attributes. In many cases, we’ll need to go to the server for a specific business rule. </p> <p>For example, we need to check if a user name already exists. We can’t solve that on the client, because for this, we’ll need to perform a call to the database over a service. When the service returns, it’s possible that the validation has failed. The object enters a non-valid state and we should be able to notify our UI about that. If you’re like me, you don’t want to write all that code yourself, so we have to put our hopes in the Silverlight framework to handle this in some way.</p> <p>The good news is that Silverlight 4 added support for this and more. More specifically, support was added for the IDataErrorInfo and the INotifyDataErrorInfo interfaces. We’ll start by looking at these in this article. Furthermore, we’ll take a look as well at how we can change the default looks of the validation: it’s very likely your application will use some other way of notifying the user that the value of a field is not correct.</p> <p>We use the same solution as with part 1, however, some more code was added. <a href="http://www.silverlightshow.net/Storage/Sources/SilverlightValidationPart2.zip" target="_blank">The code can be downloaded here</a>.</p> <h4>Hello IDataErrorInfo</h4> <p>First things first: let’s take a look at the definition of the interface. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">interface</span> IDataErrorInfo</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">string</span> Error { get; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">string</span> <span style="color: #0000ff;">this</span>[<span style="color: #0000ff;">string</span> columnName] { get; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>The Error property can be used to return error information about the object itself. In some cases, this is not used however and can be set to Null. Note that in data binding, this property is never called, so it’s only useful in custom error reporting.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Error</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> { </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>More important is the indexer. It can be used to write business rules for the different properties of the object. The columnName parameter refers to the name of the property and based on that name, we can trigger validation logic. The following snippet shows how we can use this indexer.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> <span style="color: #0000ff;">this</span>[<span style="color: #0000ff;">string</span> columnName]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">switch</span> (columnName)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">case</span> <span style="color: #006080;">"FirstName"</span>:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">string</span>.IsNullOrEmpty(FirstName))</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #006080;">"First name can't be empty"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (FirstName.Length > 50)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #006080;">"First name should be less than 50 characters"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">break</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">case</span> <span style="color: #006080;">"LastName"</span>:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">string</span>.IsNullOrEmpty(LastName))</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #006080;">"Last name can't be empty"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (LastName.Length > 50)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #006080;">"Last name should be less than 50 characters"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">break</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">case</span> <span style="color: #006080;">"Age"</span>:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (Age < 0)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #006080;">"Age can't be negative"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (Age > 120)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #006080;">"You are too old"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">break</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">default</span>:</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">break</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>Using the switch block, we check which property value needs to be validated. While in this sample, all logic ends up in this one location, it’s very well possible to extract this into a separate validation object, perhaps even containing some reusable (read: standard methods such as checking for string length).</p> <p>Now when data binding to an object that implements this interface, the same type of error messages are created for us in the UI. We do need to make one very important change: set the ValidateOnDataErrors property to true. This is a signal for the data binding engine that the object we are binding to implements the interface. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="FirstNameTextBox"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding FirstName, <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"</pre> </span></pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">/></span></pre> </div> </div> <p>If needed, we can apply both ValidatesOnExceptions and ValidatesOnDataErrors at the same time. However, if an exception occurs, the ValidatesOnDataErrors will never get called.</p> <p>While this is a clean way of performing validation, it still is aimed at simple, client-side only validation, that doesn’t solve the problem outlined earlier: performing a validation that involves asynchronous validations on the server. The interface has some other problems as well. For example, it’s not possible to return more than one exception per property (while this can be the case in real world objects). The interface does not support returning anything but a string (so no custom Exception types). </p> <p>To solve this, the INotifyDataErrorInfo comes in handy.</p> <h4>The INotifyDataErrorInfo interface</h4> <p>Next to the IDataErrorInfo, with Silverlight 4 came the INotifyPropertyChanged. Let’s start by looking at the interface definition. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">interface</span> INotifyDataErrorInfo</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">bool</span> HasErrors { get; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">event</span> EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> IEnumerable GetErrors(<span style="color: #0000ff;">string</span> propertyName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">sealed</span> <span style="color: #0000ff;">class</span> DataErrorsChangedEventArgs : EventArgs</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> DataErrorsChangedEventArgs(<span style="color: #0000ff;">string</span> propertyName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> PropertyName { get; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>Two things should pop out. First, notice the GetErrors, returning an IEnumberable. This makes it possible to have more than one exception on a single property. Next, the ErrorsChanged event can be used where we need to notify that the errors on the object have somehow changed (that is, after the return of an async call). Because of this, it’s easy to see that this interface is a perfect fit for Silverlight!</p> <p>Below is the new Person class (relevant part) with this interface applied. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> NotifyDataErrorInfoPerson: INotifyDataErrorInfo, INotifyPropertyChanged</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> _firstName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> _lastName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span> _age;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> Dictionary<<span style="color: #0000ff;">string</span>, List<CustomValidationException>> _errors;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> PropertyChangedEventHandler PropertyChanged;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> ...</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> NotifyErrorsChanged(<span style="color: #0000ff;">string</span> propertyName)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (ErrorsChanged != <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-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; padding-top: 0px;border-style: none;"> ErrorsChanged(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span> DataErrorsChangedEventArgs(propertyName));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Dictionary<<span style="color: #0000ff;">string</span>, List<CustomValidationException>> Errors </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> { </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> { </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_errors == <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-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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _errors = <span style="color: #0000ff;">new</span> Dictionary<<span style="color: #0000ff;">string</span>, List<CustomValidationException>>(); </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> } </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _errors; </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> } </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">bool</span> INotifyDataErrorInfo.HasErrors</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> (Errors.Where(error => error.Value.Count() > 0).Count() > 0);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> IEnumerable INotifyDataErrorInfo.GetErrors(<span style="color: #0000ff;">string</span> propertyName) </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> { </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (!Errors.ContainsKey(propertyName)) </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Errors.Add(propertyName, <span style="color: #0000ff;">new</span> List<CustomValidationException>()); </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> } </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> Errors[propertyName]; </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> } </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> CustomValidationException</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> ErrorLevelId { 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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Message { 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-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; padding-top: 0px;border-style: none;">} </pre> </div> </div> <p>Several things are important in this class now. First, notice we have included a Dictionary<string, List<CustomValidationException>>. The CustomValidationException is a custom class, containing some more info that just a string. The Dictionary itself is added to keep track of all errors on the properties. Indeed, for each property, we create a new KeyValuePair where the Key is the property name and the Value is a List<CustomValidationException>, making it possible to have more than one error per property. Next, notice the use of the ErrorsChanged event. We will raise this event whenever there’s a change in the errors on any property.</p> <p>Let’s now use this async validation. A new property was added, UserName. Usernames need to be unique, but we can’t check that on the client (sending down all already taken usernames would be silly): we need to make a call to a service. In this case, the service is performing a hardcoded check for the username: </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[OperationContract]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span> CheckUserNameUnique(<span style="color: #0000ff;">string</span> userName)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (userName == <span style="color: #006080;">"gillcleeren"</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Thread.Sleep(3000);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</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: #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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>Note that the Thread.Sleep(3000) was added to better see the async behavior. </p> <p>In the setter of the UserName, we now call this service. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> UserName</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _userName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _userName = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> NotifyPropertyChanged(<span style="color: #006080;">"UserName"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> CheckUserNameUnique();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> CheckUserNameUnique()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> UserValidatorService.UserValidatorServiceClient proxy = </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">new</span> UserValidatorService.UserValidatorServiceClient();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> proxy.CheckUserNameUniqueCompleted += </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">new</span> EventHandler<UserValidatorService.CheckUserNameUniqueCompletedEventArgs></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> (proxy_CheckUserNameUniqueCompleted);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> proxy.CheckUserNameUniqueAsync(UserName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>Nothing special here, this service call will be triggered whenever a new value is entered into the field. In the callback, we handle the response of the server: we check if the response is false. If so, we create a new CustomValidationException instance that we add in the List<CustomValidationException> for the key “UserName” in the errors dictionary. If the response is true, the error should be removed from the List again. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">void</span> proxy_CheckUserNameUniqueCompleted(<span style="color: #0000ff;">object</span> sender, UserValidatorService.CheckUserNameUniqueCompletedEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">bool</span> result = e.Result;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> CustomValidationException exc;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (e.Error != <span style="color: #0000ff;">null</span> || !e.Result)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (result == <span style="color: #0000ff;">false</span>)<span style="color: #008000;">//we have a failing unique constraint </span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> exc = <span style="color: #0000ff;">new</span> CustomValidationException();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> exc.ErrorId = FAILING_UNIQUE_ERROR_ID;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> exc.ErrorLevelId = 100;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> exc.Message = <span style="color: #006080;">"This username not unique"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #008000;">//add error for the property in the dictionary</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> CreatePropertyErrorList(<span style="color: #006080;">"UserName"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #008000;">//there is no error in the collection with the specified ID</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_errors[<span style="color: #006080;">"UserName"</span>].SingleOrDefault(c => c.ErrorId == exc.ErrorId) == <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-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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _errors[<span style="color: #006080;">"UserName"</span>].Add(exc);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> NotifyErrorsChanged(<span style="color: #006080;">"UserName"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (e.Result)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> CreatePropertyErrorList(<span style="color: #006080;">"UserName"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> exc = _errors[<span style="color: #006080;">"UserName"</span>].SingleOrDefault(c => c.ErrorId == FAILING_UNIQUE_ERROR_ID);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (exc != <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-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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _errors[<span style="color: #006080;">"UserName"</span>].Remove(exc);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> NotifyErrorsChanged(<span style="color: #006080;">"UserName"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>Whenever something changes in the collection of errors (here it happens asynchronously, and you’ll see this very well because of the Thread.Sleep() we added earlier), we call the NotifyErrorsChanged method, which in turn calls the ErrorsChanged event. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> NotifyErrorsChanged(<span style="color: #0000ff;">string</span> propertyName)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (ErrorsChanged != <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-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; padding-top: 0px;border-style: none;"> ErrorsChanged(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span> DataErrorsChangedEventArgs(propertyName));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>In the binding expression, we need to tell Silverlight it has to watch for the ErrorsChanged event being thrown from the bound source object by specifying the ValidatesOnNotifyDataErrors=true. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="UserNameTextBox"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding UserName, Mode=TwoWay, <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}"</pre> </span></pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">/></span></pre> </div> </div> <p>The result is, of course, similar:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image001_2.png"><img width="435" height="234" title="clip_image001" style="border:0px; display: inline;" alt="clip_image001" src="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image001_thumb.png" /></a></p> <h4>Customizing the error display</h4> <p>Up until here, we have always used the default way of displaying errors on fields: the red popup containing the error message. It’s very well possible that this default is not a good fit for your application, so we need to change it. The good news is that this validation popup is part of the control template: several controls have a VisualStateGroup called VadiationStates that dictates how the control will look in Valid, InvalidFocused and InvalidUnfocused. InvalidFocused by default shows the red Border, the red triangle in the top right corner and the red popup. InvalidUnfocused hides the popup.</p> <p>Let’s change this default look. Start by opening the project in Expression Blend 4. Right-click on the UserNameTextBox and select Edit Template --> Edit a copy. Give it a name, for example CustomValidationTemplate. Blend will now enter the template editing mode. </p> <p><a href="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image001%5B5%5D.png"><img width="507" height="232" title="clip_image001[5]" style="border:0px; display: inline;" alt="clip_image001[5]" src="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image001%5B5%5D_thumb.png" /></a></p> <p>Take a look at the Objects and Timeline window. As the last element in the list, you can see the ValidationErrorElement, the red Border, containing a few other elements, such as the small red triangle appearing when an error is displayed. In the States window, note the ValidationStates stategroup with the above mentioned states. </p> <p><a href="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image002_2.png"><img width="230" height="400" title="clip_image002" style="border:0px; display: inline;" alt="clip_image002" src="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image002_thumb.png" /></a></p> <p>Since I’m no designer, my custom template may look at bit basic: we will at a red * when the field goes into the invalid state. To do so, make sure the Base state is selected and add a TextBlock in the template, containing the *. In this Base state, set its Opacity to 0.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image003_2.png"><img width="431" height="141" title="clip_image003" style="border:0px; display: inline;" alt="clip_image003" src="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image003_thumb.png" /></a></p> <p>Now for both the InvalidFocused and InvalidUnfocused, set the Opacity of the TextBlock to 100 and (for demo purposes) set the Opacity of the ValidationErrorElement to 0. </p> <p>Now run the application again and we can see the custom validation template in action.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image004_2.png"><img width="354" height="230" title="clip_image004" style="border:0px; display: inline;" alt="clip_image004" src="http://www.silverlightshow.net/Storage/Users/gillcleeren/clip_image004_thumb.png" /></a></p> <h4>Summary</h4> <p>This concludes the overview of validation options currently available in Silverlight 4. The most fundamental option is of course the INotifyDataErrorInfo, which is due to its support for async validation a perfect fit for Silverlight. Validation in Silverlight is ready for real world scenarios!</p> <h3>About the author</h3> <p>Gill Cleeren is Microsoft Regional Director (<a href="http://www.theregion.com/">www.theregion.com</a> ), MVP ASP.NET, INETA speaker bureau member and Silverlight Insider. He lives in Belgium where he works as .NET architect at Ordina. Passionate about .NET, he’s always playing with the newest bits. In his role as Regional Director, Gill has given many sessions, webcasts and trainings on new as well as existing technologies, such as Silverlight, ASP.NET and WPF. He also leads Visug (<a href="http://www.visug.be/">www.visug.be</a>), the largest .NET user group in Belgium. He’s also the author of “Silverlight 4 Data and Services Cookbook”, published by Packt Publishing. You can find his blog at <a href="http://www.snowball.be/">www.snowball.be</a> .</p> http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-2.aspx editorial@silverlightshow.net (Gill Cleeren ) http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-2.aspx#comments http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-2.aspx Mon, 06 Dec 2010 04:15:00 GMT The validation story in Silverlight (Part 1) <p><strong>This article is compatible with the latest version of Silverlight.</strong></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; 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/Search.aspx?q=gill+cleeren&adv=true&ro=0&t=3&r=10&o=1">Recordings of Gill's webinars</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/items/The-duplex-story-looking-at-duplex-communication-in-Silverlight-4-Part-1.aspx">Gill's duplex story series</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/validation.aspx">The Validation series is now available as a fully offline resource: </a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/validation.aspx"><img style="border:0px solid;" alt="The validation story in Silverlight Ebook" src="http://www.silverlightshow.net/Storage/validation_ebook_thumb0.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($0.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 style="padding-bottom: 5px;">      <a href="http://www.silverlightshow.net/book/Microsoft-Silverlight-4-Data-and-Services-Cookbook.aspx"> <img alt="Silverlight 4 book" src="http://www.silverlightshow.net/Storage/Silverlight4book.jpg" /></a> </p> <p style="font-size: 12px;">              <a href="http://www.silverlightshow.net/Books.aspx">Show more books...</a></p> <p>This article is Part 1 of the series “The validation story in Silverlight”. </p> <p>If one feature is important when it comes to building line-of-business applications, it certainly is validation of business rules. At all levels throughout the application, we need to validate that the data that is entered by the users to verify that it meets the requirements. Some basic validation can be done by the database itself, but most (and in many cases, all) data that it trying to make its way to the database should be validated up front in order not to end up with corrupted data within the data store.</p> <p>If we think of validation in the ASP.NET world, we can identify 2 places where validation is needed. First, we try validating user input using JavaScript on the client-side (perhaps using one of the built-in validation controls). This ensures quick feedback to the user, preventing him from having to wait for a post-back to the server in which we can do server validation of the data. However, we can’t just rely on the fact that JavaScript is enabled (and therefore risk that users can go around our validation rules) so server-side validation is needed as well. The latter of course requires us to post back to the server, after which we can send back the errors to the user, if any, for example using a validation summary.</p> <p>When doing validation in Silverlight, things are a bit different. Because everything runs on the client and we want to give the user the richest experience on that client, we need to make sure that validation that we build in, adds to that rich experience as well. Immediate feedback where possible is one of the things that comes to mind: we don’t want the user to have to wait for validation to happen on the server. Instead, where possible, we want to display validation messages as soon as the user leaves the field or clicks on a button. </p> <p>The validation story in Silverlight up until version 4 was somewhat lacking in features. While Silverlight 3 had some options available, they were not really enough for real-world applications. That changed with Silverlight 4, mainly because of the introduction of 2 new interfaces, namely the IDataErrorInfo and the INotifyDataErrorInfo. The first one may sound familiar as it already exists for WinForms validation. The latter will be helpful in situations where we need to perform calls to the server and return asynchronous validation results. </p> <p>This is a two-part article. The code for this first part article exists of some samples that we are using to explain the features and <a href="http://www.silverlightshow.net/Storage/Sources/SilverlightValidation.zip" target="_blank">can be downloaded here</a>.</p> <h4>Overview of the validation options in Silverlight 4</h4> <p>As mentioned in the previous paragraph, Silverlight 3 had limited options to validate user input whereas Silverlight 4 added to this quite a lot. To start, here’s a brief overview of the options we have at our disposal today: <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p><strong>Type</strong></p> <p> </p> <p> </p> <p> </p> <p></td> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p><strong>Property</strong></p> <p> </p> <p> </p> <p> </p> <p></td> </tr> <tr> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p>Throw exceptions in your setters</p> <p> </p> <p> </p> <p> </p> <p></td> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p>Enable ValidatesOnExceptions</p> <p> </p> <p> </p> <p> </p> <p></td> </tr> <tr> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p>IDataErrorInfo</p> <p> </p> <p> </p> <p> </p> <p></td> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p>Enable ValidatesOnDataErrors </p> <p> </p> <p> </p> <p> </p> <p></td> </tr> <tr> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p>INotifyDataErrorInfo</p> <p> </p> <p> </p> <p> </p> <p></td> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p>Enable ValidatesOnNotifyDataErrors </p> <p> </p> <p> </p> <p> </p> <p></td> </tr> <tr> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p>If you want the errors to be passed on in the hierarchy</p> <p> </p> <p> </p> <p> </p> <p></td> <td valign="top" style="width: 432px;"></p> <p> </p> <p> </p> <p> </p> <p>Enable NotifyOnValidationError </p> <p> </p> <p> </p> <p> </p> <p></td> </tr> </tbody> </table> </p> <p>We’ll start this overview by looking at the “throwing exceptions” option (that is, the Silverlight 3 option).</p> <h4>Silverlight 3 validation options</h4> <p>Validation in Silverlight 3 is limited to working with 2 properties on a data binding expression: ValidatesOnExceptions and NotifyOnValidationErrors.</p> <p>When we apply ValidatesOnExceptions, when we try to update a value using data binding (that is, a TwoWay binding, since we are pushing data from the target control to the source property), Silverlight will check if any exceptions are being thrown, for example trying to enter a string into a numeric field. If an exception happens, Silverlight’s data binding engine will create ValidationError and add this error to the Validation.Errors collection of the target control (that is the UI element we are applying the binding on). If we want to receive notifications that these exceptions occurred, we need to set NotifyOnValidationErrors to true as well. </p> <p>Let’s look at the obligatory “Binding to a Person object” person to show this type of validation. The Person class itself has just two string and one integer properties. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> SimplePerson</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> _firstName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> _lastName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span> _age;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> FirstName</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _firstName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">value</span>.Length == 0)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> Exception(<span style="color: #006080;">"First name length can not be 0"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _firstName = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> LastName</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _lastName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">value</span>.Length == 0)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> Exception(<span style="color: #006080;">"Last name length can not be 0"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _lastName = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Age </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _age;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _age = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p> </p> <p>Note that the FirstName and LastName throw an error if the value entered by the user is an empty string. The parameter for the Exception is the error message we want to show to the user. The Age property, since it’s of type int, will throw an error if we try to enter a string.</p> <p>The data binding expressions are now defined with the above mentioned properties, as can be seen in the code below. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="FirstNameTextBox"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding FirstName, Mode=TwoWay, <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> ValidatesOnExceptions=True, NotifyOnValidationError=True}"</pre> </span></pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="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-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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="LastNameTextBox"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding LastName, Mode=TwoWay, <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> ValidatesOnExceptions=True, NotifyOnValidationError=True}"</pre> </span></pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="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-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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="AgeTextBox"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Top"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding Age, Mode=TwoWay, <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> ValidatesOnExceptions=True, NotifyOnValidationError=True}"</pre> </span></pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">/></span></pre> <!--CRLF--></div> </div> <p>This results in Silverlight automatically showing the default behavior for an exception being raised:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/gillcleeren/___image_2.png"><img width="594" height="152" title="image" style="border:0px; display: inline;" alt="image" src="http://www.silverlightshow.net/Storage/Users/gillcleeren/___image_thumb.png" /></a> </p> <p>This default look is implemented within the control template on most controls within Silverlight. We’ll look later how we can override this and apply our own type of look and feel for this error reporting.</p> <h5>Adding attributes</h5> <p>If we have to write Exceptions ourselves for all validation, this can become quite a cumbersome task. To solve this somewhat, it’s possible to include attributes on the properties. These validation attributes include most common types of validation, including Required fields and StringLength. When applying these, the validation engine will work in the exact same way, as can be seen below. First, the updated Person class. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[Required]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[StringLength(50)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> FirstName</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _firstName; </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_firstName != <span style="color: #0000ff;">value</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _firstName = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[Required]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[StringLength(50)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> LastName</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _lastName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_lastName != <span style="color: #0000ff;">value</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _lastName = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[Range(1, 120)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[Required]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Age</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _age;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_age != <span style="color: #0000ff;">value</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _age = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>If we try our exact same sample again now, we’ll notice that the binding won’t display an error, even though we have applied the attributes. Instead, we need to trigger the validation to happen. We can do this using the ValidationContext.ValidateProperty, passing in the name of the property we want to validate. By applying this in the setters of the properties, we can use it to trigger all attributes to be validated.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[StringLength(50)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> FirstName</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _firstName; </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_firstName != <span style="color: #0000ff;">value</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Validator.ValidateProperty(<span style="color: #0000ff;">value</span>, <span style="color: #0000ff;">new</span> ValidationContext(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">null</span>, <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-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; padding-top: 0px;border-style: none;"> { MemberName = <span style="color: #006080;">"FirstName"</span> });</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _firstName = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[Required]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[StringLength(50)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> LastName</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _lastName;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_lastName != <span style="color: #0000ff;">value</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Validator.ValidateProperty(<span style="color: #0000ff;">value</span>, <span style="color: #0000ff;">new</span> ValidationContext(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">null</span>, <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-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; padding-top: 0px;border-style: none;"> { MemberName = <span style="color: #006080;">"LastName"</span> });</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _lastName = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[Range(1, 120)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[Required]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Age</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _age;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_age != <span style="color: #0000ff;">value</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Validator.ValidateProperty(<span style="color: #0000ff;">value</span>, <span style="color: #0000ff;">new</span> ValidationContext(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">null</span>, <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-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; padding-top: 0px;border-style: none;"> { MemberName = <span style="color: #006080;">"Age"</span> });</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _age = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <h5>Custom rules</h5> <p>One attribute deserves some special attention: the CustomAttribute. Using this attribute, we can define custom methods to perform more advanced business rule validation. It accepts two parameters by default: the type that contains the validation methods and the validation method you want to use on the property. Let’s look at an example on the Age property (agreed, the rule can be done using the Range attribute as well, but I hope you get the point). Note that the method returns a ValidationResult. If everything runs fine, we return ValidationResult.Success; otherwise, we create a new ValidationResult, passing in the custom message we want to display. Note also that it’s easy to localize these error messages here to return translated strings for the exceptions. </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> CustomAgeValidator</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> ValidationResult ValidateAge(<span style="color: #0000ff;">int</span> age)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (age < 120 && age > 0)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> ValidationResult.Success;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(age < 0)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> ValidationResult(<span style="color: #006080;">"You can't have a negative age!"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <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-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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> ValidationResult(<span style="color: #006080;">"You are too old!!"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>The CustomAttribute can now be used as such: </p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[Required]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">[CustomValidation(<span style="color: #0000ff;">typeof</span>(CustomAgeValidator), <span style="color: #006080;">"ValidateAge"</span>)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> Age</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> _age;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> (_age != <span style="color: #0000ff;">value</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Validator.ValidateProperty(<span style="color: #0000ff;">value</span>, </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">new</span> ValidationContext(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">null</span>, <span style="color: #0000ff;">null</span>) { MemberName = <span style="color: #006080;">"Age"</span> });</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> _age = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>And here we see the custom validator in action, including the custom error message:</p> <h4><a href="http://www.silverlightshow.net/Storage/Users/gillcleeren/__image_4.png"><img width="484" height="174" title="image" style="border:0px; display: inline;" alt="image" src="http://www.silverlightshow.net/Storage/Users/gillcleeren/__image_thumb_1.png" /></a> </h4> <h4>Summarizing all errors with the ValidationSummary</h4> <p>Instead of displaying errors only on the fields, a separate control can help us displaying all errors on a central location: the ValidationSummary. This control, which lives in the System.Windows.Controls namespace, will display object and property errors in a list (each item in this list is of type ValidationSummaryItem and can be template).When clicking on an item, the ValidationSummary control will try to apply focus on the control that caused the error, giving the user a better experience when fixing errors in a form. For the control to pick up on the errors, the NotifyOnValidationErrors should be set to true. This causes the binding to raise a notification event for the failing validation. </p> <p>The code does not need a lot of changes. In fact, we can just add the ValidationSummary and it will work as expected.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="FirstNameTextBox"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding FirstName, Mode=TwoWay, <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> ValidatesOnExceptions=True, NotifyOnValidationError=True}"</pre> </span></pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="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-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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="LastNameTextBox"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding LastName, Mode=TwoWay, <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> ValidatesOnExceptions=True, NotifyOnValidationError=True}"</pre> </span></pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="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-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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Name</span><span style="color: #0000ff;">="AgeTextBox"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Top"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding Age, Mode=TwoWay, <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> ValidatesOnExceptions=True, NotifyOnValidationError=True}"</pre> </span></pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="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-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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;"><</span><span style="color: #800000;">sdk:ValidationSummary</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</span><span style="color: #0000ff;">="3"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">ColumnSpan</span><span style="color: #0000ff;">="2"</span><span style="color: #0000ff;">></</span><span style="color: #800000;">sdk:ValidationSummary</span><span style="color: #0000ff;">></span></pre> </div> </div> <p><a href="http://www.silverlightshow.net/Storage/Users/gillcleeren/_image_6.png"><img width="509" height="221" title="image" style="border:0px; display: inline;" alt="image" src="http://www.silverlightshow.net/Storage/Users/gillcleeren/_image_thumb_2.png" /></a> </p> <h4>Summary</h4> <p>With that, we have seen the basic validation capabilities of Silverlight. As mentioned, these are where Silverlight 3 leaves of and honestly, we need more. All what is explained here of course works in the latest version as well. On top of that, Silverlight 4 added some nice features. In the second part, we’ll look at some more advanced concepts, such as the IDataErrorInfo.</p> http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-1.aspx editorial@silverlightshow.net (Gill Cleeren ) http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-1.aspx#comments http://www.silverlightshow.net/items/The-validation-story-in-Silverlight-Part-1.aspx Fri, 03 Dec 2010 00:59:00 GMT WCF RIA Services Part 6 - Validating Data <div style="border:1px solid #dddddd;padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px;"><strong><img alt="" width="128" height="97" style="width: 112px; float: right; height: 80px; margin-left: 10px;" src="http://www.silverlightshow.net/Storage/old_skool_cassette.png" />Watch recordings of Brian's WCF RIA Services webinars:</strong>   <ul> <li><a href="http://www.silverlightshow.net/shows/WCF-RIA-Services-Webinar-1.aspx">Querying & Updating Data From Silverlight Clients with WCF RIA Services</a> (Feb 03, 2011)</li> <li><a href="http://www.silverlightshow.net/shows/WCF-RIA-Services-Webinar-2.aspx">WCF RIA Services Validation</a> (Mar 17, 2011)</li> <li><a href="http://www.silverlightshow.net/shows/WCF-RIA-Services-Webinar-3.aspx">Secure and Personalize Your Silverlight App with WCF RIA Services</a> (May 26, 2011)</li> <li><a href="http://www.silverlightshow.net/shows/WCF-RIA-Services-Webinar-4.aspx">WCF RIA POCO Domain Services</a> (Sep 29, 2011)</li> </ul> </div> <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/Deep-dive-into-WCF-part-1-TDD.aspx">Deep Dive Into WCF series</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Search.aspx?q=WCF&adv=true&tg=true&ro=0&t=1,2,3,5&r=10&o=1">See more articles on WCF</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/shows/Paging-WCF-Ria-Services-entities-in-MVVM-applications.aspx">WCF RIA Services Show</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/wcf_ria_services.aspx">The WCF series is now available as a fully offline resource: </a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/wcf_ria_services.aspx"><img style="border:0px solid;" alt="WCF RIA Services Ebook" src="http://www.silverlightshow.net/Storage/wcf_ria_ebook_thumb0.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>This article is Part 6 of the series WCF RIA Services.</p> <h3>Introduction</h3> <p>In <a href="http://www.silverlightshow.net/items/WCF-RIA-Services-Part-5-Metadata-and-Shared-Classes.aspx" target="_blank">Part 5</a> I discussed metadata classes and shared code, and one of the example uses of metadata classes I showed was using a <strong>[Required]</strong> validation attribute to cause some validation on both the client and server side. In this article, I will dive into more depth on the various ways you can validate data using WCF RIA Services. I’m going to look at four ways of validating input data:</p> <ul> <li>Using built-in validation attributes from the System.ComponentModel.DataAnnotations namespace </li> <li>Using custom validation attributes to invoke custom logic on the server and client side for cross property validation </li> <li>Using server side validation when changes are submitted to the back end </li> <li>Doing asynchronous validation using a domain service invoke operation </li> </ul> <p>To demonstrate these things in the application context that I have been building up over the last 5 articles, I needed to add some more functionality. That functionality included some small schema changes to the database, so a new database creation script is included with the download code to create an appropriate database schema with some minimal sample data to be able to run the application. Because I am continuing to keep the focus on WCF RIA Services capabilities and not on general Silverlight display functionality, the display of some of the validation errors in the sample is necessarily crude to keep the changes to the app to a minimum and to keep the article length digestible.</p> <p>The new functionality includes the ability to add customers (and there are a couple defined in the DB script so you don’t have to add any to get started), as well as select a customer associated with a given <strong>Task</strong>. There are validations associated with the definition of a <strong>Customer</strong>, as well as for creating time entries associated with a task that has a customer, described in more detail later in the article.</p> <p>The finished code for this article <a href="http://www.silverlightshow.net/Storage/Sources/TaskManagerPart6.zip" target="_blank">can be downloaded here</a>.</p> <h3>Data Annotation Validation Attributes</h3> <p>As mentioned last time, WCF RIA Services has rich built-in support for the validation attributes in the <strong>System.ComponentModel.DataAnnotation</strong> namespace. These attributes include the ability to specify simple forms of validation on entity properties by adding an attribute to an entity property. If your entity model is one where you cannot modify the properties directly (such as the code generated entities of Entity Framework), you can place the validation attributes on the properties of your metadata class. Those validation attributes will be used for server side validation by WCF RIA Services, and they will also be used client side because the client generated entities will have those attributes on their properties.</p> <p>The available validation attributes include:</p> <ul> <li>Required </li> <li>StringLength (added by Entity Framework for string fields and therefore generated on the client) </li> <li>Regular Expressions </li> <li>Range (for numeric inputs) </li> </ul> <p>There are a few others in the namespace that you might want to look into that purely affect display, but I won’t go into details of those in this article.</p> <p>To apply them when using an entity framework model, you again just add them to the properties of your metadata class.</p> <p>The generated client code will include those defined in your metadata class, as well as any defined on the model entities themselves, such as the<strong> [StringLength]</strong> attributes added by Entity Framework for string fields in the database.</p> <p>As an example of using one of these attributes, a <strong>Customer</strong> has a <strong>Phone</strong> property that is a string, but needs to follow a proper format for a phone number. A regular expression is a great way of checking this kind of thing. So the metadata class for my <strong>Customer</strong> entity type includes the following attribute on the <strong>Phone</strong> property:</p> <div id="codeSnippetWrapper"> <div class="csharpcode" id="codeSnippet"> <pre class="alt"><span class="lnum" id="lnum1"> </span>[MetadataTypeAttribute(<span class="kwrd">typeof</span>(Customer.CustomerMetadata))]</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum2"> </span><span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> Customer</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum3"> </span>{</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum4"> </span> <span class="kwrd">internal</span> <span class="kwrd">sealed</span> <span class="kwrd">class</span> CustomerMetadata</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum5"> </span> {</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum6"> </span> ...</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum7"> </span> [RegularExpression(<span class="str">@"^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$"</span>, ErrorMessage=<span class="str">"..."</span>)]</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum8"> </span> <span class="kwrd">public</span> <span class="kwrd">string</span> Phone { get; set; }</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum9"> </span> ...</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum10"> </span> }</pre> </div> </div> <p>You can see the only challenge in using the regular expression validation is in coming up with the right regular expression. The one I am using here allows several formatting variants of US phone numbers (3 digits, 3 digits, 4 digits with variations on delimiters in between). </p> <p>Just by having that attribute on the server entity or its metadata class, it shows up on the code generated client entity. Additionally, the WCF RIA Services <strong>Entity</strong> base class that is added to the client entity has an implementation of <strong>INotifyDataErrorInfo</strong> that uses the data annotation attributes to perform validation when data bound in the UI. So just by adding these attributes with appropriate error messages, you get validation indications for the user like shown below.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/brian.noyes/8-24-2010%207-20-20%20AM_2.png"><img width="727" height="417" title="8-24-2010 7-20-20 AM" style="border:0px solid; display: inline;" alt="8-24-2010 7-20-20 AM" src="http://www.silverlightshow.net/Storage/Users/brian.noyes/8-24-2010%207-20-20%20AM_thumb.png" /></a> </p> <p>The error message shown on the <strong>Phone</strong> input <strong>TextBox</strong> happens automatically when the focus leaves the control. In the sample code, I used a behavior to cause the binding to update on each keystroke to get more immediate feedback to the user. The error message shown is the one specified in the server side attribute. You can also see that I added a <strong>ValidationSummary</strong> control to the form. That is to display when there is more than one validation error on the form at a time, which will come into play in the next section.</p> <h3>Custom Validation Attributes</h3> <p>In addition to the pre-built validation attributes discussed in the last section, there is a<strong> [CustomValidation]</strong> attribute in the data annotations namespace that allows you to point to a static method you can define to perform any kind of custom logic you need to validate when a property is set. That may involve doing some calculation or conditional logic, but ultimately you are deciding whether the newly input values are valid. Keep in mind that if you put these attributes on the server side entity or its metadata class, you will need to ensure that the code defined in the custom validation will be able to execute on both the client and server side. So you would not want to put code in there that does a look up against the database for example. I’ll show examples of how to deal with that kind of validation in the next two sections.</p> <p>One place custom validations come in very handy is for cross-property validations. When the validity of one property’s value depends on the value of another property on the same object, or possibly the values of some of the child objects or a parent object, you can accommodate this fairly easily using custom validation.</p> <p>In the <strong>Customer</strong> class for the sample, I added a contrived property called <strong>HasPhone</strong>. The simple idea here is that if <strong>HasPhone</strong> is set to true, then a valid phone number should be supplied. If <strong>HasPhone</strong> is set to false, no phone number should be supplied. This validation should be triggered whenever either property is modified, and both properties can be displayed as having a validation error when they are out of sync. You can see this in action below. Notice that both input controls (Phone <strong>TextBox</strong> and HasPhone <strong>CheckBox</strong>) are indicating a validation error, and there are two errors shown in the <strong>ValidationSummary</strong> control.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/brian.noyes/8-24-2010%207-23-02%20AM_2.png"><img width="508" height="407" title="8-24-2010 7-23-02 AM" style="border:0px solid; display: inline;" alt="8-24-2010 7-23-02 AM" src="http://www.silverlightshow.net/Storage/Users/brian.noyes/8-24-2010%207-23-02%20AM_thumb.png" /></a> </p> <p>To support this, you first define the validation method that you want to point to from the <strong>[CustomValidation]</strong> attribute. That method has to have a particular signature, specifically it must be public, return a <strong>ValidationResult</strong>, and take in a value and a <strong>ValidationContext</strong>. If you are doing two properties with different types on the properties like I am here, you can break it down into two methods with each value having the appropriate type, even if they share some validation code:</p> <div id="codeSnippetWrapper"> <div class="csharpcode" id="codeSnippet"> <pre class="alt"><span class="lnum" id="lnum1"> </span><span class="kwrd">public</span> <span class="kwrd">class</span> CustomerPhoneValidator</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum2"> </span>{</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum3"> </span> <span class="kwrd">public</span> <span class="kwrd">static</span> ValidationResult CrossValidatePhoneWithHasPhone(<span class="kwrd">string</span> newPhone, ValidationContext context)</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum4"> </span> {</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum5"> </span> Customer customer = context.ObjectInstance <span class="kwrd">as</span> Customer;</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum6"> </span> <span class="kwrd">if</span> (customer == <span class="kwrd">null</span>) <span class="kwrd">return</span> ValidationResult.Success;</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum7"> </span> <span class="kwrd">bool</span> hasPhone = customer.HasPhone;</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum8"> </span> <span class="kwrd">string</span> phone = newPhone;</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum9"> </span> </pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum10"> </span> <span class="kwrd">return</span> ValidatePhoneAndHasPhone(hasPhone, phone);</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum11"> </span> }</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum12"> </span> </pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum13"> </span> <span class="kwrd">public</span> <span class="kwrd">static</span> ValidationResult CrossValidateHasPhoneWithPhone(<span class="kwrd">bool</span> newHasPhone, ValidationContext context)</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum14"> </span> {</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum15"> </span> Customer customer = context.ObjectInstance <span class="kwrd">as</span> Customer;</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum16"> </span> <span class="kwrd">if</span> (customer == <span class="kwrd">null</span>) <span class="kwrd">return</span> ValidationResult.Success;</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum17"> </span> <span class="kwrd">bool</span> hasPhone = newHasPhone;</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum18"> </span> <span class="kwrd">string</span> phone = customer.Phone;</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum19"> </span> </pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum20"> </span> <span class="kwrd">return</span> ValidatePhoneAndHasPhone(hasPhone, phone);</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum21"> </span> }</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum22"> </span> </pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum23"> </span> <span class="kwrd">private</span> <span class="kwrd">static</span> ValidationResult ValidatePhoneAndHasPhone(<span class="kwrd">bool</span> hasPhone, <span class="kwrd">string</span> phone)</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum24"> </span> {</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum25"> </span> <span class="kwrd">if</span> (hasPhone && <span class="kwrd">string</span>.IsNullOrWhiteSpace(phone))</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum26"> </span> {</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum27"> </span> <span class="kwrd">return</span> <span class="kwrd">new</span> ValidationResult(<span class="str">@"If the customer has a phone, the number must be specified"</span>, </pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum28"> </span> <span class="kwrd">new</span> <span class="kwrd">string</span>[] { <span class="str">"HasPhone"</span>, <span class="str">"Phone"</span> });</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum29"> </span> }</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum30"> </span> <span class="kwrd">else</span> <span class="kwrd">if</span> (!hasPhone && !<span class="kwrd">string</span>.IsNullOrWhiteSpace(phone))</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum31"> </span> {</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum32"> </span> <span class="kwrd">return</span> <span class="kwrd">new</span> ValidationResult(<span class="str">@"If the customer does not have a phone, the number should not be specified"</span>, </pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum33"> </span> <span class="kwrd">new</span> <span class="kwrd">string</span>[] { <span class="str">"HasPhone"</span>, <span class="str">"Phone"</span> });</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum34"> </span> }</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum35"> </span> <span class="kwrd">else</span></pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum36"> </span> {</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum37"> </span> <span class="kwrd">return</span> ValidationResult.Success;</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum38"> </span> }</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum39"> </span> }</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum40"> </span>}</pre> <!--CRLF--></div> </div> <p>You can see that I have two validation methods, one for the boolean <strong>HasPhone</strong> property and one for the string <strong>Phone</strong> property. Other than the type of the value, the signature of the methods is the same. You can see that the <strong>ValidationContext</strong> argument that is passed to your method allows you to get a reference to the whole object that the property being validated is on, allowing you to get to other properties on that object. At the point where your validation method is being called, the target property (i.e. <strong>Phone</strong>) has not been set on the object itself yet. The value being passed in to your validation method is the proposed new value, and it is up to your method to decide whether to allow it to be set or not. If you are fine with the value being set, you just return a <strong>ValidationResult.Success</strong> value. If you do not like the value, then you can return a <strong>ValidationResult</strong> with an error string populated and optionally a string array containing all of the property names affected by the error. This is how you can address cross-property validation scenarios like the one here. If no phone or an invalid phone number is supplied, I can check to see if the <strong>HasPhone</strong> property is set to true. If so, both <strong>Phone</strong> and <strong>HasPhone</strong> are in error because they have to agree with respect to their supplied values.</p> <p>To apply the custom validation to a property, you just use a<strong> [CustomValidation]</strong> attribute:</p> <div id="codeSnippetWrapper"> <div class="csharpcode" id="codeSnippet"> <pre class="alt"><span class="lnum" id="lnum1"> </span>[MetadataTypeAttribute(<span class="kwrd">typeof</span>(Customer.CustomerMetadata))]</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum2"> </span><span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> Customer</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum3"> </span>{</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum4"> </span> <span class="kwrd">internal</span> <span class="kwrd">sealed</span> <span class="kwrd">class</span> CustomerMetadata</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum5"> </span> {</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum6"> </span> ...</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum7"> </span> [CustomValidation(<span class="kwrd">typeof</span>(CustomerPhoneValidator),<span class="str">"CrossValidatePhoneWithHasPhone"</span>)]</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum8"> </span> [RegularExpression(<span class="str">@"^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$"</span>, ErrorMessage=<span class="str">"..."</span>)]</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum9"> </span> <span class="kwrd">public</span> <span class="kwrd">string</span> Phone { get; set; }</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum10"> </span> </pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum11"> </span> [CustomValidation(<span class="kwrd">typeof</span>(CustomerPhoneValidator), <span class="str">"CrossValidateHasPhoneWithPhone"</span>)]</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum12"> </span> <span class="kwrd">public</span> <span class="kwrd">bool</span> HasPhone { get; set; }</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum13"> </span> ...</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum14"> </span> }</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum15"> </span>}</pre> <!--CRLF--></div> </div> <p>In this case I have a separate attribute for the regular expression and the cross-property validation for demonstration purposes. That will result in two different errors at times. For a more user friendly experience, as long as you are writing custom validation logic for a property tied in with the<strong> [CustomValidation]</strong> attribute, you might want to move that format validation inside the custom validation logic so that you only return one error at a time from a single control value.</p> <h3>Server-Side Validation</h3> <p>Some kinds of validation are not appropriate to do on the client side. You may have data you need to look up on the back end that you don’t want to expose to the client that will drive the decision of whether a given chunk of data is valid or not. For the sample application, I added the ability to look up a customer status on a customer when a task is saved. If the customer status (which I don’t want exposed to the client so that it doesn’t get inadvertently displayed in the client) is marked as “DeadBeat” status, then I want to limit the number of billable hours I accrue for that customer. So at the point where I go to save a task on the back end, I need to look up the customer status and see how many hours have been added to the modified <strong>Task</strong> as child <strong>TimeEntries</strong> and decide whether to accept that task for update. If I don’t want to accept it, I can throw a <strong>ValidationException</strong> from the update method, and validation errors will be added to the entity in the client application and can be displayed in various ways. </p> <p>To facilitate this scenario, it did require a change to my object model. I talked briefly about the<strong> [Composition]</strong> attribute in the last article. In order to have the <strong>TimeEntries</strong> sent down with the <strong>Task</strong> even if they have not changed themselves (such as when a customer has just been assigned to the <strong>Task</strong>), I needed to switch to having the <strong>TimeEntries</strong> collection on the <strong>Task</strong> be a <strong>[Composition]</strong> relationship. When you do that, the <strong>TimeEntries</strong> become wholly owned by their parent <strong>Task</strong>, and you don’t submit updates to individual time entries the way the application was doing in the last couple articles. Now you just get updates to tasks, and those changes might involve changes to the discrete properties of the task, the assignment of a related customer (which is not a <strong>Composition</strong> relationship because customers can be independently queried and updated) or the addition/removal/change of a time entry within the child <strong>TimeEntries</strong> collection of the <strong>Task</strong>. You can check out the <strong>UpdateTask</strong> method in the domain service to see the way this altered the coding patterns. Basically you have to do some state detection yourself and call the appropriate parts of the data access API (Entity Framework in this case) to manage the inserts/updates/deletes of your child objects in a composition relationship.</p> <p>By going with a composition relationship, though, now all the child <strong>TimeEntries</strong> are sent down with a modified task and you can evaluate the package as a whole for server side validation. So the update and insert methods for <strong>Tasks</strong> call a helper method that first does the server side validation:</p> <div id="codeSnippetWrapper"> <div class="csharpcode" id="codeSnippet"> <pre class="alt"><span class="lnum" id="lnum1"> </span><span class="kwrd">private</span> <span class="kwrd">void</span> ValidateCustomerHours(Task task)</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum2"> </span>{</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum3"> </span> <span class="kwrd">if</span> (task.CustomerId.HasValue)</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum4"> </span> {</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum5"> </span> <span class="kwrd">int</span> customerId = task.CustomerId.Value;</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum6"> </span> <span class="kwrd">bool</span> timeAllowed = IsTotalTimeAllowed(customerId, task.TotalTime);</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum7"> </span> <span class="kwrd">if</span> (!timeAllowed)</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum8"> </span> <span class="kwrd">throw</span> <span class="kwrd">new</span> ValidationException(</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum9"> </span> <span class="str">"You cannot enter more than 10 hours per billing cycle for this customer."</span>);</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum10"> </span> }</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum11"> </span>}</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum12"> </span> </pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum13"> </span>[Invoke]</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum14"> </span><span class="kwrd">public</span> <span class="kwrd">bool</span> IsTotalTimeAllowed(<span class="kwrd">int</span> customerId, TimeSpan totalTime)</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum15"> </span>{</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum16"> </span> Customer relatedCustomer = ObjectContext.Customers.Where(c => c.CustomerId == customerId).FirstOrDefault();</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum17"> </span> <span class="kwrd">if</span> (relatedCustomer != <span class="kwrd">null</span> && relatedCustomer.Status == <span class="str">"Deadbeat"</span> </pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum18"> </span> && (totalTime > TimeSpan.FromHours(10)))</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum19"> </span> {</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum20"> </span> <span class="kwrd">return</span> <span class="kwrd">false</span>;</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum21"> </span> }</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum22"> </span> <span class="kwrd">return</span> <span class="kwrd">true</span>;</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum23"> </span>}</pre> <!--CRLF--></div> </div> <p>If I wrote the client so that it did not validate the max hours for a customer on the client side before sending the task to the back end for updating or inserting, this code would be invoked and would throw the <strong>ValidationException</strong> back to the client. On the client side, WCF RIA Services would add a <strong>ValidationError</strong> to the <strong>Task</strong>  and it could be displayed by the build in validation mechanisms of Silverlight Controls.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/brian.noyes/8-24-2010%2012-55-52%20PM_2.png"><img width="813" height="408" title="8-24-2010 12-55-52 PM" style="border:0px solid; display: inline;" alt="8-24-2010 12-55-52 PM" src="http://www.silverlightshow.net/Storage/Users/brian.noyes/8-24-2010%2012-55-52%20PM_thumb.png" /></a> </p> <h3>Async Validation through Invoke Methods</h3> <p>When it comes to validation, it is generally better to let the user know as early as possible when they have entered invalid data instead of waiting until a later point such as when they have tried to send that invalid data to the back end for persistence. A decent way to do this in WCF RIA Services is to use an <strong>[Invoke]</strong> method on your service. In addition to the CRUD methods you can expose on a WCF RIA Service, you can also add arbitrary methods that you mark with an <strong>[Invoke]</strong> attribute. These too will be exposed as service methods to the client and will show up on the corresponding domain context. They can pass different types than the main entities that the domain service is managing as entities, but there is a restricted set of types that you can pass as parameters and return types. The WCF RIA Services enumerates the types that can be used as parameters and return types on domain service methods.</p> <p>To support more immediate feedback to the user for the case of entering too many hours for a customer with bad status, I added the <strong>IsTotalTimeAllowed</strong> method that you can see in the code snippet in the previous section. That method is being used both internally by the server side validation, and can be called directly from the client as well. In the client side view model, at the point where the user has entered a new time entry, I can make a call to that service method to check whether the new time entry will exceed the max allowed hours.</p> <div id="codeSnippetWrapper"> <div class="csharpcode" id="codeSnippet"> <pre class="alt"><span class="lnum" id="lnum1"> </span>TimeEntry entry = popup.DataContext <span class="kwrd">as</span> TimeEntry;</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum2"> </span>...</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum3"> </span><span class="kwrd">if</span> (SelectedTask.CustomerId.HasValue)</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum4"> </span>{</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum5"> </span> TasksDomainContext context = <span class="kwrd">new</span> TasksDomainContext();</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum6"> </span> Action<InvokeOperation<<span class="kwrd">bool</span>>> action = <span class="kwrd">delegate</span>(InvokeOperation<<span class="kwrd">bool</span>> op)</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum7"> </span> {</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum8"> </span> ...</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum9"> </span> <span class="kwrd">if</span> (entry != <span class="kwrd">null</span>) SelectedTask.TimeEntries.Add(entry);</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum10"> </span> ...</pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum11"> </span> };</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum12"> </span> context.IsTotalTimeAllowed(SelectedTask.CustomerId.Value, </pre> <!--CRLF--> <pre class="alt"><span class="lnum" id="lnum13"> </span> SelectedTask.TotalTime + (entry.EndTime - entry.StartTime), action, <span class="kwrd">null</span>);</pre> <!--CRLF--> <pre class="alteven"><span class="lnum" id="lnum14"> </span>}</pre> <pre class="alteven"></pre> <!--CRLF--></div> </div> As you can see, the invoke method shows up on the domain context as a normal async service method. You can pass a callback delegate of type<strong> InvokeOperation<T></strong>, where T is the return type of the invoke method, and that callback will be invoked when the async call is complete. You get the same thread marshalling back to the UI thread that you do with <strong>Load</strong> and <strong>SubmitChanges</strong> operations, so you don’t have to do any thread marshaling yourself. <p>You can see the full implementation with some (crude) user prompting in the sample application in the download code.</p> <h3>Summary</h3> <p>The built in validation support in WCF RIA Services is one of the more compelling features that makes me want to use WCF RIA Services for most data-oriented situations in Silverlight. The ease of using data annotation attributes to express simple validation rules or custom validation attributes to tie in more complex validations covers a large number of validation scenarios nicely. Add to that the ability to invoke whatever logic you need from your domain service CRUD methods and Invoke methods on the back end and you have a nice end to end solution for handling validation. The fact that WCF RIA Services takes care of adding the validation errors to the entities on the client side and implements <strong>INotifyDataErrorInfo</strong> on those entities to participate nicely with the data binding features of Silverlight just rounds it all out into a very powerful part of WCF RIA Services.</p> <p>The complete code for this article <a href="http://www.silverlightshow.net/Storage/Sources/TaskManagerPart6.zip" target="_blank">can be downloaded here</a>.</p> <p><span style="font-size: 18px;">About the Author</span></p> <p>Brian Noyes is Chief Architect of IDesign, a Microsoft Regional Director, and Connected System MVP. He is a frequent top rated speaker at conferences worldwide including Microsoft TechEd, DevConnections, DevTeach, and others. He is 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> <p> </p> http://www.silverlightshow.net/items/WCF-RIA-Services-Part-6-Validating-Data.aspx editorial@silverlightshow.net (Brian Noyes ) http://www.silverlightshow.net/items/WCF-RIA-Services-Part-6-Validating-Data.aspx#comments http://www.silverlightshow.net/items/WCF-RIA-Services-Part-6-Validating-Data.aspx Thu, 26 Aug 2010 06:06:00 GMT WCF RIA Services Part 4 - Integrating with the Model-View-ViewModel Pattern <div style="border:1px solid #dddddd;padding-bottom: 5px; background-color: #f3f3f3; margin-top: 5px; padding-left: 10px; padding-top: 5px;"><strong><img alt="" width="128" height="97" style="width: 112px; float: right; height: 80px; margin-left: 10px;" src="http://www.silverlightshow.net/Storage/old_skool_cassette.png" />Watch recordings of Brian's WCF RIA Services webinars:</strong>   <ul> <li><a href="http://www.silverlightshow.net/shows/WCF-RIA-Services-Webinar-1.aspx">Querying & Updating Data From Silverlight Clients with WCF RIA Services</a> (Feb 03, 2011)</li> <li><a href="http://www.silverlightshow.net/shows/WCF-RIA-Services-Webinar-2.aspx">WCF RIA Services Validation</a> (Mar 17, 2011)</li> <li><a href="http://www.silverlightshow.net/shows/WCF-RIA-Services-Webinar-3.aspx">Secure and Personalize Your Silverlight App with WCF RIA Services</a> (May 26, 2011)</li> <li><a href="http://www.silverlightshow.net/shows/WCF-RIA-Services-Webinar-4.aspx">WCF RIA POCO Domain Services</a> (Sep 29, 2011)</li> </ul> </div> <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/Deep-dive-into-WCF-part-1-TDD.aspx">Deep Dive Into WCF series</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/Search.aspx?q=WCF&adv=true&tg=true&ro=0&t=1,2,3,5&r=10&o=1">See more articles on WCF</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/shows/Paging-WCF-Ria-Services-entities-in-MVVM-applications.aspx">WCF RIA Services Show</a> </li> <li style="padding-bottom: 5px;"><a href="http://www.silverlightshow.net/ebooks/wcf_ria_services.aspx">The WCF series is now available as a fully offline resource: </a></li> </ul> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/wcf_ria_services.aspx"><img style="border:0px solid;" alt="WCF RIA Services Ebook" src="http://www.silverlightshow.net/Storage/wcf_ria_ebook_thumb0.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>This article is Part 4 of the series WCF RIA Services.</p> <h3>Introduction</h3> <p>The Model-View-ViewModel pattern (MVVM) is a very popular approach for building more loosely coupled Silverlight and WPF applications. I won’t attempt to full define and explain the pattern here, but will give a quick explanation of what it is about and why you would want to use it. At a high level, MVVM is an alternative or evolution of MVC and MVP patterns, but taking full advantage of the rich data binding, commands, and behaviors that we have available to us in Silverlight and WPF. The view model’s primary responsibility is to offer up state to the view in the way the view wants to see it. It exposes properties that the view can easily bind to that let the view display the data it needs and to also hook up commands and behaviors that point back to the view model to invoke interaction logic that the view model encapsulates. The view model is all about containing and manipulating the data that the view needs and providing the interaction logic to support the view. The view model acts as a translator from the complex world of the overall application model to the specific set of data that a single view needs, structured in the way the view needs to display it. Structurally, you typically set the view’s DataContext equal to an instance of the view model so that the view can easily bind to the exposed properties of the view model. There are many ways to get this hook up done.</p> <p>The motivations for using it include the fact that it allows you to work on the view and the view model mostly in isolation, facilitating developer/designer workflow. Additionally, by separating your interaction logic into the view model, you can more easily unit test that logic because it is not tightly woven with the UI itself. And finally, the pattern just provides a clean separation of responsibility so the view can just be about the structure and visual behavior of what you see on the screen, and the view model can just be about the data and logic surrounding the data that the view needs to support it. For more in depth coverage, I recommend you read Josh Smith’s excellent <a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx" target="_blank">article on MVVM</a>, as well as the guidance being developed by the Microsoft patterns & practices Prism team in Prism 4 at <a href="http://prism.codeplex.com/">http://prism.codeplex.com/</a>. Prism 4 is due out in the September/October timeframe but there are already public drops in the downloads section on CodePlex.</p> <p>So now let’s see how MVVM fits with WCF RIA Services. The starting point code for this article will be the sample code from Part 3 of the series, which <a href="http://www.silverlightshow.net/Storage/Sources/TaskManagerPart3.zip" target="_blank">you can download here</a>. You can download the <a href="http://www.silverlightshow.net/Storage/Sources/TaskManagerPart4.zip" target="_blank">finished code for this article here</a>.</p> <h3>Step 1: Factor out a view model</h3> <p>In the <a href="http://www.silverlightshow.net/items/WCF-RIA-Services-Part-3-Updating-Data.aspx" target="_blank">last article</a>’s version of the TaskManager application, I was already starting to have a fair amount of code building up in the code behind of the view (the <strong>MainPage</strong> user control), even with such a simple application. The first step is to factor that code out into a view model. Create a new class named <strong>TasksViewModel</strong> in the project. Often a good way to get started defining your view model is to analyze the view and determine what properties would be needed to support it. The image below shows the form as it is currently defined. To clean things up a bit, I’ve replaced the two <strong>TextBoxes</strong> for date input at the top with <strong>DatePickers</strong>, removed the unused properties on the Task from the <strong>DataGrid</strong>, and reordered the columns to look a little better.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/brian.noyes/figure1_2.png"><img width="763" height="153" title="figure1" style="border:0px solid; display: inline;" alt="figure1" src="http://www.silverlightshow.net/Storage/Users/brian.noyes/figure1_thumb.png" /></a> </p> <p>By looking at the UI design, you can identify 6 properties the view model should expose to support this view: two <strong>DateTime</strong> properties for lower and upper dates for a search; three commands to support searching by date, adding a task, and saving changes; and one Tasks collection. In its simplest form, that would look like this:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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> TasksViewModel</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> DateTime LowerSearchDate { 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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> DateTime UpperSearchDate { 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> ICommand SearchByDateCommand { 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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> ICommand AddTaskCommand { 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> ICommand SaveChangesCommand { 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> IEnumerable<Task> Tasks { 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>However, you generally need to implement <strong>INotifyPropertyChanged</strong> on your view model which requires the expanded syntax for each property so that the UI can stay fresh through its data bindings if the bound property on the view model changes, so each property definition should look more like this in its full form, except possibly the private set properties that the view model sets once and does not change.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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> TasksViewModel : INotifyPropertyChanged</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> PropertyChangedEventHandler PropertyChanged = <span style="color: #0000ff;">delegate</span> { };</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> DateTime _LowerSearchDate;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> DateTime LowerSearchDate</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> _LowerSearchDate;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">value</span> != _LowerSearchDate)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> _LowerSearchDate = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> PropertyChanged(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span> PropertyChangedEventArgs(<span style="color: #006080;">"LowerSearchDate"</span>));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> }</pre> <!--CRLF--></div> </div> <p>To support the <strong>ICommand</strong> properties, you will need a decent command implementation. I’ve included a simple <strong>RelayCommand</strong> implementation, but normally in real projects I use the <strong>DelegateCommand</strong> from Prism. </p> <p>A view model is all about managing the data needed by a view, and a <strong>DomainContext</strong> in RIA Services is all about providing and tracking changes to the data, so a simple approach to using RIA Services with MVVM is to simply use a <strong>DomainContext</strong> within your view model.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span>TasksDomainContext _Context = <span style="color: #0000ff;">new</span> TasksDomainContext();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> TasksViewModel()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> SearchByDateCommand = <span style="color: #0000ff;">new</span> RelayCommand<<span style="color: #0000ff;">object</span>>(OnSearchByDate);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> AddTaskCommand = <span style="color: #0000ff;">new</span> RelayCommand<<span style="color: #0000ff;">object</span>>(OnAddTask);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> SaveChangesCommand = <span style="color: #0000ff;">new</span> RelayCommand<<span style="color: #0000ff;">object</span>>(OnSaveChanges);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> Tasks = _Context.Tasks;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (!DesignerProperties.IsInDesignTool)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> _Context.Load(_Context.GetTasksQuery());</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>Here I have made the <strong>TasksDomainContext</strong> a member of the view model, and initialized the commands in the constructor to point to methods within the view model. The Tasks property exposed by the view model just holds a reference to the Tasks entity collection exposed by the domain context, which will raise <strong>INotifyCollectionChanged</strong> events to keep the view fresh when the collection changes, which will happen on the initial load, when you add Tasks, and when <strong>SubmitChanges</strong> completes and has updated entities from the back end. Notice the use of the <strong>DesignerProperties.IsInDesignTool</strong> property to prevent calling Load in the designer, which would break it.</p> <p>Next is to move the methods that were in the code behind of <strong>MainPage</strong> into the view model. I’ve cleaned them up a bit in the process too. Note that the search method now leverages the deferred execution I talked about in Part 3, making the <strong>GetTasksByStartDate</strong> domain service method unnecessary since the client can specify that search expression itself. I’ve also moved the creation of a new Task into a simple popup <strong>ChildWindow</strong> so you can actually edit the values. Note the commend in the code below – showing a dialog from a view model is really a no-no, just doing it here because the focus is on RIA Services, not on full MVVM patterns. </p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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> OnSearchByDate(<span style="color: #0000ff;">object</span> param)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> _Context.Tasks.Clear();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> EntityQuery<Task> query = _Context.GetTasksQuery();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> LoadOperation<Task> loadOp = _Context.Load(query.Where(t => t.StartDate >= LowerSearchDate && t.StartDate <= UpperSearchDate));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> OnAddTask(<span style="color: #0000ff;">object</span> param)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #008000;">// Generally don't want to do this for testability reasons</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #008000;">// Simplification because MVVM structuring is not the focus here</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #008000;">// See Prism 4 MVVM RI for a cleaner way to do this</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> AddTaskView popup = <span style="color: #0000ff;">new</span> AddTaskView();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> popup.DataContext = <span style="color: #0000ff;">new</span> Task();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> popup.Closed += <span style="color: #0000ff;">delegate</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (popup.DialogResult == <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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> Task newTask = popup.DataContext <span style="color: #0000ff;">as</span> Task;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (newTask != <span style="color: #0000ff;">null</span>) _Context.Tasks.Add(newTask);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum21" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> popup.Show();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum25" 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-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; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> OnSaveChanges(<span style="color: #0000ff;">object</span> param)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> _Context.SubmitChanges();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>At this point you have you have a functioning view model, now I’ll clean up the view to work with the view model.</p> <h3>Step 2: Hook up the view to the view model</h3> <p>From Part 1, the view was using the <strong>DomainDataSource</strong> that was generated from the drag and drop. If you want a clean MVVM design, you will unfortunately have to pass on using <strong>DomainDataSource</strong>. That object is effectively putting state management and query logic into the XAML itself, which violates the clean separation of responsibilities followed in MVVM.</p> <p>So basically I took the existing view, deleted out the <strong>DomainDataSource</strong>, and added appropriate bindings to each of the controls to bind to the exposed view model properties as shown below. For a top level view like this, constructing the view model in the XAML to set it as the data context is a simple way to get the view’s data context set to an instance of the view.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">UserControl</span> <span style="color: #ff0000;">x:Class</span><span style="color: #0000ff;">="TaskManager.MainPage"</span> ...<span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">UserControl.DataContext</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">local:TasksViewModel</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">UserControl.DataContext</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum5" 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;">Background</span><span style="color: #0000ff;">="White"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">sdk:DataGrid</span> <span style="color: #ff0000;">ItemsSource</span><span style="color: #0000ff;">="{Binding Tasks}"</span> ...<span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">Command</span><span style="color: #0000ff;">="{Binding SearchByDateCommand}"</span> ...<span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">Command</span><span style="color: #0000ff;">="{Binding AddTaskCommand}"</span> ... <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">Command</span><span style="color: #0000ff;">="{Binding SaveChangesCommand}"</span> ... <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">sdk:DatePicker</span> <span style="color: #ff0000;">SelectedDate</span><span style="color: #0000ff;">="{Binding LowerSearchDate}"</span> ... <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">sdk:DatePicker</span> <span style="color: #ff0000;">SelectedDate</span><span style="color: #0000ff;">="{Binding UpperSearchDate}"</span> ... <span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">UserControl</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>Lastly, remove all the code from the code behind of the view, since it is no longer being used (all the button click handlers were removed in the process of hooking of the commands with bindings to the view model properties).</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span> MainPage : UserControl</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> MainPage()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> InitializeComponent();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <h3>Summary</h3> <p>The simplest way to use WCF RIA Services with the MVVM pattern is to stop using the <strong>DomainDataSource</strong> in your views and to use a domain context as the repository of data for your view models. You can still leverage the drag and drop Data Sources window features, you just have to do a little clean up to delete off the <strong>DomainDataSource</strong> after the drop and touch up the bindings a little. </p> <p>There are two downsides to the approach as I have shown it here: testability and separation of concerns. One of the benefits of the MVVM pattern is supposed to be unit testability. But with a concrete type dependency on the domain context type in your view model, you are out of luck for mocking out that dependency. There are two approaches possible to address this:</p> <ol> <li>Use dependency injection to provide the domain context to the view model, and create a mock <strong>DomainClient</strong> and pass it to the <strong>DomainContext</strong>. This allows your view model to keep using the full functionality of the <strong>DomainContext</strong>, but you are able to mock out the calls to the service underneath the <strong>DomainContext</strong>. This approach is outlined <a href="http://www.nikhilk.net/NET-RIA-Services-ViewModel-Pattern-2.aspx" target="_blank">in this post</a>. I’ll be providing an example in Part 8 of this series, which is focused on testability. </li> <li>Factor out the <strong>DomainContext</strong> to a repository service that defines an interface similar to the <strong>DomainContext</strong> API and consume that from the view model. This would allow you to mock your repository service that contains the domain context. It would also address the separation of concerns problem, because then you would be separating the implementation choice of using RIA Services from the view model, which should really be separated. However, you would give up a lot of flexibility in the view model and it would not be an easy repository implementation. </li> </ol> <p>Neither of these approaches is particularly easy. I’ll cover them in more detail later in part 8, and may blog some more on this topic as well. That’s all for now. You can download the finished code <a href="http://www.silverlightshow.net/Storage/Sources/TaskManagerPart4.zip" target="_blank">for this article here</a>. See you next time.</p> <p><span style="font-size: 18px;">About the Author</span></p> <p>Brian Noyes is Chief Architect of IDesign, a Microsoft Regional Director, and Connected System MVP. He is a frequent top rated speaker at conferences worldwide including Microsoft TechEd, DevConnections, DevTeach, and others. He is 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 http://briannoyes.net.</p> http://www.silverlightshow.net/items/WCF-RIA-Services-Part-4-Integrating-with-the-Model-View-ViewModel-Pattern.aspx editorial@silverlightshow.net (Brian Noyes ) http://www.silverlightshow.net/items/WCF-RIA-Services-Part-4-Integrating-with-the-Model-View-ViewModel-Pattern.aspx#comments http://www.silverlightshow.net/items/WCF-RIA-Services-Part-4-Integrating-with-the-Model-View-ViewModel-Pattern.aspx Tue, 03 Aug 2010 02:51:00 GMT Data Driven Applications with MVVM Part III: Validation, Bringing the UI Closer <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> <p><span style="font-size: 12px; font-weight: normal;"><a href="http://www.silverlightshow.net/ebooks/data_driven_mvvm.aspx">This series is now available as a fully offline resource:</a></span></p> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/data_driven_mvvm.aspx"><img style="border:0px solid;" alt="Data Driven Applications with MVVM Ebook" src="http://www.silverlightshow.net/Storage/mvvm_ebook_thumb_small.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($0.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><em><strong>This article is compatible with the latest version of Silverlight.</strong></em></p> <h3>Introduction</h3> <p>In this short series of articles I’ll cover what MVVM is and how to use it in practice, how to solve issues when applying this pattern and how to take advantage from it.</p> <p>In the previous articles we created a simple master details scenario with the MVVM pattern. We used mock and live data sources with WCF, we created unit tests, we used Messaging from the MVVM Light Toolkit.</p> <p>By now, we have an application that communicates with a server, and we know how to send data back to a server. This raises another questions like, are we sending back valid data?</p> <h3>Validation in MVVM</h3> <p>Let’s think about this a little bit. How and what do we want to validate? Let’s see. We have an Author, a Title, and a Price. Well we can set the price property to a negative value, which is probably not a valid scenario. In Silverlight 3 we can do validation in property setters. What we basically do is throwing exceptions in the setter if the value is not valid. This kind of validation has two problems.</p> <ol> <li>You throw exceptions to validate in property setters…. well… yeah… </li> <li>You can’t support full entity validation. You need to do workarounds to support that scenario. </li> </ol> <p>Well, in Silverlight 4 we have an IDataErrorInfo interface, that supports validation, without throwing exceptions. Also you can centralize your validation rules.</p> <p>Let’s validate the Price property! If the price is lower than zero, then this value is invalid.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #008000;">//Modify the BookDetailsViewModel class to implement IDataErrorInfo</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> BookDetailsViewModel : ViewModelBase, IDataErrorInfo</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span><span style="color: #008000;">//Implement IDataErrorInfo</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Error</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> get { <span style="color: #0000ff;">return</span> <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-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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> <span style="color: #0000ff;">this</span>[<span style="color: #0000ff;">string</span> columnName]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (columnName == <span style="color: #006080;">"Price"</span>)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #008000;">//We have a validaton error</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (Price < 0) <span style="color: #0000ff;">return</span> <span style="color: #006080;">"Price must be positive"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #008000;">//Everthing is okay</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> <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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>Also you have to modify the binding for the textbox displaying the price. You need to add the <em>ValidatesOnDataErrors=True</em> option, to enable the use of IDataErrorInfo based validation.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">TextWrapping</span><span style="color: #0000ff;">="Wrap"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">d:LayoutOverrides</span><span style="color: #0000ff;">="Height"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="15,0"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding Price, Mode=TwoWay, ValidatesOnDataErrors=True}"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--></div> </div> <p>You can create you own validation handler classes and centralize the validation logic as much you want. However this kind of validation supports synchronous validation only. Which means, the binding happens, the validation happens and that’s it. If there is a later change in the validation state, this scenario cannot be applied. Let me give you an example. You have the Title property. Let’s assume we have an Update operation. When we update a book, we have to make sure, that the new title we enter is not the same as any other title. The title should be unique (well not in real life, but right now it does :D). You can’t validate this one on the client side! You have thousands of books in the database. You have to run a check against a huge amount of data and it might take more than a second. Which means that when the user sets the title property, we should let him do it. But immediately we should run an asynchronous check to validate the title. If the check’s result is that the title entered is not valid, then we have to indicate it somehow.</p> <p>Also what if I need more detailed error report, not just a simple string? What if a change in a property changes another property bound to the UI and now the other property’s value is invalid? I should indicate it somehow. </p> <p>IDataErrorInfo does not support these scenarios. Fortunately there is an other interface that supports all these scenarios. It’s called INotifyDataErrorInfo.</p> <p>This is a little bit more complex, so let’s go step by step.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span>public interface INotifyDataErrorInfo</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> bool HasErrors { get; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> event EventHandler<span style="color: #0000ff;"><</span><span style="color: #800000;">DataErrorsChangedEventArgs</span><span style="color: #0000ff;">></span> ErrorsChanged;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> IEnumerable GetErrors(string propertyName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>There are two very important members here The ErrorsChanged event, and the GetErrors method!</p> <p>GetErrors() returns a list of errors of a specific property, it can be a list of strings, or a list of custom objects, it’s up to us. The ErrorsChanged event should be raised whenever a new validation error should be added, or a validation error should be removed. How you handle the validation errors’ list is pretty much up to you.</p> <p>Let’s implement it. However this will need a lot of additional code that is not specific to a certain ViewModel, so most of the code, I’ll put into an extended ValidatingViewModelBase class which implements INotifyDataErrorInfo interface and inherits ViewModelBase.</p> <p>First I’ll need a list that can contain the errors for each property.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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> ValidatingViewModelBase : ViewModelBase, INotifyDataErrorInfo</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #008000;">//Key is propertyName, value is list of validation errors</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;">protected</span> Dictionary<<span style="color: #0000ff;">string</span>, List<<span style="color: #0000ff;">string</span>>> errorList = <span style="color: #0000ff;">new</span> Dictionary<<span style="color: #0000ff;">string</span>, List<<span style="color: #0000ff;">string</span>>>();</pre> <!--CRLF--></div> </div> <p>The key of the dictionary is the name of the property. The Value is a list of errors represented by simple strings.</p> <p>I have an error if I have something in the Values inner collection.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span> HasErrors</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #008000;">//If there is any validation error</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> errorList.Values.Count > 0;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>Now I need to implement the GetErrors() method:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span><span style="color: #008000;">/// Gets the list of validation errors for a 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span><span style="color: #008000;">/// <param name="propertyName">Name of the propety</param></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> System.Collections.IEnumerable GetErrors(<span style="color: #0000ff;">string</span> propertyName)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> CheckErrorCollectionForProperty(propertyName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #008000;">//return related validation errors for selected property.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> errorList[propertyName];</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">void</span> CheckErrorCollectionForProperty(<span style="color: #0000ff;">string</span> propertyName)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #008000;">//First time to get the validation errors of this property.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (!errorList.ContainsKey(propertyName))</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> errorList[propertyName] = <span style="color: #0000ff;">new</span> List<<span style="color: #0000ff;">string</span>>();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>The <em>CheckErrorCollectionForProperty</em>() method’s responsibility is to check whether the property is already registered in the error collection. If not, than it should do it, and assign an empty string list as a value, to store the list of validation errors. The GetErrors() method now returns with the list of errors associated with the property name.</p> <p>Now we need ways to add and remove validation errors.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span><span style="color: #008000;">/// Add a validation error to a property name.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span><span style="color: #008000;">/// <param name="propertyName">Name of the property</param></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span><span style="color: #008000;">/// <param name="error">The validation error itself</param></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">void</span> AddError(<span style="color: #0000ff;">string</span> propertyName, <span style="color: #0000ff;">string</span> error)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> CheckErrorCollectionForProperty(propertyName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> errorList[propertyName].Add(error);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> RaiseErrorsChanged(propertyName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum14" 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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span><span style="color: #008000;">/// Remove a specific validation error registered to a property name.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum16" 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-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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span><span style="color: #008000;">/// <param name="propertyName">Name of the property</param></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span><span style="color: #008000;">/// <param name="error">The validation error itself</param></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">void</span> RemoveError(<span style="color: #0000ff;">string</span> propertyName, <span style="color: #0000ff;">string</span> error)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (errorList[propertyName].Contains(error))</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> errorList[propertyName].Remove(error);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> RaiseErrorsChanged(propertyName);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum25" 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-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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum28" 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-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; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span><span style="color: #008000;">/// Notifies the UI of validation error state change</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum30" 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-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; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span><span style="color: #008000;">/// <param name="propertyName">The name of the property that is validated</param></span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">void</span> RaiseErrorsChanged(<span style="color: #0000ff;">string</span> propertyName)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum33" 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-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; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (ErrorsChanged != <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-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; padding-top: 0px;border-style: none;"><span id="lnum35" 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-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; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> </span> ErrorsChanged(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span> DataErrorsChangedEventArgs(propertyName));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>The Add method makes sure that there is a list associated with the property name, then adds the error string to this collection. One last thing to do there, is to notify the UI, that something has changed related to the validation error of this property.</p> <p>The Remove method removes the specific error from the error collection.</p> <p>The infrastructure is ready by now, we can use it. The BookDetailsViewModel now inherits the ValidatingViewModelBase class.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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> BookDetailsViewModel : ValidatingViewModelBase, IDataErrorInfo</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Title</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> book.Title;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> book.Title = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> RaisePropertyChanged(<span style="color: #006080;">"Title"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> ValidateTitle(<span style="color: #0000ff;">value</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #008000;">//Validate Title Property</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> ValidateTitle(<span style="color: #0000ff;">string</span> title)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #008000;">//Check server side data for validation result</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> bookDataSource.CheckIfTitleAvailable(<span style="color: #0000ff;">this</span>.BookID, title);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum23" 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-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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #008000;">//Callback from the server validation process</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;">void</span> bookDataSource_CheckIfTitleAvailableCompleted(<span style="color: #0000ff;">object</span> sender, CheckIfTitleAvailableCompletedEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> <span style="color: #008000;">//Validation Logic</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (!e.IsAvailable)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> <span style="color: #008000;">//Invalid</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> AddError(<span style="color: #006080;">"Title"</span>, <span style="color: #006080;">"The Book with that title already exits!"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum33" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum35" style="color: #606060;"> </span> <span style="color: #008000;">//Valid</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum36" style="color: #606060;"> </span> RemoveError(<span style="color: #006080;">"Title"</span>, <span style="color: #006080;">"The Book with that title already exits!"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> </span> }</pre> <!--CRLF--></div> </div> <p>In the setter of the Title property I call the ValidateTitle() method. The validate Title uses the bookDataSource, to check on the server if the title is available for this item, or another book already has it. (I made minor changes, to enable an extra WCF service operation. You can check it in the VS solution posted with this article).</p> <p>Now in the completed event handler I check if the title is available. If not, then I call the previously created AddError() method. If it’s available, I call the RemoveError() method. This is happening absolutely asynchronously. The AddError() and the RemoveError() methods raise the ErrorsChanged event, so the UI gets notified also asynchronously about the change in the state of the validation.</p> <p>We have to indicate on the binding, that we are using this kind of validation mechanism. This is done through the <em>ValidatesOnNotifyDataErrors=True</em> option</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><TextBox Grid.Column=<span style="color: #006080;">"1"</span> TextWrapping=<span style="color: #006080;">"Wrap"</span> d:LayoutOverrides=<span style="color: #006080;">"Height"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> VerticalAlignment=<span style="color: #006080;">"Center"</span> Margin=<span style="color: #006080;">"15,0"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> Text=<span style="color: #006080;">"{Binding Title, Mode=TwoWay, ValidatesOnNotifyDataErrors=True}"</span>/></pre> <!--CRLF--></div> </div> <p>That’s it, you have asynchronous validation across tiers.</p> <h3>Bringing the UI and the ViewModels more closely</h3> <p>If you start to work with MVVM, you can get the taste of it very soon. You’ll really like it, but even in the beginnings there will be battles, you’ll have to fight. The problem will emerge mostly in the area of integrating the ViewModel with the specific View more closely. For example, how do you plan to display messages, or dialog boxes? What if you want to do something in the ViewModel as soon as a Storyboard ends? This is the area where behaviors, actions, and triggers can help you a lot.</p> <p>For me, among many others, there are two very important and useful behavior to use with MVVM, which I’d like to introduce you now.</p> <p><strong>1. The EventToCommand behavior.</strong></p> <p>What if, I don’t want to click the load data button in my application? What if I want to load the data as soon as the application starts. (I know what is in your mind right now, please don’t ever put code in the ViewModel’s constructor that calls a real data source (WCF Service, etc…) That would make blendability a nightmare). The EvenToCommand behavior located in the MVVM Light Toolkit can help you a lot. You can attach it to a control, tell which event you are waiting for, and as soon as that event fires, the associated command object gets invoked.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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;">Background</span><span style="color: #0000ff;">="White"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">i:Interaction.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: 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">i:EventTrigger</span> <span style="color: #ff0000;">EventName</span><span style="color: #0000ff;">="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: #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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">GalaSoft_MvvmLight_Command:EventToCommand</span> <span style="color: #ff0000;">Command</span><span style="color: #0000ff;">="{Binding LoadBooksCommand}"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">i: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: #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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">i:Interaction.Triggers</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> As soon as the Grid’s Loaded event happens, the LoadBooksCommand gets invoked. <p><strong>2. The VSMChangerBehavior</strong></p> <p>Imagine you have a special menu, panel, whatever. In some cases it’s visible, in some cases it’s not. Very easy you say, let’s create a bool property in the ViewModel, and use a converter to convert the bool value to Visibility for the UI. That definitely works. But you just tied the hands of your designer. What if his plan is to slide the panel in and out for the true and false values? What you should really do, is to define Visual States for the Visible and NonVisible states and use the VisualStateManager to move from one state to the other. Now the designer can do whatever he wants in these Visual States. What a big difference in flexibility, huh? But now you have a problem. You have a bool value, or an enum in the ViewModel. Now you have to write code on the UI, to check these states. Or let the view model “know” about the view and control it like a Controller. This is not something you want. This is where the VSMChangerBehavior created by Andras Velvart can help you out. You define states (by convention) for you enums, and let the VSMChangerBehavior do the transitions automatically, as the properties in the ViewModel change.</p> <p>If you want to know more about this behavior, go and visit <a href="http://www.silverlightshow.net/items/A-Designer-friendly-Approach-to-MVVM-Part-I.aspx">silverlightshow</a>.</p> <p>There are a lot of other behaviors / actions you should be familiar with, like GoToStateAction, CallMethodAction, ControlStoryboardAction, DataStateBehavior. These can help you a lot. </p> <h3>Final thoughts</h3> <p>Also there are other concepts you should consider, like I prefer to manage an IsBusy property in the ViewModel, so I have the option to indicate the user if there is something going on behind. Or for your collections you should implement paging using a PagedCollectionView class. To make your application and your components really flexible and loosely coupled, you might want to get familiar with MEF (for extensibility) or Unity (IoC container). So there is still a long way to go, but I hope these 3 articles are enough to get you started.</p> <p>Today MVVM is close to be called a mature pattern. Let me rephrase it. A well supported pattern. I think if it comes to business application development, this pattern definitely should be used. Silverlight 4 is now a very good platform on which you can develop Line of Business Applications.</p> <p><a href="http://www.silverlightshow.net/Storage/Sources/MVVMProductsDemoPart3.zip">Download the source code</a></p> http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-III.aspx editorial@silverlightshow.net (Zoltan Arvai ) http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-III.aspx#comments http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-III.aspx Thu, 17 Jun 2010 07:29:00 GMT Data Driven Applications with MVVM Part II: Messaging, Unit Testing, and Live Data Sources <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> <p><span style="font-size: 12px; font-weight: normal;"><a href="http://www.silverlightshow.net/ebooks/data_driven_mvvm.aspx">This series is now available as a fully offline resource:</a></span></p> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/data_driven_mvvm.aspx"><img style="border:0px solid;" alt="Data Driven Applications with MVVM Ebook" src="http://www.silverlightshow.net/Storage/mvvm_ebook_thumb_small.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($0.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><em><strong>This article is compatible with the latest version of Silverlight.</strong></em></p> <h3>Introduction</h3> <p>In this short series of articles I’ll cover what MVVM is and how to use it in practice, how to solve issues when applying this pattern and how to take advantage from it.</p> <p>In the previous article we discussed what MVVM is and why it matters. In this article we’ll try to benefit from the pattern and talk about the issues you have to battle through when working with MVVM. Our sample application was able to pull some data from a model, and display it on the screen in a master-detail fashion. </p> <p>Now what we want is to add extra functionalities to our application, like being able to remove an item by clicking on a remove button, located next to each item in the ListBox. </p> <h3>Adding Remove functionality – Messaging</h3> <p>So here is the deal. I want to place a button displaying an X, next to each of the books in the ListBox. When I click on the remove button, the associated Book gets deleted! However this seems a very straightforward task, you’ll see very shortly, that it isn’t. Let’s think this trough a bit. </p> <p>We want to call a remove operation when we click the remove button. The remove button is in the DataTemplate, its DataContext is a BookDetailsViewModel instance. If I want this functionality, the Remove button’s command property should be bound to a RemoveBookCommand defined in the BookDetailsViewModel class. This means that I’ll have to write a Remove() method in this class. Right now the BookDetailsViewModel class represents the necessary data of a single book. This seems problematic. Why? Because when I remove an item:</p> <ol> <li>I need to persist the changes in the data store. </li> <li>I need to refresh my ListBox containing all those books! </li> </ol> <p>Let’s see the first. I’m going to need a reference to the DataSource, so I can persist the changes in the data store. I don’t have this reference right now. I can add it though, however it seems a bit strange yet, since removing an item from a list is not the responsibility of that single item. You remember the single responsibility principle? Are you sure this should be controlled by the BookDetailsViewModel class? Yeah, I don’t think so either.</p> <p>What about the second one? On the BooksView UserControl, I need to refresh the ListBox, which has its ItemsSource property set to the Books property, defined in the BooksViewModel. I don’t have a reference to that ViewModel in my BookDetailsViewModel! I could add it, but then again, the single responsibility principle. Not to mention that it would increase complexity AND here is what really is a problem, it would increase the level of dependency between the ViewModels. However doing  this is not illegal, but it’s definitely not something I would like to do.</p> <p>Also I could add a third problem, which right now does not concern us, but it could definitely be an issue. Maybe another part of the application, another ViewModel wants to know if an item gets removed by the application. Maybe an other module!</p> <p>If we want to address this issue, we immediately try to think of some sort of a static or singleton solution. Don’t think too much, we have a solution prepared for us. The MVVM Light Toolkit, which we used in our base application, provides us a Messenger class. This is a singleton object and you can use it to send messages for different subscribers.</p> <p>From any ViewModel, you can subscribe for a specific type of message. If someone sends that specific type of message, everybody who subscribed for that type of message will receive it. You can send very simple type of messages, like a string, or GenericMessage<T>s. However I prefer to create a custom message class for every single message type / case.</p> <p>So here is what I want. I will send a message from the BookDetailViewModel, and tell the world that this specific item should be removed, and let the rest of the world worry about it! :)</p> <p>Let’s add the extras to the BookDetailsViewModel. First let’s create the RemoveBookMessage class:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">namespace</span> MVVMProductsDemo.Messages</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> RemoveBookMessage : MessageBase</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> BookDetailsViewModel Book { 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> RemoveBookMessage(BookDetailsViewModel bookToRemove)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.Book = bookToRemove;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>Now let’s add commanding and message sending to the BookDetailsViewModel class:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> RelayCommand removeBookCommand;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> RelayCommand RemoveBookCommand</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> get { <span style="color: #0000ff;">return</span> removeBookCommand; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> RemoveBook()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> Messenger.Default.Send<RemoveBookMessage>(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;">new</span> RemoveBookMessage(<span style="color: #0000ff;">this</span>));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span><span style="color: #008000;">//This one goes in the constructor</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span>removeBookCommand = <span style="color: #0000ff;">new</span> RelayCommand(RemoveBook);</pre> <!--CRLF--></div> </div> <p>Now everybody, who wants to know about the book removal, should subscribe! Let’s change the BooksViewModel’s constructor!</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> BooksViewModel(IBookDataSource bookDataSource)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.bookDataSource = bookDataSource;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (bookDataSource != <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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> bookDataSource.LoadBooksCompleted += <span style="color: #0000ff;">new</span> EventHandler<BooksLoadedEventArgs>(bookDataSource_LoadBooksCompleted);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> bookDataSource.RemoveBookCompleted += <span style="color: #0000ff;">new</span> EventHandler<OperationEventArgs>(bookDataSource_RemoveBookCompleted);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> loadBooksCommand = <span style="color: #0000ff;">new</span> RelayCommand(LoadBooks);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> Messenger.Default.Register<RemoveBookMessage>(<span style="color: #0000ff;">this</span>, RemoveBook);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>As you can see the Register() method needed a parameter of type Action<RemoveBookMessage>. This is point to a callback method that runs when a message is received.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> RemoveBook(RemoveBookMessage message)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #008000;">//Remove item from collection!</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> Books.Remove(message.Book);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #008000;">//Remove item from data store</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> bookDataSource.RemoveBook(message.Book.BookID);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span><span style="color: #0000ff;">void</span> bookDataSource_RemoveBookCompleted(<span style="color: #0000ff;">object</span> sender, OperationEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (e.Error != <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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #008000;">//Do dg.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> So now, our ViewModels are ready. Also the IBookDataSource provides a way to remove the item from the data store. We just need to modify a view. In some scenarios you’d want to defined a separate UserControl as a special view, and use it as a DataTemplate. However that is not necessary. We can just create a simple ItemTemplate here. <p>Let’s change the ListBox in the BooksView.xaml:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">ListBox</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="lboxBooks"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="8,8,0,29"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="129"</span> <span style="color: #ff0000;">ItemsSource</span><span style="color: #0000ff;">="{Binding Books}"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #ff0000;">SelectedItem</span><span style="color: #0000ff;">="{Binding SelectedBook, Mode=TwoWay}"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">ListBox.ItemTemplate</span><span style="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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">StackPanel</span> <span style="color: #ff0000;">Orientation</span><span style="color: #0000ff;">="Horizontal"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="X"</span> <span style="color: #ff0000;">Command</span><span style="color: #0000ff;">="{Binding RemoveBookCommand}"</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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding Title}"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="8,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: #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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <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; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" 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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">ListBox.ItemTemplate</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">ListBox</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> <p>As you can see, by clicking the button, you’ll invoke the RemoveBookCommand, which will invoke the RemoveBook() method, which sends a RemoveBookMessage. On the other side the subscribers for this specific type of message will handle it accordingly. Remove it from the collection and the data store as well. However Messaging is mostly useful when communicating between different modules. So if you use it between different ViewModels, be careful, not to overuse it, since it can lead to a “what the hell is happing right now” situation.</p> <p>By now we have tons of functionality! I’m getting worried about later changes to this code base. Will my application still work, if I do minor changes? This is where Unit Testing can help you a lot! I told you, MVVM architecture is really testable. So let’s write some unit tests!</p> <h3>Unit testing MVVM</h3> <p>Well Silverlight Unit Test projects are not default in Visual Studio 2010. It’s part of the Silverlight Toolkit. So if you want to do unit testing, you should download it from <a href="http://silverlight.codeplex.com/releases/view/43528">here</a>. After you install the toolkit, you’ll have a new project type called Silverlight Unit Test Application. The Project Template will add a new page (or web project) for the unit tests. In the Unit Test project you’ll have to reference both the Model and the Demo Project.</p> <p>There is a couple of things worth mentioning here. Most of the ViewModels work asynchronously, so we have to keep that in mind, when writing tests! In order to support this scenario, we’ll use a special base class for our TestClass, called SilverlightTest. Our TestMethod will be decorated with the AsynchronousAttribute so the framework knows how to handle it. We’ll use our mock data sources (since we don’t use real data sources in unit tests). To handle asynchronous callbacks we’ll use the EnqueueXXX methods. Let’s create a test for the LoadBook operation.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">namespace</span> MVVMProductsDemo.UnitTests</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> [TestClass]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Tests : SilverlightTest <span style="color: #008000;">//Note that the base class is SilverlightTest</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> [TestMethod]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> [Asynchronous] <span style="color: #008000;">//Indicate that this test will include asynchronous operations</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> LoadBook()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #008000;">//Flag to indicate that the async operation is done</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;">bool</span> isAsyncOperationCompleted = <span style="color: #0000ff;">false</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #008000;">//Use the mock data source</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> IBookDataSource dataSource = <span style="color: #0000ff;">new</span> MockBookDataSource();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> BooksViewModel viewModel = <span style="color: #0000ff;">new</span> BooksViewModel(dataSource);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #008000;">//If the books are loaded set the completed flag to 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-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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> dataSource.LoadBooksCompleted += (s,e) => isAsyncOperationCompleted = <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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #008000;">//Call method</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> EnqueueCallback(viewModel.LoadBooks);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #008000;">//Wait for flag to be 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-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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> EnqueueConditional(() => isAsyncOperationCompleted);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum25" 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-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; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> <span style="color: #008000;">//If async operations is done, check for the valid conditions!</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> EnqueueCallback(() => Assert.IsTrue(viewModel.Books.Count > 0, <span style="color: #006080;">"Books count is zero!"</span>));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #008000;">//Indicate that test is complete</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> EnqueueTestComplete();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>As you can see we created a flag (<em>isAsnycOperationCompleted</em>) to indicate whether the asynchronous operation is completed or not. Then we’ll configure our <em>BooksViewModel</em> to use the <em>MockBookDataSource</em> class. When the <em>LoadBooksCompleted</em> event raises, we should set the flag to true. Now we’ll call the <em>LoadBooks</em>() method using <em>EnqueueCallback</em>, and wait until it completes (see <em>EnqueueConditional</em>). After that we can check whether we have any <em>BookDetailsViewModel</em> instance loaded into the Books property. Finally we have to indicate that the Test is complete by now (<em>EnqueueTestComplete</em>). If we don’t do that, the test will run forever. You can run the test by starting the generated Test Page.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/unittest_2.png"><img width="604" height="414" title="unittest" style="border:0px solid; display: block; float: none; margin-left: auto; margin-right: auto;" alt="unittest" src="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/unittest_thumb.png" /></a> </p> <p>There you go. We just tested our ViewModel. Of course more extensive testing is necessary to make sure, you release a high quality product! Using this approach you can test the UI as well by instantiating the View UserControls, however I prefer to stick with testing the ViewModels and only do UI testing where it is absolutely necessary.</p> <h3>Changing to Live, WCF-based Data Source</h3> <p>So far we’ve used a mock data source object in our application. It’s time to move to a “real” data source, provided by a WCF Service. Let’s think the basics through. Changing to a live data source should not be that big of a problem. I could write a LiveDataSource class, that works well with a WCF proxy, to communicate with the server side! What about my entities? Right now I have this Book class on the client side. One thing I could do, is adding this Book class to the server side as well. Another approach could be to create an extra transformation layer on the client side, to convert the data received from the server side, to our Book entity. What I’m going to do here, is to create a separate Model project for my entities for the server side, and I’m going to add the Book class file in the silverlight project as a <strong><em>LINK.</em></strong> </p> <p>I’m going to have to set up it’s default namespace to the same as on the client side. (In this case I have to delete the Web substring.)</p> <p><a href="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/namespace_2.png"><img width="713" height="382" title="namespace" style="border:0px solid; display: block; float: none; margin-left: auto; margin-right: auto;" alt="namespace" src="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/namespace_thumb.png" /></a> <br /> Now I can add the Book class as a link.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/addaslink_2.png"><img width="676" height="418" title="addaslink" style="border:0px solid; display: block; float: none; margin-left: auto; margin-right: auto;" alt="addaslink" src="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/addaslink_thumb.png" /></a> <br /> Now we can reference this project in our Web application / WCF Service project. We can implement our Silverlight-enabled WCF Service. Also I have to add a couple of attributes to my Book class so it can we serialized with WCF. These are the DataContract and DataMember attributes.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span>[DataContract(Namespace=<span style="color: #006080;">"MVVMProductsDemo.Model"</span>)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Book</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> [DataMember]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> BookID { 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> [DataMember]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Title { 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> [DataMember]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Author { 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> [DataMember]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">decimal</span> Price { 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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>Here is the WCF Service implementation:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span>[ServiceContract(Namespace = <span style="color: #006080;">""</span>)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span>[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> BookService</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> [OperationContract]</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> IEnumerable<Book> LoadBooks()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> List<Book> bookList = <span style="color: #0000ff;">new</span> List<Book>();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> bookList.Add(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;">new</span> Book</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> BookID = 1,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> Author = <span style="color: #006080;">"Tom Clancy"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> Title = <span style="color: #006080;">"Rainbow Six"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> Price = 29.99m</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> bookList.Add(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;">new</span> Book</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum21" 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-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; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> BookID = 2,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> Author = <span style="color: #006080;">"Tom Clancy"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> Title = <span style="color: #006080;">"Executive Orders"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> Price = 19.99m</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> bookList.Add(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;">new</span> Book</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> BookID = 3,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span> Author = <span style="color: #006080;">"John Grisham"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> Title = <span style="color: #006080;">"The Partner"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> Price = 22.99m</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum35" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> bookList;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> The next step is to implement the LiveBookDataSource class and use this WCF Service to get the data. We should not forget, that calls to the WCF service will be asynchronous. <p>I’m going to need to do a little restructuring. I want to keep my model project for entities only, so I’m going to create a separate project for my data sources and I’m going to move all my data source classes and interfaces to this project. I’m going to reference my model project here and also add a service reference to my WCF Service, and tell the proxy generation tool to use existing types in my referenced assemblies, instead of generating its own Book classes.</p> <p><a href="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/wcfconfig_2.png"><img width="462" height="431" title="wcfconfig" style="border:0px solid; display: block; float: none; margin-left: auto; margin-right: auto;" alt="wcfconfig" src="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/wcfconfig_thumb.png" /></a> </p> <p>Let’s see the LiveBookDataSource implementation details.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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> LiveBookDataSource : IBookDataSource</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #cc6633;">#region</span> IBookDataSource Members</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> LoadBooks()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> BookServiceClient client = <span style="color: #0000ff;">new</span> BookServiceClient();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> client.LoadBooksCompleted += <span style="color: #0000ff;">new</span> EventHandler<LoadBooksCompletedEventArgs>(client_LoadBooksCompleted);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> client.LoadBooksAsync();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" 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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;">void</span> client_LoadBooksCompleted(<span style="color: #0000ff;">object</span> sender, LoadBooksCompletedEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> IEnumerable<Book> books = e.Result;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum17" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (LoadBooksCompleted != <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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #008000;">//Error is null if nothing went wrong</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> LoadBooksCompleted(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span> BooksLoadedEventArgs(books) { Error = e.Error });</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum21" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum23" 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-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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> RemoveBook(<span style="color: #0000ff;">int</span> bookID)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum25" 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-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; padding-top: 0px;border-style: none;"><span id="lnum26" style="color: #606060;"> </span> <span style="color: #008000;">//Remove book through WCF</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> EventHandler<BooksLoadedEventArgs> LoadBooksCompleted;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> EventHandler<OperationEventArgs> RemoveBookCompleted;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> <span style="color: #cc6633;">#endregion</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>As you can see, LoadBooks() calls a WCF LoadBooksAsync operations. When the operation ends, we get notified through an event, then we pass this data back to our caller, through an event.</p> <p>Now that we have a live data source, we can change the mock implementation in the Application_Startup method. Also you have to move the ServiceReference.ClientConfig xml file in the DataSources project to the Silverlight application project, since the running application is going to look for those settings there.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #008000;">//Change this Line</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span>IBookDataSource dataSource = <span style="color: #0000ff;">new</span> MockBookDataSource();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span><span style="color: #008000;">//To this line</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span>IBookDataSource dataSource = <span style="color: #0000ff;">new</span> LiveBookDataSource();</pre> <!--CRLF--></div> </div> <p>Now we can run our application. There you go, now we are on live data source! </p> <h3>Summary</h3> <p>What do we have right now? We have learned a new concept called Messaging that helps us communicating between different modules or view models if that’s necessary. Also we created a unit test to make sure that we know if later changes have any kind of effect on our codebase. We learned that Silverlight is special, so we need to write Asynchronous unit tests. The Unit Testing Framework in the Silverlight Toolkit comes to the rescue. Finally we changed our mock data source to a wcf data source and shared entities between the client and the server.</p> <p>We still need to discuss some issues, like how Validation works,  or how we can respond in the view model to UI specific events, or how states can be managed from the ViewModel.</p> <p>If you are interested, read Part 3.</p> <p><a href="http://www.silverlightshow.net/Storage/Sources/MVVMProductsDemoPart2.zip">Download the source code</a></p> http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-II.-Messaging-Unit-Testing-and-Live-Data-Sources.aspx editorial@silverlightshow.net (Zoltan Arvai ) http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-II.-Messaging-Unit-Testing-and-Live-Data-Sources.aspx#comments http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-II.-Messaging-Unit-Testing-and-Live-Data-Sources.aspx Wed, 16 Jun 2010 07:29:00 GMT Data Driven Applications with MVVM Part I: The Basics <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> <p><span style="font-size: 12px; font-weight: normal;"><a href="http://www.silverlightshow.net/ebooks/data_driven_mvvm.aspx">This series is now available as a fully offline resource:</a></span></p> <p style="padding-bottom: 5px; text-align: center;"><a href="http://www.silverlightshow.net/ebooks/data_driven_mvvm.aspx"><img style="border:0px solid;" alt="Data Driven Applications with MVVM Ebook" src="http://www.silverlightshow.net/Storage/mvvm_ebook_thumb_small.png" usemap="#rade_img_map_1291385581316" /></a><br /> <strong><span style="font-size: 13px;">($0.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><em><strong>This article is compatible with the latest version of Silverlight.</strong></em></p> <h3>Introduction</h3> <p>In this short series of articles I’ll cover what MVVM is and how to use it in practice, how to solve issues when applying this pattern and how to take advantage from it.</p> <h3>What is MVVM and why you need it</h3> <p>Do you know the feeling, when you start to develop an application, and in the first couple of days you feel good because you made a really good progress? Do you know the feeling, when after a couple of days, you feel that your design is not that best and when you have to modify a little code, you are afraid of the effect it might have on other parts of you code? The first sign of a bad design is when applying a hack is easier than to implement it the proper way. At the end of the week you already have spaghetti code. You have logic that is not testable, it is very tightly coupled with the UI. You cannot make just “minor” changes without taking risks. If someone wants to understand your code, it takes days or weeks to figure out how it works.</p> <p>This is where MVVM comes into play. MVVM stands for the Model – View – ViewModel pattern. It’s originated from MVC and is specific to WPF and Silverlight. The three most important things that MVVM can offer you:</p> <ol> <li>Testable code </li> <li>UI is loosely coupled with related logic </li> <li>Maintainable code </li> </ol> <h3>Basic concepts in MVVM</h3> <p><a href="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/MVVM_pattern_diagram%5B1%5D_2.jpg"><img width="244" height="221" title="MVVM_pattern_diagram[1]" style="border:0px solid; display: block; float: none; margin-left: auto; margin-right: auto;" alt="MVVM_pattern_diagram[1]" src="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/MVVM_pattern_diagram%5B1%5D_thumb.jpg" /></a></p> <h4><strong>The Layers:</strong> </h4> <p><strong>1.  The View</strong></p> <p>The View is your User Interface. It’s basically xaml. The view does not interact directly with the model. It does not contain any kind of non-UI related logic. Be aware, don’t be fooled by demo codes and presentations. Sometimes you also have C# code in your code-behind, not just xaml. Sometimes you just cannot get around it. Don’t feel bad about it. There is nothing wrong writing UI related code in the view’s code-behind, after all it’s probably view specific. However sometimes you can write or find workarounds for these cases, in form of Behaviors and Triggers.</p> <p><strong>2. The Model</strong></p> <p>The Model can contain entities, DTOs, data source and proxy objects, repositories. It largely depends on what kind of application you are writing. For example if you have a WCF service on the server (above the service layer you may have many other layers, like Business Logic Layer and Data Access Layer, etc.) you will need client side objects to interact with the services. You will need DataContracts (you can transfer data with these objects) and proxy objects to invoke operations. These can be part of your model. I like to refer to the model as the entry point to the rest of the application. The Model and the View DOES NOT know each other, they do not communicate directly.</p> <p><strong>3. The ViewModel</strong></p> <p>The ViewModel’s responsibility is to get the necessary data from the model and expose it for the view. Through the view, the user can enter data and trigger actions (commands), so the ViewModel has to interpret this input and the commands, and invoke the appropriate operations on the model and also pass the necessary data.</p> <h4><strong>Interaction between the Layers:</strong></h4> <p>The ViewModel communicates with the Model through an interface. (It’s highly recommended to use interfaces instead of actual implementation). The Model should not know the ViewModel. We try to keep the dependencies low and avoid tightly coupled scenarios. <br /> The communication between the View and the ViewModel is where it gets more interesting. Thanks to the brilliant binding mechanism in Silverlight and WPF the view can get and pass data to and from the ViewModel without actually referencing it. <br /> For example if you have a list of products in the ViewModel and the ViewModel itself is the DataContext of your View, a ListBox defined in your view can DataBind to those product entities. So the Binding mechanism provides this kind of flexibility in this specific pattern.</p> <p>Let’s see it in action!</p> <h4><strong>MVVM in practice</strong></h4> <p>Well, if you decide to use the MVVM pattern, you’ll see that there are many things that needs to be implemented over and over again. So after a while you may want to develop you own MVVM assisting framework / library to help you along with forthcoming projects. Luckily enough, there are very good solutions out there. The two most famous ones are the MVVM Light Toolkit by Laurent Bugnion, and the Composite Application Library (aka Prism) by the Patterns and Practices Team of Microsoft. However both products are very popular and support MVVM, their main concepts are pretty different. While the MVVM Light Toolkit focuses solely on the MVVM architecture, the Composite Application Library’s main focus is on supporting composite scenarios. Prism supports building Modular applications and also happens to support the MVP architecture. (MVP is like MVVM, but in MVP, the Presenter (ViewModel in our terms) may interact with the View through a well-defined interface directly)) So in our example we will use the MVVM Light Toolkit. (also available, for WPF 3.5, 4.0, Silverlight 3.0, 4.0 and WP7) You can download it from <a href="http://mvvmlight.codeplex.com/">here</a>.</p> <p>Our demo application will load Books in a ListBox. The selected product’s details will be displayed in a details panel. Also we’ll have remove buttons, so when we click on one, the selected product will be deleted.</p> <p>So I’m just going to create a simple Silverlight 4.0 project. (Please note, that if you install the MVVM Light Toolkit, you’ll also get Visual Studio Project templates. I’m just going to use the dlls here only)</p> <p><a href="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/mvvmstructure_2.png"><img width="450" height="400" title="mvvmstructure" style="border:0px solid; display: block; float: none; margin-left: auto; margin-right: auto;" alt="mvvmstructure" src="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/mvvmstructure_thumb.png" /></a> </p> <p>As you can see I’ve created separate folders for my ViewModels and my Views. I have a Master View this is the BooksView UserControl, and a details view, the BookDetailsView UserControl. Also I’ve created a separate Model Project, let’s see that first.</p> <h4>1. The Model Project</h4> <p>Book.cs – This is an entity class, that represents a Book object. It’s very simple does not contain any special code:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">namespace</span> MVVMProductsDemo.Model</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Book</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> BookID { 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-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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Title { 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Author { 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">decimal</span> Price { 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>IBookDataSource.cs – This is an interface that specifies how the ViewModel will interact with the Model.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">namespace</span> MVVMProductsDemo.Model</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">interface</span> IBookDataSource</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">void</span> LoadBooks();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #0000ff;">void</span> RemoveBook(<span style="color: #0000ff;">int</span> bookID);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> <span style="color: #0000ff;">event</span> EventHandler<BooksLoadedEventArgs> LoadBooksCompleted;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">event</span> EventHandler<OperationEventArgs> RemoveBookCompleted;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>As you can see, the interface implies that access to the DataSource will be asynchronous. Well, in Silverlight, mostly this is the case. I have two operations. One to load books, and another one to remove a book. I get notified of the results of the operations by events. Below there is an example of the BooksLoadedEventArgs</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">namespace</span> MVVMProductsDemo.Model</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> BooksLoadedEventArgs : OperationEventArgs</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> IEnumerable<Book> Books { 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> BooksLoadedEventArgs(IEnumerable<Book> books)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.Books = books;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>Now all I have to do is to actually implement the interface and provide a DataSource implementation. Well for this article a mock (fake) data source is perfect. Not to mention that I plan to use that for testing as well!</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; background-color: #f4f4f4; margin-top: 20px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-left: 4px; width: 97.6%; padding-right: 4px; font-family: 'courier new', courier, monospace; direction: ltr; height: 402px; max-height: 200px; font-size: 8pt; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">namespace</span> MVVMProductsDemo.Model</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> MockBookDataSource : IBookDataSource</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> List<Book> bookList = <span style="color: #0000ff;">new</span> List<Book>();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> MockBookDataSource()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> bookList.Add(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;">new</span> Book</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> BookID = 1,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> Author = <span style="color: #006080;">"Tom Clancy"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> Title = <span style="color: #006080;">"Rainbow Six"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> Price = 29.99m</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> bookList.Add(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum19" style="color: #606060;"> </span> <span style="color: #0000ff;">new</span> Book</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> BookID = 2,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> Author = <span style="color: #006080;">"Tom Clancy"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> Title = <span style="color: #006080;">"Executive Orders"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> Price = 19.99m</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum25" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum27" style="color: #606060;"> </span> bookList.Add(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span> <span style="color: #0000ff;">new</span> Book</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum30" style="color: #606060;"> </span> BookID = 3,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> Author = <span style="color: #006080;">"John Grisham"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum32" style="color: #606060;"> </span> Title = <span style="color: #006080;">"The Partner"</span>,</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> Price = 22.99m</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum35" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum37" style="color: #606060;"> </span> <span style="color: #cc6633;">#region</span> IBookDataSource Members</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum39" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> LoadBooks()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum41" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (LoadBooksCompleted != <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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum43" style="color: #606060;"> </span> LoadBooksCompleted(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span> BooksLoadedEventArgs(bookList));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum46" 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-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; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> RemoveBook(<span style="color: #0000ff;">int</span> bookID)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum49" style="color: #606060;"> </span> Book bookToDelete = bookList.Single(p => p.BookID == bookID);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum50" style="color: #606060;"> </span> bookList.Remove(bookToDelete);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum52" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (RemoveBookCompleted != <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-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; padding-top: 0px;border-style: none;"><span id="lnum53" style="color: #606060;"> </span> RemoveBookCompleted(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">new</span> OperationEventArgs());</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum54" 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-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; padding-top: 0px;border-style: none;"><span id="lnum55" 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-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; padding-top: 0px;border-style: none;"><span id="lnum56" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> EventHandler<BooksLoadedEventArgs> LoadBooksCompleted;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum57" 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-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; padding-top: 0px;border-style: none;"><span id="lnum58" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> EventHandler<OperationEventArgs> RemoveBookCompleted;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum59" 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-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; padding-top: 0px;border-style: none;"><span id="lnum60" style="color: #606060;"> </span> <span style="color: #cc6633;">#endregion</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum61" 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-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; padding-top: 0px;border-style: none;"><span id="lnum62" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>As you can see I load some fake books and provide an implementation for LoadBooks and RemoveBook.</p> <h4>2. The ViewModels</h4> <p><strong>ViewModelBase and Property Change Notifications</strong></p> <p>Let’s get back to the ViewModels. So I have to provide a special model class for my view to display products, load products and handle item selection. This is the BooksViewModel class. The BooksViewModel inherits from ViewModelBase defined in the MVVM Light Toolkit. For data binding to work properly, we need property change notification. ViewModelBase implements the INotifyPropertyChanged interface and provides a protected RaisePropertyChanged method, that we can use to propagate property change notification towards the UI.</p> <p><strong>Books Collection</strong></p> <p>The BooksViewModel class exposes a Books property of type ObservableCollection<BookDetailsViewModel>. This property serves as the ItemSource of the ListBox. But why not ObservableCollection<Book>? The answer is simple, I have three reasons:</p> <ol> <li>I want to bind to details panel’s (BookDetailsView) DataContext to the SelectedItem of the ListBox. But if I have Books in the ListBox instead of BookDetailsViewModel instances I cannot do this simply since the DataContext should be a BookDetailsViewModel, not a Book instance. </li> <li>In the ListBox I might want to define a DataTemplate. In the template I might want to add a button that corresponds to an action defined in the BookDetailsViewModel. </li> <li>I really want to keep the dependency of the book object very low in my ViewModels. Who knows, maybe I will have to replace it. </li> </ol> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> ObservableCollection<BookDetailsViewModel> books;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> ObservableCollection<BookDetailsViewModel> Books</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> get { <span style="color: #0000ff;">return</span> books; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> books = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> RaisePropertyChanged(<span style="color: #006080;">"Books"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span>}</pre> </div> </div> <p><strong>Selected Book</strong></p> <p>Also I have a SelectedBook property of type BookDetailsViewModel. I’m planning to bind the ListBox’s SelectedItem to this property and also the BookDetailsView’s DataContext should be read from this property. Why not use direct UI to UI binding? I have many reasons:</p> <ol> <li>Most of the time different parts of my application is likely to react if a selected item changes. Not just the UI, other components as well. </li> <li>I' want to modify the selected book from code as well. The UI needs to reflect those changes! </li> <li>The designer might screw this one up :) </li> <li>etc… </li> </ol> <p>So basically I need control over the SelectedItem, in this case the SelectedBook. This is why I’m going to do a two-way binding for the ListBox’s SelectedItem and a one-way binding for the BookDetailsView’s DataContext.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> BookDetailsViewModel selectedBook;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> p</span><span style="color: #0000ff;">ublic</span> BookDetailsViewModel SelectedBook</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> get { <span style="color: #0000ff;">return</span> selectedBook; }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span> selectedBook = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> RaisePropertyChanged(<span style="color: #006080;">"SelectedBook"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span>}</pre> </div> </div> <p><strong>Loading Books</strong></p> <p>I can access the DataSource through IBookDataSource, an instance that I get through the BooksViewModel constructor. The DataSource is event-based so I just have to subscribe the the loaded event.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span>IBookDataSource bookDataSource;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> BooksViewModel(IBookDataSource bookDataSource)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.bookDataSource = bookDataSource;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (bookDataSource != <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-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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> bookDataSource.LoadBooksCompleted += <span style="color: #0000ff;">new</span> EventHandler<BooksLoadedEventArgs>(bookDataSource_LoadBooksCompleted);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>I also create a LoadBooks() method that loads the books from the DataSource;</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> LoadBooks()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> bookDataSource.LoadBooks();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span><span style="color: #0000ff;">void</span> bookDataSource_LoadBooksCompleted(<span style="color: #0000ff;">object</span> sender, BooksLoadedEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">if</span> (e.Error != <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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #008000;">//Do dg.</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> List<BookDetailsViewModel> loadedBooks = <span style="color: #0000ff;">new</span> List<BookDetailsViewModel>();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;">foreach</span> (var book <span style="color: #0000ff;">in</span> e.Books)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> loadedBooks.Add(<span style="color: #0000ff;">new</span> BookDetailsViewModel(book));</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> Books = <span style="color: #0000ff;">new</span> ObservableCollection<BookDetailsViewModel>(loadedBooks);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>As you can see after we check a possible error, we refresh the Books Collection. Transformation in necessary into ViewModels since the EventArgs returns IEnumerable<Book> list. </p> <p>One final step for this View Model. When the user clicks the load button, the ViewModel should get the books. Now we are not binding a simple data property to a simple dependency property like a TextBox.TextProperty. Now we are binding an event to an operation. Of course this is just not possible, we need an extra object, what is called a command. Different MVVM libraries use different names for these commands, like DelegateCommand, ActionCommands or RelayCommands. All of them implement the ICommand interface and this is what matters here. We have RelayCommands in the toolkit. You can bind commands as properties. So all I have to do is to expose a LoadBooksCommand</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">private</span> RelayCommand loadBooksCommand;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span><span style="color: #0000ff;">public</span> RelayCommand LoadBooksCommand</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> loadBooksCommand;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span><span style="color: #008000;">//This line goes to the contructor</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span>loadBooksCommand = <span style="color: #0000ff;">new</span> RelayCommand(LoadBooks);</pre> <!--CRLF--></div> </div> <p>What did we here? We specified that if a LoadBooksCommand gets invoked than we should call the LoadBooks() method! The buttons have a Command property which is a dependency property. We can directly bind that property to this LoadBooksCommand. Also note, that the second parameter the the RelayCommand’s contstructor is another delegate. Here you can enter a function that checks whether the command in question can actually be executed. If not, then the associated control’s IsEnabled property is set to false. (And this is why I don’t like it. Once more we tie the hands of the designer)</p> <p><strong>BookDetailsViewModel</strong></p> <p>The last ViewModel in our case is just a representation of the Book class for now. But that’ll change later!</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;">namespace</span> MVVMProductsDemo.ViewModels</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> BookDetailsViewModel : ViewModelBase</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> Book book;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> BookDetailsViewModel(Book book)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" style="color: #606060;"> </span> <span style="color: #0000ff;">this</span>.book = book;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Title</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum14" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum16" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> book.Title;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum18" style="color: #606060;"> </span> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> book.Title = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> RaisePropertyChanged(<span style="color: #006080;">"Title"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum23" 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Author</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum29" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> book.Author;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum31" style="color: #606060;"> </span> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum33" style="color: #606060;"> </span> book.Author = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum34" style="color: #606060;"> </span> RaisePropertyChanged(<span style="color: #006080;">"Author"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum35" 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-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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum38" style="color: #606060;"> </span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">decimal</span> Price</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum40" 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-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; padding-top: 0px;border-style: none;"><span id="lnum41" 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-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; padding-top: 0px;border-style: none;"><span id="lnum42" style="color: #606060;"> </span> <span style="color: #0000ff;">return</span> book.Price;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum44" style="color: #606060;"> </span> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum46" style="color: #606060;"> </span> book.Price = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum47" style="color: #606060;"> </span> RaisePropertyChanged(<span style="color: #006080;">"Price"</span>);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum52" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>There we go. We’re done. Remember that I wrote always things like, the user does this or that, that we have a ListBox, and details etc… I never said anything about a concrete UI or layout. Let’s create it now!</p> <h3>3. The Views</h3> <p>Let’s start with the details view. How do we display one item.</p> <p style="text-align: center;"><a href="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/details_2.png"><img width="350" height="242" title="details" style="border:0px solid; display: inline;" alt="details" src="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/details_thumb.png" /></a> </p> <p>So this is what we want to create and bind. Here is the code:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">UserControl</span> <span style="color: #ff0000;">x:Class</span><span style="color: #0000ff;">="MVVMProductsDemo.Views.BookDetailsView"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #ff0000;">xmlns:d</span><span style="color: #0000ff;">="http://schemas.microsoft.com/expression/blend/2008"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> <span style="color: #ff0000;">xmlns:mc</span><span style="color: #0000ff;">="http://schemas.openxmlformats.org/markup-compatibility/2006"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> <span style="color: #ff0000;">mc:Ignorable</span><span style="color: #0000ff;">="d"</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> <span style="color: #ff0000;">d:DesignHeight</span><span style="color: #0000ff;">="300"</span> <span style="color: #ff0000;">d:DesignWidth</span><span style="color: #0000ff;">="400"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum8" 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-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; padding-top: 0px;border-style: none;"><span id="lnum9" 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;">Background</span><span style="color: #0000ff;">="White"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum10" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">Grid.RowDefinitions</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum11" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RowDefinition</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="0.117*"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum12" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RowDefinition</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="0.107*"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum13" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RowDefinition</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="0.117*"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum14" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">RowDefinition</span> <span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="0.66*"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum15" style="color: #606060;"> </span> <span style="color: #0000ff;"></</span><span style="color: #800000;">Grid.RowDefinitions</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum16" 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-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; padding-top: 0px;border-style: none;"><span id="lnum17" 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;">="0.345*"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum18" 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;">="0.655*"</span><span style="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-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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum20" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="10,0,0,0"</span> <span style="color: #ff0000;">TextWrapping</span><span style="color: #0000ff;">="Wrap"</span> <span style="color: #ff0000;">d:LayoutOverrides</span><span style="color: #0000ff;">="Width, Height"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="Title:"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum21" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="10,0,0,0"</span> <span style="color: #ff0000;">TextWrapping</span><span style="color: #0000ff;">="Wrap"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">d:LayoutOverrides</span><span style="color: #0000ff;">="Width, Height"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="Author:"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum22" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBlock</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="10,0,0,0"</span> <span style="color: #ff0000;">TextWrapping</span><span style="color: #0000ff;">="Wrap"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">d:LayoutOverrides</span><span style="color: #0000ff;">="Width, Height"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="Price:"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum23" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">TextWrapping</span><span style="color: #0000ff;">="Wrap"</span> <span style="color: #ff0000;">d:LayoutOverrides</span><span style="color: #0000ff;">="Height"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="15,0"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding Title, Mode=TwoWay}"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum24" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">TextWrapping</span><span style="color: #0000ff;">="Wrap"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">d:LayoutOverrides</span><span style="color: #0000ff;">="Height"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="15,0"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding Author, Mode=TwoWay}"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum25" style="color: #606060;"> </span> <span style="color: #0000ff;"><</span><span style="color: #800000;">TextBox</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Column</span><span style="color: #0000ff;">="1"</span> <span style="color: #ff0000;">TextWrapping</span><span style="color: #0000ff;">="Wrap"</span> <span style="color: #ff0000;">Grid</span>.<span style="color: #ff0000;">Row</span><span style="color: #0000ff;">="2"</span> <span style="color: #ff0000;">d:LayoutOverrides</span><span style="color: #0000ff;">="Height"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Center"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="15,0"</span> <span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="{Binding Price, Mode=TwoWay}"</span><span style="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-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; 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-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; 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: #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-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; padding-top: 0px;border-style: none;"><span id="lnum28" style="color: #606060;"> </span><span style="color: #0000ff;"></</span><span style="color: #800000;">UserControl</span><span style="color: #0000ff;">></span></pre> <!--CRLF--></div> </div> As you can see we did simple two-way bindings like {Binding Title, Mode=TwoWay}. <p>The BooksView UserControl is where it gets interesting:</p> <p><a href="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/master_2.png"><img width="410" height="290" title="master" style="border:0px solid; display: block; float: none; margin-left: auto; margin-right: auto;" alt="master" src="http://www.silverlightshow.net/Storage/Users/zoltan.arvai/master_thumb.png" /></a> And here is the xaml:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">ListBox</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="lboxBooks"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="8,8,0,29"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="129"</span> <span style="color: #ff0000;">ItemsSource</span><span style="color: #0000ff;">="{Binding Books}"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum2" style="color: #606060;"> </span> <span style="color: #ff0000;">SelectedItem</span><span style="color: #0000ff;">="{Binding SelectedBook, Mode=TwoWay}"</span> <span style="color: #ff0000;">DisplayMemberPath</span><span style="color: #0000ff;">="Title"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">Button</span> <span style="color: #ff0000;">Command</span><span style="color: #0000ff;">="{Binding LoadBooksCommand}"</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="btnLoad"</span> <span style="color: #ff0000;">Content</span><span style="color: #0000ff;">="Load Books"</span> <span style="color: #ff0000;">HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="8,0,0,3"</span> <span style="color: #ff0000;">VerticalAlignment</span><span style="color: #0000ff;">="Bottom"</span> <span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="129"</span><span style="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-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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span><span style="color: #0000ff;"><</span><span style="color: #800000;">local:BookDetailsView</span> <span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="bookDetails"</span> <span style="color: #ff0000;">Margin</span><span style="color: #0000ff;">="154,8,8,29"</span> <span style="color: #ff0000;">DataContext</span><span style="color: #0000ff;">="{Binding SelectedBook}"</span><span style="color: #0000ff;">/></span></pre> <!--CRLF--></div> </div> <p>So we have a ListBox with and ItemsSource bound to the Books property, and the SelectedItem bound two-way to the SelectedBook property. Right now we are not using any DataTemplates yet, this is why the DisplayMemberPath is set to Title (not Book.Title, its BookDetailsViewMode.Title!!!)</p> <p>The Button has the Command property bound to the LoadBooksCommand so when the user clicks it, it gets invoked. And finally a complete view (a user control) is placed here, this is the BookDetailsView. It’s DataContext is bound to the SelectedBook. So whenever that property changes, the Details will reflect the changes.</p> <h4>4. Wiring Up</h4> <p>Okay so we have the Views and ViewModels but we lack the wire up at the beginning? I told you I don’t want to reference the ViewModel from View. (If you do, that’s not a big problem, many MVVM implementation does that.) But I prefer to do this one more level above, in the application class:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum1" style="color: #606060;"> </span>private void Application_Startup(object sender, StartupEventArgs e)</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; 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-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; padding-top: 0px;border-style: none;"><span id="lnum3" style="color: #606060;"> </span> BooksView view = new BooksView();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum4" style="color: #606060;"> </span> IBookDataSource dataSource = new MockBookDataSource();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum5" style="color: #606060;"> </span> BooksViewModel viewModel = new BooksViewModel(dataSource);</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum6" style="color: #606060;"> </span> view.DataContext = viewModel;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum7" style="color: #606060;"> </span> this.RootVisual = view;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span id="lnum8" style="color: #606060;"> </span>}</pre> <!--CRLF--></div> </div> <p>As you can see, this is the place where I specify the actual implementation details for the IBookDatasource. This is the place where I could change it to a live data source. And here is the wire up. I specify the DataContext of the BookView as a BooksViewModel instance. That’s it.</p> <p>If we run the application now, it just works!</p> <h3>Summary</h3> <p>Okay, what do we have so far? We have a Maintainable, Testable and pretty loosely coupled solution. Also we can easily create different views, for the same data and functionality!</p> <p>Where do we go from here? We need advanced functionalities, like Removing or Updating an item, we need to battle the problems we face, when implementing these additions, like notifying other views / ViewModels if something changes. We need to create unit tests to make sure, changes in the code does not ruin the application. We need to change to a live data source from the mock one, and of course, we need validation support both on the server and the client!</p> <p>Well, if you’re interested, read Part 2!</p> <p><a href="http://www.silverlightshow.net/Storage/Sources/MVVMProductsDemoPart1.zip">Download the source code</a></p> http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-I.-The-Basics.aspx editorial@silverlightshow.net (Zoltan Arvai ) http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-I.-The-Basics.aspx#comments http://www.silverlightshow.net/items/Data-Driven-Applications-with-MVVM-Part-I.-The-Basics.aspx Tue, 15 Jun 2010 07:27:00 GMT Red-To-Green scale using an IValueConverter <h3><span style="font-family: calibri, sans-serif; font-size: 15px; line-height: 17px;"><em><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><br /> </em></span></h3> <div><span style="font-family: calibri, sans-serif; font-size: 15px; line-height: 17px;"><em><em><span style="font-size: 11pt; line-height: 115%; font-family: calibri, sans-serif;"><strong><br /> </strong></span></em></em></span></div> <h3>Introduction</h3> <p>Recently I have been working on a project, where a certain task's completion needs to be visually indicated in some graphic way. I settled on creating a style for the ProgressBar control, with a changing background color depending on the current value of the ProgressBar.</p> <h3> <p>HSV (Hue-Saturation-Value)</p> </h3> <p>From <a href="http://en.wikipedia.org/wiki/HSL_and_HSV" title="Go to Wikipedia" target="_blank">Wikipedia</a> :</p> <p>"HSL and HSV are the two most common cylindrical-coordinate representations of points in an RGB color model, which rearrange the geometry of RGB in an attempt to be more perceptually relevant than the cartesian representation."</p> <p>HSV is a different way of representing a color (as opposed to RGB, where R indicates a value from 0 to 255 that "controls the amount of red", G for green and B for Blue). Have a look at the link above for an in-depth discussion. </p> <p>I'll be using HSV to do my color change. By keeping the Saturation and Value values constant, and changing the Hue based on my progress, the color will change between Red, Orange, Yellow and finally Green.</p> <h3> <p>IValueConverter</p> </h3> <p>IValueConverter is an interface that can be implemented in WPF/Silverlight to provide a declarative way to convert properties from one datatype to another. I'll be using it to convert from my current progress (a int value between 0 and 100) and a Brush, which is what my ProgressBar expects as a background.</p> <p>Create a class, and have it implement the IValueConverter interface, as below : </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: #006699; font-weight: bold;"><br /> public</code> <code style="color: #006699; font-weight: bold;">class</code> <code style="color: #000000;">RedToGreenScaleConverter : IValueConverter</code></span></div> <div style="background-color: #f8f8f8;"><span style="margin-left: 0px !important;"><code style="color: #000000;">{ </code></span></div> <div style="background-color: #ffffff;"><span><code>    </code><span style="margin-left: 12px !important;"><code style="color: gray;">#region IValueConverter Members</code></span></span><code> </code><span style="margin-left: 3px !important;"> </span></div> <div style="background-color: #ffffff;"><span><code>    </code><span style="margin-left: 12px !important;"><code style="color: #006699; font-weight: bold;">public</code> <code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">Convert(</code><code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">value, Type targetType, </code><code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">parameter, System.Globalization.CultureInfo culture) </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;">{ </code></span></span></div> <div style="background-color: #ffffff;"><span><code>        </code><span style="margin-left: 24px !important;"><code style="color: #006699; font-weight: bold;">return</code> <code style="color: #006699; font-weight: bold;">new</code> <code style="color: #000000;">SolidColorBrush(ColorFromHSV((</code><code style="color: #006699; font-weight: bold;">double</code><code style="color: #000000;">)value, 1, 1)); </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;">} </code></span></span></div> <div style="background-color: #ffffff;"><span><code> </code><span style="margin-left: 3px !important;"> </span></span></div> <div style="background-color: #f8f8f8;"><span><code>    </code><span style="margin-left: 12px !important;"><code style="color: #006699; font-weight: bold;">public</code> <code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">ConvertBack(</code><code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">value, Type targetType, </code><code style="color: #006699; font-weight: bold;">object</code> <code style="color: #000000;">parameter, System.Globalization.CultureInfo culture</code></span></span><span style="color: #5c5c5c; font-family: monospace;"><span style="color: #000000; font-family: 'times new roman';"><code>    </code></span><span style="color: #000000; font-family: 'times new roman'; margin-left: 12px !important;"><code style="color: #000000;">{</code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>        </code><span style="margin-left: 24px !important;"><code style="color: #006699; font-weight: bold;">return</code> <code style="color: #006699; font-weight: bold;">null</code><code style="color: #000000;">; </code></span></span></div> <div style="background-color: #ffffff;"><span><code>    </code><span style="margin-left: 12px !important;"><code style="color: #000000;">} </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>    </code><span style="margin-left: 12px !important;"><code style="color: gray;">#endregion </code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;">}</code></span></div> </div> <p>IValueConverter implements two methods : Convert, and ConvertBack. The titles should be self-explanatory. In ConvertBack, I return a null value (I don't want to convert a Brush to an int in my application). In Convert, I return a new SolidColorBrush, which I need to provide with one argument : a Color.</p> <p>The Color is returned from a custom method call ColorFromHSV. It calculates the RGB values for specific H, S and V values (which are provided as arguments) :</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: #006699; font-weight: bold;">private</code> <code style="color: #006699; font-weight: bold;">static</code> <code style="color: #000000;">Color ColorFromHSV(</code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">hue, </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">saturation, </code><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">value)</code></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;"></code></span><span style="font-family: monospace;">{</span></div> <div style="background-color: #ffffff;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">hi = (</code><code style="color: #006699; font-weight: bold;">int</code><code style="color: #000000;">)(Math.Floor(hue / 60)) % 6; </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">double</code> <code style="color: #000000;">f = hue / 60 - Math.Floor(hue / 60);</code></span></span><code> </code><span style="margin-left: 3px !important;"> </span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #000000;">value = value * 255; </code></span></span></div> <div style="background-color: #ffffff;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">v = (</code><code style="color: #006699; font-weight: bold;">int</code><code style="color: #000000;">)(value); </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">p = (</code><code style="color: #006699; font-weight: bold;">int</code><code style="color: #000000;">)(value * (1 - saturation)); </code></span></span></div> <div style="background-color: #ffffff;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">q = (</code><code style="color: #006699; font-weight: bold;">int</code><code style="color: #000000;">)(value * (1 - f * saturation)); </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">int</code> <code style="color: #000000;">t = (</code><code style="color: #006699; font-weight: bold;">int</code><code style="color: #000000;">)(value * (1 - (1 - f) * saturation)); </code></span></span></div> <div style="background-color: #ffffff;"><span><code> </code><span style="margin-left: 3px !important;"> </span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">if</code> <code style="color: #000000;">(hi == 0) </code></span></span></div> <div style="background-color: #ffffff;"><span><code>                </code><span style="margin-left: 48px !important;"><code style="color: #006699; font-weight: bold;">return</code> <code style="color: #000000;">Color.FromArgb(255, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)v, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)t, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)p); </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">else</code> <code style="color: #006699; font-weight: bold;">if</code> <code style="color: #000000;">(hi == 1) </code></span></span></div> <div style="background-color: #ffffff;"><span><code>                </code><span style="margin-left: 48px !important;"><code style="color: #006699; font-weight: bold;">return</code> <code style="color: #000000;">Color.FromArgb(255, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)q, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)v, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)p); </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">else</code> <code style="color: #006699; font-weight: bold;">if</code> <code style="color: #000000;">(hi == 2) </code></span></span></div> <div style="background-color: #ffffff;"><span><code>                </code><span style="margin-left: 48px !important;"><code style="color: #006699; font-weight: bold;">return</code> <code style="color: #000000;">Color.FromArgb(255, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)p, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)v, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)t); </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">else</code> <code style="color: #006699; font-weight: bold;">if</code> <code style="color: #000000;">(hi == 3) </code></span></span></div> <div style="background-color: #ffffff;"><span><code>                </code><span style="margin-left: 48px !important;"><code style="color: #006699; font-weight: bold;">return</code> <code style="color: #000000;">Color.FromArgb(255, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)p, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)q, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)v); </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">else</code> <code style="color: #006699; font-weight: bold;">if</code> <code style="color: #000000;">(hi == 4) </code></span></span></div> <div style="background-color: #ffffff;"><span><code>                </code><span style="margin-left: 48px !important;"><code style="color: #006699; font-weight: bold;">return</code> <code style="color: #000000;">Color.FromArgb(255, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)t, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)p, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)v); </code></span></span></div> <div style="background-color: #f8f8f8;"><span><code>            </code><span style="margin-left: 36px !important;"><code style="color: #006699; font-weight: bold;">else</code></span></span></div> <div style="background-color: #ffffff;"><span><code>                </code><span style="margin-left: 48px !important;"><code style="color: #006699; font-weight: bold;">return</code> <code style="color: #000000;">Color.FromArgb(255, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)v, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)p, (</code><code style="color: #006699; font-weight: bold;">byte</code><code style="color: #000000;">)q);</code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 48px !important;"><code style="color: #000000;"></code></span><span style="font-family: monospace;">}</span></div> </div> <p>This code was adapted from <a href="http://www.cs.rit.edu/~ncs/color/t_convert.html">here</a>.</p> <h3> <p>ProgressBar Style</p> </h3> <p>To implement this in a ProgressBar, I needed to create a new style. Using Expression Blend, add a ProgressBar to your control/window/page, right-click on it in the Objects and Timeline window, select Edit Templates and Edit a Copy... :</p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/grimstoner/pgbCreateStyle.png" /></p> <p>This will generate a Style for a ProgressBar in the location you specify, based on the current style. Because I had no style specified, the default style is returned.</p> <p>The style consists of a lot of XAML... but the part I'm interested in is called "Indicator", a rectangle. This rectangle contracts/expands depending on the Value property of the ProgressBar. I'll be changing it's Fill property, but first, a namespace declaration :</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;">xmlns:converters="clr-namespace:ConverterDemo"</code></span></div> </div> <p>and a reference to my converter in the Resources section</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;"><</code><code style="color: #006699; font-weight: bold;">Window.Resources</code><code style="color: #000000;">> </code></span></div> <div style="background-color: #f8f8f8;"><span><code>        </code><span style="margin-left: 24px !important;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">converters:RedToGreenScaleConverter</code> <code style="color: #808080;">x:Key</code><code style="color: #000000;">=</code><code style="color: blue;">"redGreenScale"</code> <code style="color: #000000;">/> </code></span></span></div> <div style="background-color: #ffffff;"><span style="margin-left: 0px !important;"><code style="color: #000000;"></</code><code style="color: #006699; font-weight: bold;">Window.Resources</code><code style="color: #000000;">></code></span></div> </div> <p><span style="font-size: 14px;">and finally, changing the Fill property :</span> </p> <div class="reCodeBlock" style="border:1px solid #7f9db9;overflow-y: auto;"> <div style="background-color: #ffffff;"><code style="color: #000000;"><</code><code style="color: #006699; font-weight: bold;">Rectangle</code> <code style="color: #808080;">x:Name</code><code style="color: #000000;">=</code><code style="color: blue;">"Indicator"</code> <code style="color: #808080;">Fill</code><code style="color: #000000;">=</code><code style="color: blue;">"{TemplateBinding Value, Converter={StaticResource redGreenScale}}"</code><code style="color: #000000;">/></code></div> </div> <p><span style="color: #ff0000;"><strong>[Update] :</strong></span> Thanks to Waqas for pointing out that the previous code snippet only works in WPF. For it to work in Silverlight, you need to use a RelativeSource Binding, as follows :</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 id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span>Rectangle x:Name="Indicator" </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;"> </span> Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, </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;"> </span> Path=Value, </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;"> </span> Converter={StaticResource redGreenScale}}" </pre> <!--CRLF--></div> </div> <p><strong><span style="color: #ff0000;">[Another update] :</span></strong> You can also use the Progressbar’s Foreground property with the RelativeSource Binding… eliminating the need for the template :</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 id="lnum1" style="color: #606060;"> </span><span style="color: #0000ff;"><</span>ProgressBar Foreground="{Binding RelativeSource={RelativeSource Self}, </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;"> </span> Path=Value, </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;"> </span> Converter={StaticResource redGreenScale}}"</pre> <!--CRLF--></div> </div> <p>This piece of code says that the Fill property should be set to the value of the ProgressBar's Value property (via TemplateBinding, check <a href="http://www.beacosta.com/blog/?m=200611">Bea Stollnitz's blog</a> for a simple explanation), <em>converted</em> by using the RedToGreenScaleConverter. So, everytime the ProgressBar's value changes, that value will be converted to a Color by the converter.</p> <h3>Result</h3> <p>This is what the ProgressBar looks like at the indicated values :</p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/grimstoner/pgb4of100.png" /></p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/grimstoner/pgb52of100.png" /></p> <p><img alt="" src="http://www.silverlightshow.net/Storage/Users/grimstoner/pgb100of100.png" /></p> <p>Ciao! <br /> Marcel du Preez <br /> <a href="mailto:marcel@inivit.com">marcel@inivit.com</a> </p> http://www.silverlightshow.net/items/Red-To-Green-scale-using-an-IValueConverter.aspx editorial@silverlightshow.net (Marcel du Preez ) http://www.silverlightshow.net/items/Red-To-Green-scale-using-an-IValueConverter.aspx#comments http://www.silverlightshow.net/items/Red-To-Green-scale-using-an-IValueConverter.aspx Tue, 15 Jun 2010 01:20:00 GMT ModalDialogs, IEditableObject and MVVM in Silverlight 4 <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>1. Introduction</strong></h3> <p>I recently found myself in the following situation. My boss came to me and asked me: “<em>Dude, we have a big Silverlight project, performing a great number of CRUD operations. We need to find a unified way of showing Modal Dialogs in a MVVM manner, without using any code in the View. The logic of showing dialogs must reside in the <strong>ViewModel</strong>, not in the code-behind. Also do you remember our previous WinForms projects? There are several pretty useful classes, such as <strong>BindingSource</strong> and <strong>DataRowView</strong>, implementing <strong>BeginEdit</strong>, <strong>EndEdit</strong> and <strong>CancelEdit</strong> functionality out of the box. We need to bring this functionality in our Silverlight projects, however, this time on business objects level. It must be ready till tonight, otherwise you won’t get salary at the end of the month!!!</em>” </p> <p>Knowing my boss, the last sentence must have been a joke, or at least I hope to be a joke :) After working a few hours on the problem, I found a solution, which makes me feel pretty happy. That’s why I decided to share it with you guys.</p> <h3></h3> <h3><strong>2. Modal Dialogs and MVVM</strong></h3> <p>So here is the general idea. First, we need to find a way to show modal dialogs. Fortunately, Silverlight 3 and Silverlight 4 provide us with <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.childwindow%28VS.95%29.aspx">ChildWindow</a>. Of course, with the same success you can use dialogs (windows) provided by any third-party component vendor. However, the most important question is how to use a Modal Dialog inside the ViewModel and in the same time to remain decoupled. One of the most important OOP principles – <em>The Dependency Inversion Principle</em> teaches us to depend on abstractions not on concrete implementations. When we have static dependencies in our code, we can break them by using either an interface or a base class. Additionally, according to the MVVM pattern, the ViewModel doesn’t have to know about the View. Definitely we need an interface. Here it is:</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image010.png" /></div> <p>So we need a <em>DialogResult</em> to determine whether the OK or Cancel button is clicked. We need to have the possibility to <em>Close</em> and <em>Show</em> the dialog; to be notified when the dialog is closed, in order to perform the subsequent actions. And finally, let’s take a look at the <em>Content</em> property. It is a little bit more special. Why? The answer is that there are two possible solutions of the current problem. In the first one, we can exchange the <strong>Content</strong> property with <strong>DataContext</strong> property. Or in other words, we need to create a new modal dialog for each entity. After that we just set the target entity to the dialog’s <strong>DataContext</strong>, like on the image below.</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image020.png" /></div> <p>The second solution requires some additional work. Instead of having a separate child window for each entity, you could use UserControls. After that, you just set the UserControl to the dialog’s <strong>Content</strong> property.</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image030.png" /></div> <p>Personally I prefer the second one, and namely it is demonstrated in this demo. However, the first one is also “<em>playable</em>”. Here is the IModalView interface. It is a quite simple, and provides a way to set the <strong>DataContext</strong> property of the UserControl, as well as to be notified when OK or Cancel button is pressed.</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image040.png" /></div> <p>Finally, we need to bring in another level of abstraction on the scene. The final piece is the glue between the ModalDialog, the ModalView, and the ViewModel. This is the IModalDialogWorker interface. It provides only one method for showing dialogs and completely hiding the details of the implementation.</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image050.png" /></div> <p>As you can see, when you show modal dialogs, you have to pass implementations of IModalDialog and IModalView interfaces, a dataContext (this is the currently edited entity – e.g. Person, Customer, Employee, etc). Finally, you need to pass an action that is invoked when the dialog is closed. The last parameter is optional (e.g. you can use that method to show custom MessageBox dialogs). Via the IModalDialog’s DialogResult property, you can obtain the dialog result.</p> <p>The ModalDialogWorker implementation is quite simple. It is just a matter of coding, here it is:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> ModalDialogWorker : IModalDialogWorker</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> ShowDialog<T>( IModalDialog modalDialog, IModalView modalView, T dataContext, Action<T> onClosed )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( modalDialog == <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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ArgumentNullException( <span style="color: #006080;">"modalDialog"</span>, <span style="color: #006080;">"Cannot be 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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( modalView == <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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ArgumentNullException( <span style="color: #006080;">"modalView"</span>, <span style="color: #006080;">"Cannot be 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-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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> EventHandler onDialogClosedHandler = <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-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; padding-top: 0px;border-style: none;"> EventHandler<ModalViewEventArgs> onViewClosedHandler = <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-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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( onClosed != <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-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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> onDialogClosedHandler = ( s, a ) =></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalDialog.Closed -= onDialogClosedHandler;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> onClosed( dataContext );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> };</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> onViewClosedHandler = ( s, a ) =></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalDialog.Closed -= onDialogClosedHandler;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalView.Closed -= onViewClosedHandler;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalDialog.DialogResult = a.DialogResult;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #008000;">//modalDialog.Close();</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> onClosed( dataContext );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> };</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalDialog.Closed += onDialogClosedHandler;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalView.Closed += onViewClosedHandler;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalDialog.Content = modalView;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalView.DataContext = dataContext;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> modalDialog.ShowDialog();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>Now let’s see how to create IModalDialog and IModalView implementations. The ModalDialog is very simple. You just have to derive from ChildWindow and implement the IModalDialog interface.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> ExtendedChildWindow : ChildWindow, IModalDialog</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> ShowDialog()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.Show();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>Note that the ExtendedChildWindow dialog is universal, you just have to set its content property with the concrete <em>XXXModalView</em>. For example, if you want to create a control for editing Person objects, you need to create a new UserControl and implement IModalView interface.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span> EditPersonControl : UserControl, IModalView</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> EditPersonControl()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> InitializeComponent();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> EventHandler<ModalViewEventArgs> Closed;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> OnClosed( ModalViewEventArgs e )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( <span style="color: #0000ff;">this</span>.Closed != <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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.Closed( <span style="color: #0000ff;">this</span>, e );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> btnOkClick( <span style="color: #0000ff;">object</span> sender, RoutedEventArgs e )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.OnClosed( <span style="color: #0000ff;">new</span> ModalViewEventArgs( <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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> btnCancelClick( <span style="color: #0000ff;">object</span> sender, RoutedEventArgs e )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.OnClosed( <span style="color: #0000ff;">new</span> ModalViewEventArgs( <span style="color: #0000ff;">false</span> ) );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>The only things you should do in the code-behind is to mark the control as IModalView implementation; to set the DialogResult to true, if user clicked OK, and to false if user clicked Cancel. Note that this is done in the code-behind because it is not part of the business logic, but of the UI logic.</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image060.png" /></div> <p>The key moments in the ModalDialogWorker are these three lines of code:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">modalDialog.Content = modalView;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">modalView.DataContext = dataContext;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">modalDialog.ShowDialog();</pre> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"></pre> </div> </div> <h3><strong>3. “M” for Mighty</strong></h3> <p>The question remains how to <strong>inject</strong> the IModalDialog, IModalVIew and IModalDialogWorker implementations into the ViewModel.</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image070.png" /></div> <p>Fortunately, we have <strong>MEF</strong> in our tool belt. You need to mark all composable parts with the <strong>Export</strong> attribute and to specify contracts.</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image080.png" /></div> <p>On the other side of the channel, the ViewModel, you have to specify the <strong>Imports</strong>. After that, using the ModalDialogWorker is just a piece of cake.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> OnEditPersonCommandExecute()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.ModalDialogWorker.ShowDialog<Person>(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.ModalDialog, <span style="color: #0000ff;">this</span>.EditPersonControl, <span style="color: #0000ff;">this</span>.SelectedPerson, p =></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( <span style="color: #0000ff;">this</span>.ModalDialog.DialogResult.HasValue &&</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.ModalDialog.DialogResult.Value )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #008000;">// OK</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <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-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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #008000;">// Cancel</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> } );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>Of course you could use any other discovering patterns.</p> <h3><strong>4. Generic Implementation of IEditableObject</strong></h3> <p>The next important bunch of questions is: What happens when the user edits objects? What should happen when he/she presses the OK or Cancel button? How to commit the changes? How to restore the original state of the object?</p> <p>We need to commit or rollback changes through the <strong>BeginEdit</strong>, <strong>EndEdit</strong> and <strong>CancelEdit</strong> methods. That is easy. We can use <strong>IEditableObject</strong> interface. The most important problem is how to keep a snapshot of the object’s state. To address this bullet, we can use the <strong>Memento</strong> pattern. The function of the <strong>Memento</strong> pattern is to capture and externalize an object’s internal state so that the object can be restored to this state later, without violating encapsulation.</p> <div style="text-align: center;"><img alt="" src="http://www.silverlightshow.net/Storage/Users/ppopadiyn/ModalDialogs_IEditableObject_MVVM_SL4/Image090.gif" /></div> <p>Well having this in mind, let’s create a new generic class named <strong>Memento<T></strong>.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Memento<T></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> Dictionary<PropertyInfo, <span style="color: #0000ff;">object</span>> storedProperties = <span style="color: #0000ff;">new</span> Dictionary<PropertyInfo, <span style="color: #0000ff;">object</span>>();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> Memento( T originator )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.InitializeMemento( originator );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> T Originator</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">protected</span> set;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Restore( T originator )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">foreach</span> ( var pair <span style="color: #0000ff;">in</span> <span style="color: #0000ff;">this</span>.storedProperties )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> pair.Key.SetValue( originator, pair.Value, <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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> InitializeMemento( T originator )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( originator == <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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ArgumentNullException( <span style="color: #006080;">"Originator"</span>, <span style="color: #006080;">"Originator cannot be 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-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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.Originator = originator;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> IEnumerable<PropertyInfo> propertyInfos = <span style="color: #0000ff;">typeof</span>( T ).GetProperties( BindingFlags.Public | BindingFlags.Instance )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> .Where( p => p.CanRead && p.CanWrite );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">foreach</span> ( PropertyInfo property <span style="color: #0000ff;">in</span> propertyInfos )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.storedProperties[ property ] = property.GetValue( originator, <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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>The code is quite simple. First you are passing the <strong>originator</strong> (this is the object we want to track). In the <strong>InitializeMemento</strong> method, you are taking the internal state. All properties and their values are stored in a simple <strong>Dictionary<string,object></strong>.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">this</span>.Originator = originator;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">IEnumerable<PropertyInfo> propertyInfos = <span style="color: #0000ff;">typeof</span>( T ).GetProperties( </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> BindingFlags.Public | BindingFlags.Instance )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> .Where( p => p.CanRead && p.CanWrite );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">foreach</span> ( PropertyInfo property <span style="color: #0000ff;">in</span> propertyInfos )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.storedProperties[ property ] = property.GetValue( originator, <span style="color: #0000ff;">null</span> );</pre> </div> </div> <p>Finally, in the RestoreState method, we are taking the original values and restoring the object’s initial state.</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Restore( T originator )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">foreach</span> ( var pair <span style="color: #0000ff;">in</span> <span style="color: #0000ff;">this</span>.storedProperties )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> pair.Key.SetValue( originator, pair.Value, <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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <p>The last piece of the puzzle is the <strong>Caretaker</strong>. The Caretaker is a simple wrapper. It implements the <strong>IEditableObject</strong> interface and has a reference to the generic Memento<T>. This is the place where the magic happens. However, the code is even simpler than the code for Memento<T>.</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Caretaker<T> : IEditableObject</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> Memento<T> memento;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">private</span> T target;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> T Target</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> get</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">this</span>.target;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">protected</span> set</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( <span style="color: #0000ff;">value</span> == <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-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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ArgumentNullException( <span style="color: #006080;">"Target"</span>, <span style="color: #006080;">"Target cannot be 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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( Object.ReferenceEquals( <span style="color: #0000ff;">this</span>.Target, <span style="color: #0000ff;">value</span> ) )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">return</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.target = <span style="color: #0000ff;">value</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> Caretaker( T target )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.Target = target;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> BeginEdit()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( <span style="color: #0000ff;">this</span>.memento == <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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.memento = <span style="color: #0000ff;">new</span> Memento<T>( <span style="color: #0000ff;">this</span>.Target );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> CancelEdit()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( <span style="color: #0000ff;">this</span>.memento == <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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ArgumentNullException( <span style="color: #006080;">"Memento"</span>, <span style="color: #006080;">"BeginEdit() is not invoked"</span> );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.memento.Restore( Target );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.memento = <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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> EndEdit()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( <span style="color: #0000ff;">this</span>.memento == <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-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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ArgumentNullException( <span style="color: #006080;">"Memento"</span>, <span style="color: #006080;">"BeginEdit() is not invoked"</span> );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.memento = <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-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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> <!--CRLF--></div> </div> <p>Now, you are free to use the Caretaker in the following manner:</p> <div id="codeSnippetWrapper"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">Caretaker<Person> editableObject = <span style="color: #0000ff;">new</span> Caretaker<Person>( <span style="color: #0000ff;">this</span>.SelectedPerson );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">editableObject.BeginEdit();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #008000;">//.....</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">this</span>.SelectedPerson.Name = <span style="color: #006080;">"Pesho"</span>;</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #008000;">// Commit Changes</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">editableObject.EndEdit();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #008000;">// -or CancelChanges</span></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">// editableObject.CancelEdit();</pre> </div> </div> <p>Let’s go back to our <strong>PersonViewModel</strong>, and update the <strong>OnEditPersonCommandExecute</strong> method:</p> <div id="codeSnippetWrapper" style="border:1px solid silver;padding-bottom: 4px; line-height: 12pt; overflow-x: auto; overflow-y: auto; 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; cursor: text; padding-top: 4px; text-align: left;"> <div id="codeSnippet" style="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; text-align: left;border-style: none;"> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> OnEditPersonCommandExecute()</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">{</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> Caretaker<Person> editableObject = <span style="color: #0000ff;">new</span> Caretaker<Person>( <span style="color: #0000ff;">this</span>.SelectedPerson );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> editableObject.BeginEdit();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> </pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.ModalDialogWorker.ShowDialog<Person>(</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.ModalDialog, <span style="color: #0000ff;">this</span>.EditPersonControl, <span style="color: #0000ff;">this</span>.SelectedPerson, p =></pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">if</span> ( <span style="color: #0000ff;">this</span>.ModalDialog.DialogResult.HasValue &&</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <span style="color: #0000ff;">this</span>.ModalDialog.DialogResult.Value )</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> editableObject.EndEdit();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> <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-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; padding-top: 0px;border-style: none;"> {</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> editableObject.CancelEdit();</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> }</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;"> } );</pre> <!--CRLF--> <pre style="text-align: left; padding-bottom: 0px; line-height: 12pt; overflow-x: visible; overflow-y: visible; 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; padding-top: 0px;border-style: none;">}</pre> </div> </div> <h3><strong>5. Final Words</strong></h3> <p>You can download the source code from <a href="http://www.silverlightshow.net/Storage/Sources/ModalDialogsInMVVM.zip">here</a>.</p> <p>The other goodies: Note that the whole business logic is located in the ViewModel. No actions in the code-behind. Also pay attention to the fact that at each point the ViewModel deals with interfaces, no concrete implementations. This is important, because it is not recommended to have a reference in the ViewModel to ChildWindow (for example). I am a big fan of MEF, that’s why I am using it wherever this is possible. However, marking the concrete implementations with the Export attribute doesn’t obligate you to use MEF for parts discovering. You are free to use any other pattern (approach). Finally, using DelegateCommand – this is standard, no need of explanation.</p> <p>And the online demo. Select a person from the datagrid. Press the Edit button, a new modal dialog appears. This is happening thanks to the three interfaces presented in the article. Make some changes to the current Person object. Click either the OK or Cancel button. The changes are committed, or respectively rejected. This is happening thanks to the generic implementations of the IEditableObject and the Memento pattern.</p> <div id="silverlightControlHost" style="width: 100%; height: 320px; text-align: left;"><object width="100%" height="100%" data="data:application/x-silverlight-2," type="application/x-silverlight-2"> <param name="source" value="http://www.silverlightshow.net/Storage/demos/ModalDialogsInMVVM.xap"> <param name="background" value="white"> <param name="minRuntimeVersion" value="3.0.40624.0"> <param name="autoUpgrade" value="true"> <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none;"> </a> </object><iframe id="_sl_historyFrame" style="border:0px; width: 0px; height: 0px; visibility: hidden;"></iframe></div> <p>So, that’s it. I know the problem for performing CRUD operations in Silverlight/WPF is not so simple and I hope that the code here will be useful for you. Feel free to experiment with it. If you have any idea for further improvements or questions, I will be happy if you share it with us.</p> http://www.silverlightshow.net/items/ModalDialogs-IEditableObject-and-MVVM-in-Silverlight-4.aspx editorial@silverlightshow.net (Pencho Popadiyn ) http://www.silverlightshow.net/items/ModalDialogs-IEditableObject-and-MVVM-in-Silverlight-4.aspx#comments http://www.silverlightshow.net/items/ModalDialogs-IEditableObject-and-MVVM-in-Silverlight-4.aspx Tue, 11 May 2010 10:47:00 GMT