<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>My Public Interface &#187; roboblob</title>
	<atom:link href="http://blog.roboblob.com/author/roboblob/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.roboblob.com</link>
	<description>and ideas for its refactoring...</description>
	<lastBuildDate>Fri, 16 Jul 2010 14:55:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Custom Silverlight TextBox control that immediately updates DataBound Text property in TwoWay binding</title>
		<link>http://blog.roboblob.com/2010/07/16/custom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding/</link>
		<comments>http://blog.roboblob.com/2010/07/16/custom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding/#comments</comments>
		<pubDate>Fri, 16 Jul 2010 14:55:20 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[CustomControl]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[Control]]></category>
		<category><![CDATA[DataBinding]]></category>
		<category><![CDATA[TextBlock]]></category>
		<category><![CDATA[TextBox]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=385</guid>
		<description><![CDATA[Number of View: 3339 Standard Silverlight TextBox control is very useful but has one strange behavior: if you use TwoWay data binding and bind some property to controls Text property, when users type text into the control, this change is not propagated to the bound property until the control loses its focus. This can be]]></description>
			<content:encoded><![CDATA[Number of View: 3339<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Standard Silverlight TextBox control is very useful but has one strange behavior: if you use TwoWay data binding and bind some property to controls Text property, when users type text into the control, this change is not propagated to the bound property until the control loses its focus.</p>
<p>This can be very annoying if you have MVVM application and you have some kind of real-time filter that needs to update some data as-you-type.</p>
<p>Problem is that TextBox control does not call <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.bindingexpression.updatesource%28VS.95%29.aspx" target="_blank">BindingExpression.UpdateSource</a> when its Text property is changed so we have to do that manually in order to fix this issue.</p>
<p>To fix this once and for all I have created simple custom control ImmediateTextBox that inherits the standard TextBox and just calls BindingExpression.UpdateSource for TextBox.TextProperty whenever text is changed.</p>
<p>Here is all the code that is in our custom control:</p>
<pre class="brush: csharp;">
using System.Windows.Controls;

namespace ImmediateDataBindingTextBox
{
    public class ImmediateTextBox : TextBox
    {
        public ImmediateTextBox()
        {
            this.Loaded += ImmediateTextBox_Loaded;
        }

        void ImmediateTextBox_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            this.TextChanged += ImmediateTextBox_TextChanged;
        }

        void ImmediateTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            var tb = sender as TextBox;
            if (tb != null)
            {
                var be = tb.GetBindingExpression(TextBox.TextProperty);
                if (be != null)
                {
                 be.UpdateSource();
                }
            }
        }
    }
}
</pre>
<p>And here is the <a title="sample silverlight application for ImmediateTextBox" href="http://demos.roboblob.com/Silverlight4/mvvm/ImmediateTextBox/" target="_blank">demo application</a> that shows this in action.<br />
In sample app you have standard TextBox and our custom ImmediateTextBox that are both bound to some property in ViewModel using TwoWay binding.</p>
<p>Below is TextBlock also bound to same property to show the current value of the property.</p>
<p>If you type text into standard TextBox the text in TextBlock will not be updated until TextBox loses its focus  and if you type text into our custom control you will see the changes propagated to the underlying property immediately.</p>
<p>If you want to use this control you can download <a title="sample solution Visual Studio 2010" href="http://demos.roboblob.com/Silverlight4/mvvm/ImmediateTextBox/ImmediateDataBindingTextBoxSolution.zip" target="_self">sample  Visual Studio 2010 Solution</a></p>
<p>Hope someone can find this useful when doing MVVM style applications where you cannot just reach for the code in code-behind to fix problems like this <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F&amp;title=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F&amp;title=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F&amp;title=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F&amp;headline=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F&amp;title=Custom+Silverlight+TextBox+control+that+immediately+updates+DataBound+Text+property+in+TwoWay+binding&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F07%2F16%2Fcustom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/07/16/custom-silverlight-textbox-control-that-immediately-updates-databound-text-property-in-twoway-binding/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Silverlight MergedDictionaries &#8211; using styles and resources from Class Libraries</title>
		<link>http://blog.roboblob.com/2010/06/09/silverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries/</link>
		<comments>http://blog.roboblob.com/2010/06/09/silverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 12:54:11 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[resources]]></category>
		<category><![CDATA[styles]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=346</guid>
		<description><![CDATA[Number of View: 9289 If you were developing larger Silverlight/WPF applications and trying to keep things like styles, control templates and other resources organized it can become really hard. Prior to Silverlight 3 it was hell to be honest You had to scatter resources all around your application, on control level and put global ones]]></description>
			<content:encoded><![CDATA[Number of View: 9289<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>If you were developing larger Silverlight/WPF applications and trying to keep things like styles, control templates and other resources organized it can become really hard.<br />
Prior to Silverlight 3 it was hell to be honest <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>You had to scatter resources all around your application, on control level and put global ones in App.xaml and soon it would all grow beyond control.</p>
<p>But then nice people from Microsoft introduced lovely little feature called <a href="http://msdn.microsoft.com/en-us/library/system.windows.resourcedictionary.mergeddictionaries(VS.95).aspx">MergedDictionaries</a> that allows you to combine the resources from different places in your application.</p>
<p>The beauty of this simple technique is that you can use resources from different files that can even reside in different Class Libraries in your project and just &#8216;reference&#8217; them in the application level (App.xaml) and they will immediately become available to all the controls in your application.</p>
<p>Not to mention the moment of reuse: you can group your application resources into assemblies, for example one can hold the Styles, another can contain Control Templates, third can have text resources etc and then you can just reference them in any project and easily (re)use them.</p>
<p>So lets see how to actually accomplish this.<br />
Luckily its very simple. We just need to add few lines to our App.xaml file:</p>
<pre class="brush: xml;">
&lt;Application xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             x:Class=&quot;ResourceDictionariesInLib.App&quot;&gt;
    &lt;Application.Resources&gt;
        &lt;ResourceDictionary&gt;
            &lt;ResourceDictionary.MergedDictionaries&gt;
                &lt;ResourceDictionary Source=&quot;/ResourceDictionariesInLib.BasicStyles;component/StylesForShapes.xaml&quot; /&gt;
                &lt;ResourceDictionary Source=&quot;/ResourceDictionariesInLib.FontStyles;component/StylesForFonts.xaml&quot; /&gt;
                &lt;ResourceDictionary Source=&quot;LocalStyles/BasicStyles.xaml&quot; /&gt;
            &lt;/ResourceDictionary.MergedDictionaries&gt;
        &lt;/ResourceDictionary&gt;
  &lt;/Application.Resources&gt;
&lt;/Application&gt;
</pre>
<p>As you see here I&#8217;m using resources from two different Silverlight Class Libraries and one is from local subfolder called &#8220;LocalStyles&#8221;.<br />
The format is clear, for resources in DLLs you use:<br />
Source=&#8221;/AssemblyName;<strong>component</strong>/FileName.xaml&#8221;<br />
The &#8220;component&#8221; part is just a keyword that tells the parser that resource is in referenced DLL.</p>
<p>One important catch here is if you are merging resources from DLLs than you need to actually add references to those Class Libraries that hold your resources so in this case i had to Add Reference to two DLLs: ResourceDictionariesInLib.BasicStyles.dll and ResourceDictionariesInLib.FontStyles.dll.</p>
<p>Format for the resource file in the application is self-explanatory.</p>
<p>In order to create a xaml file in some Class Library to hold resources just choose Add-&gt;New Item and then select SilverlightResourceDictionary from the list.</p>
<p>Also its important to state here that you can put MergedDictionaries at every level, meaning that you can put them to App.xaml and then those merged resources will be available to every element of your application, but also you can place MergedDictionaries in the CustomControl (in CustomControl.Resources) and then this resources will be available only to this control.</p>
<p>So lets see how those MergedDictionaries of resources can be used.</p>
<p>In the StylesForShapes.xaml file i have some background gradient brushes:</p>
<pre class="brush: xml;">
&lt;ResourceDictionary
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&gt;

    &lt;LinearGradientBrush x:Key=&quot;EllipseFillBrush&quot; EndPoint=&quot;1,0.5&quot; StartPoint=&quot;0,0.5&quot;&gt;
        &lt;GradientStop Color=&quot;Black&quot; Offset=&quot;0&quot; /&gt;
        &lt;GradientStop Color=&quot;#FFD41313&quot; Offset=&quot;1&quot; /&gt;
    &lt;/LinearGradientBrush&gt;

  &lt;LinearGradientBrush x:Key=&quot;RectangleFillBrush&quot; EndPoint=&quot;1,0.5&quot; StartPoint=&quot;0,0.5&quot;&gt;
    &lt;GradientStop Color=&quot;Black&quot; Offset=&quot;0&quot; /&gt;
    &lt;GradientStop Color=&quot;#FF3AD859&quot; Offset=&quot;1&quot; /&gt;
  &lt;/LinearGradientBrush&gt;

&lt;/ResourceDictionary&gt;
</pre>
<p>So since i referenced StylesForShapes.xaml file in MergedDictionaries in my App.xaml file i can use styles from that file in any Silverlight control in the whole application.</p>
<pre class="brush: xml;">
    &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot; Height=&quot;348&quot; Width=&quot;489&quot;&gt;
        &lt;Ellipse Fill=&quot;{StaticResource EllipseFillBrush}&quot; /&gt;
        &lt;Rectangle Fill=&quot;{StaticResource RectangleFillBrush}&quot; /&gt;
    &lt;/Grid&gt;
</pre>
<p>You can do the same for any other property like FontSize or FontFamilly.</p>
<p>Just extract property value to a resource and then reuse it in your app.</p>
<p>Another very nice thing about MergedDictionaries is that they are supported by Visual Studio 2010 and Blend 3/4 so if you have DLLs with resources and you merge them in App.xaml then when you are extracting new resources you can specify those resource files in DLL&#8217;s as the place where that newly extracted resource will be created.</p>
<p>Here is the example:<br />
In Visual Studio create UserControl and put an Ellipse element on it and set its Fill property to be some nice GradientBrush and then click on the <strong>black diamond</strong> <strong>symbol </strong>to the right of the Fill property and in the pop-up menu choose option <strong>Extract value to Resource</strong>:</p>
<p><a href="http://blog.roboblob.com/wp-content/uploads/2010/06/ExtractToResource.jpg"></a><a href="http://blog.roboblob.com/wp-content/uploads/2010/06/ExtractToResource.jpg"><br />
</a><a href="http://blog.roboblob.com/wp-content/uploads/2010/06/ExtractToResource.jpg"><img class="aligncenter size-full wp-image-354" title="ExtractToResource" src="http://blog.roboblob.com/wp-content/uploads/2010/06/ExtractToResource.jpg" alt="" width="468" height="349" /></a></p>
<p>After clicking on the <strong>Extract Value to Resource</strong> menu item you will need to choose where to save the newly created resource and you can here choose any of the resource xaml files in your Class Libraries like this:</p>
<p><a href="http://blog.roboblob.com/wp-content/uploads/2010/06/ChooseResourceFile.jpg"><img class="aligncenter size-full wp-image-357" title="ChooseResourceFile" src="http://blog.roboblob.com/wp-content/uploads/2010/06/ChooseResourceFile.jpg" alt="" width="380" height="174" /></a></p>
<p>So here is how a sample page that uses MergedDictionaries to set styles and fonts on its controls looks like:<br />
<a title="Silverlight MergedDictionaries demo" href="http://demos.roboblob.com/Silverlight4/MergedDictionaries/" target="_blank"><br />
</a><a href="http://demos.roboblob.com/Silverlight4/MergedDictionaries/"></a><a href="http://demos.roboblob.com/Silverlight4/MergedDictionaries/"><img class="aligncenter size-full wp-image-367" title="MergedDictionariesSample" src="http://blog.roboblob.com/wp-content/uploads/2010/06/MergedDictionariesSample.jpg" alt="" width="600" height="344" /></a></p>
<p>And <a href="http://demos.roboblob.com/Silverlight4/MergedDictionaries/ResourceDictionariesInLibrarySolution.zip">here is the Visual Studio 2010 demo solution</a>.</p>
<p>Have fun! <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F&amp;title=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F&amp;title=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F&amp;title=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F&amp;headline=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F&amp;title=Silverlight+MergedDictionaries+-+using+styles+and+resources+from+Class+Libraries&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F06%2F09%2Fsilverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/06/09/silverlight-mergeddictionaries-using-styles-and-resources-from-class-libraries/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Unit Testing Modal Dialogs in MVVM and Silverlight 4</title>
		<link>http://blog.roboblob.com/2010/04/21/unit-testing-modal-dialogs-in-mvvm-and-silverlight-4/</link>
		<comments>http://blog.roboblob.com/2010/04/21/unit-testing-modal-dialogs-in-mvvm-and-silverlight-4/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 07:58:53 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[ChildWindow]]></category>
		<category><![CDATA[Dialog]]></category>
		<category><![CDATA[ModalDialog]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[UnitTest]]></category>
		<category><![CDATA[UnitTesting]]></category>
		<category><![CDATA[ViewModel]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=319</guid>
		<description><![CDATA[As feedback to my recent post on Modal Dialogs in MVVM and Silverlight 4 I have received comments that the solution is not easy to Unit Test so i decided to create small blog posts on this subject just to show how simple and clean it is to do this...]]></description>
			<content:encoded><![CDATA[Number of View: 3969<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>As feedback to <a href="http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/" target="_blank">my recent post on Modal Dialogs in MVVM and Silverlight 4</a> I have received comments that the solution is not easy to Unit Test so i decided to create small blog posts on this subject just to show how simple and clean it is to do this.</p>
<p>So for those who are too lazy to read <a href="http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/" target="_blank">my original modal dialog post</a> here is a quick reminder:</p>
<ul>
<li>I presented a simple solution how to abstract modal dialogs and  message boxes in Silverlight 4 and call them from your ViewModel and act  according to the results returned from those modal dialogs.</li>
<li>I used Silverlight&#8217;s ChildWindow control because it was perfect fit for  that job.</li>
<li>Important thing is to say that ChildWindow control was used as  implementation (with its ViewModel off course) but was hidden by  abstractions (like IModalWindow and IModalWindowService) so it can  easily be changed by some other implementation and unit tested, mocked  out etc.</li>
</ul>
<p>So in this post i will use the same simple <a href="http://demos.roboblob.com/demos/Silverlight4/MVVM/MvvmModalDialogsUnitTesting/" target="_blank">Demo Application</a> for the previous modal dialogs post but I will add few Unit Tests using <a href="http://code.msdn.microsoft.com/silverlightut" target="_blank">Silverlight Unit Testing Framework</a> and <a href="http://www.ayende.com/projects/rhino-mocks/downloads.aspx" target="_blank">Silverlight verstion of RhinoMocks</a>.</p>
<p>Our <a href="http://demos.roboblob.com/demos/Silverlight4/MVVM/MvvmModalDialogsUnitTesting/" target="_blank">Sample app</a> is very simple and just shows a view with list of some User entities.</p>
<p>Each of users can be edited by clicking on EDIT button next to them &#8211; this shows a modal dialog with User editor, we can change details and save them by clicking on OK or CANCEL.</p>
<p>Also there is option to delete each User by clicking on the DEL button &#8211; Message Box is shown with OK/Cancel buttons &#8211; these are very common scenarios for every LOB application so that&#8217;s why i picked them.</p>
<p>I must admit that i improved my framework since the previous post &#8211; I changed the signature of the IModalDialogService a little because now in my framework i have a IViewInitializationService that wires up ViewModels with Views so all this is used in this posts just to show it off <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   (more on the IViewInitializationService and the new way how i wire up ViewModels and View in one of the next posts).</p>
<p>So first let&#8217;s see the changes made to the IModalDialogView that is the abstraction of the actual modal dialog to be shown:</p>
<pre class="brush: csharp;">
  public interface IModalWindowView : IView
  {
    bool? DialogResult { get; set; }
    event EventHandler Closed;
    void Show();
    void Close();
  }
</pre>
<p>So the real ChildWindow that will be our dialog only needs to be marked as implementor of IModalWindowView interface with no additional code needed since this interface contains only methods and properties that ChildWindow already implements:</p>
<pre class="brush: csharp;">
    public partial class EditUserModalDialogView : IModalWindowView
    {
        public EditUserModalDialogView()
        {
            InitializeComponent();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }
    }
</pre>
<p>Also you could see that our IModalDialogView implements our old friend &#8211; IView:</p>
<pre class="brush: csharp;">
    public interface IView
    {
        object FindName(string name);
        object DataContext { get; set; }
        string Name { get; set; }
        event RoutedEventHandler Loaded;
    }
</pre>
<p>Again nothing to implement here &#8211; no code to add &#8211; because ChildWindow already implements all this since its inheriting the ContentContol that has all this.</p>
<p>So now lets see the MainPageViewModel for our MainPageView that will actually show the modal dialogs and message boxes:</p>
<pre class="brush: csharp;">
    public class MainPageViewModel : ViewModel
    {
        private readonly IModalDialogService modalDialogService;
        private readonly IMessageBoxService messageBoxService;
        private ObservableCollection&lt;User&gt; users = new ObservableCollection&lt;User&gt;();

        public MainPageViewModel(IModalDialogService modalDialogService, IMessageBoxService messageBoxService)
        {
          this.modalDialogService = modalDialogService;
          this.messageBoxService = messageBoxService;

          this.Users = new ObservableCollection&lt;User&gt;();

          for (int i = 1; i &lt; 6; i++ )
          {
            this.Users.Add(new User {Username = string.Format(&quot;Admin User {0}&quot;,
                new Random((int)DateTime.Now.Ticks).Next(10,100)), IsAdmin = true});
            Thread.Sleep(100);
          }

          this.ShowUserCommand =
              new DelegateCommand&lt;User&gt;(userInstanceToEdit =&gt;
                                      {
                                       this.modalDialogService.ShowDialog&lt;EditUserModalDialogViewModel&gt;
                                             (
                                             userInstanceToEdit,
                                             (dialog, returnedViewModelInstance) =&gt;
                                             {
                                                if (dialog.DialogResult.HasValue &amp;&amp; dialog.DialogResult.Value)
                                                {
                                                var oldItem = this.Users.FirstOrDefault( u =&gt; u.Id == userInstanceToEdit.Id);
                                                var oldPos = this.Users.IndexOf(oldItem);
                                                if (oldPos &gt; -1)
                                                {
                                                    this.Users.RemoveAt(oldPos);
                                                    this.Users.Insert(oldPos, returnedViewModelInstance.User);
                                                }
                                                }
                                            });
                                       });

          this.DeleteUserCommand = new DelegateCommand&lt;User&gt;
              (p =&gt;
                                    {
                                        var result = this.messageBoxService.Show(string.Format(
                                            &quot;Are you sure you want to delete user {0} ???&quot;, p.Username),
                                            &quot;Please Confirm&quot;, GenericMessageBoxButton.OkCancel);
                                        if (result == GenericMessageBoxResult.Ok)
                                        {
                                        this.Users.Remove(p);
                                        }});

        }

        public ObservableCollection&lt;User&gt; Users
        {
            get { return users; }
            set { users = value;
            this.OnPropertyChanged(&quot;Users&quot;);
            }
        }

        private ICommand showUserCommand;
        public ICommand ShowUserCommand
        {
            get { return showUserCommand; }
            set { showUserCommand = value;
                this.OnPropertyChanged(&quot;ShowUserCommand&quot;);
            }
        }

      private ICommand deleteUserCommand;
      public ICommand DeleteUserCommand
      {
        get { return deleteUserCommand; }
        set { deleteUserCommand = value;
        this.OnPropertyChanged(&quot;DeleteUserCommand&quot;);
        }
      }
    }
</pre>
<p>As you see ViewModel is simple class and it just has a list of Users to be shown by its View and important things to notice here are two commands for editing and deleting single user.</p>
<p><strong> ShowUserCommand </strong>shows modal dialog for editing single user, and <strong>DeleteUserCommand </strong>just shows MessageBox for confirmation of deletion with OK and Cancel buttons.</p>
<p>So now comes the fun part, lets write unit tests for those commands:</p>
<p>First UnitTest checks that our ShowUserCommand shows the modal dialog for editing the user (using the IModalDialogService). We put expectation on our IModalDialogService mock and invoke our command on ViewModel and verify all expectations afterwards.</p>
<p>Here is the code:</p>
<pre class="brush: csharp;">
        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUser_ShowsModalDialogByPassingThatUserAsInitParam()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                Is.Same(userToSend),
                Is.TypeOf(typeof(Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once();

            viewModel.ShowUserCommand.Execute(userToSend);

            modalDialogService.VerifyAllExpectations();
        }
</pre>
<p>We first get our ViewModel with Rhino-mocked instances of IModalDialogService and IMessageBoxService and some test Users by calling this methods:</p>
<pre class="brush: csharp;">
        private static ObservableCollection&lt;User&gt; GenerateSampleUsers()
        {
            return new ObservableCollection&lt;User&gt;()
                                  {
                                      new User() {Username = &quot;user 1&quot;},
                                      new User() {Username = &quot;user 2&quot;},
                                      new User() {Username = &quot;user 3&quot;}
                                  };
        }

        private MainPageViewModel GetInitializedAndMockedViewModel()
        {
            this.modalDialogService = MockRepository.GenerateMock&lt;IModalDialogService&gt;();
            this.messageBoxService = MockRepository.GenerateMock&lt;IMessageBoxService&gt;();
            return new MainPageViewModel(this.modalDialogService, this.messageBoxService);
        }
</pre>
<p>So that was easy or what?</p>
<p>Lets go to next Unit Test. Lets check that when we call ShowUserCommand with instance of User that when it shows dialog and dialog returns true as its DialogResult &#8211; that we replace the original User in ViewModel&#8217;s list of Users with the one we got from the modal dialog:</p>
<pre class="brush: csharp;">
        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUserAndOnModalDialogResultIsTrue_ShouldReplaceTheOriginalUserInstanceWithOneReturnedFromModel()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            var dialog = MockRepository.GenerateMock&lt;IModalWindowView&gt;();
            dialog.Expect(p =&gt; p.DialogResult).Return(true);

            var mockViewModel = MockRepository.GenerateStub&lt;EditUserModalDialogViewModel&gt;();
            mockViewModel.User = new User() {Username = &quot;mocked&quot;};

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                    Is.Same(userToSend),
                    Is.TypeOf(typeof (Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once().WhenCalled(
                    m =&gt;
                        {
                            var action = (m.Arguments[1] as Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;);
                            if (action != null)
                            {
                                action.Invoke(dialog, mockViewModel);
                            }
                        });

            viewModel.ShowUserCommand.Execute(userToSend);

            Assert.AreEqual(&quot;mocked&quot;, viewModel.Users[1].Username);
        }
</pre>
<p>And here is the unit test that checks the DeleteUserCommand so that it actually deletes the user from the ViewModel&#8217;s list of users if OK button was clicked on the shown message box:</p>
<pre class="brush: csharp;">
        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUserAndCallToMessageBoxServiceReturnsOk_ShouldDeleteThatUser()
        {
            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Anything()).Return(GenericMessageBoxResult.Ok);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert user is not there anymore
            Assert.IsFalse(viewModel.Users.Any( u =&gt; u.Username == userToSend.Username));
        }
</pre>
<p>So it turned out that its quite simple to test Modal Dialogs as long as you have the proper abstractions in place <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
You can <a href="http://demos.roboblob.com/demos/Silverlight4/MVVM/MvvmModalDialogsUnitTesting/tests.aspx" target="_blank">open this page to see all the unit tests running in browser</a>.</p>
<p>Those tests are actually running on the code from the sample demo app!</p>
<p>And as you see all the Unit Tests are green, and the world is safe again <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Here is the code for all the tests, that is &#8211; all 9 of them:</p>
<pre class="brush: csharp;">
namespace UnitTestingModalDialogs.Tests
{
    [TestClass]
    public class MainPageViewModelTests
    {
        private IModalDialogService modalDialogService;
        private IMessageBoxService messageBoxService;

        private static ObservableCollection&lt;User&gt; GenerateSampleUsers()
        {
            return new ObservableCollection&lt;User&gt;()
                                  {
                                      new User() {Username = &quot;user 1&quot;},
                                      new User() {Username = &quot;user 2&quot;},
                                      new User() {Username = &quot;user 3&quot;}
                                  };
        }

        private MainPageViewModel GetInitializedAndMockedViewModel()
        {
            this.modalDialogService = MockRepository.GenerateMock&lt;IModalDialogService&gt;();
            this.messageBoxService = MockRepository.GenerateMock&lt;IMessageBoxService&gt;();
            return new MainPageViewModel(this.modalDialogService, this.messageBoxService);
        }

        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUser_ShowsModalDialogByPassingThatUserAsInitParam()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                Is.Same(userToSend),
                Is.TypeOf(typeof(Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once();

            viewModel.ShowUserCommand.Execute(userToSend);

            modalDialogService.VerifyAllExpectations();
        }

        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUserAndOnModalDialogResultIsTrue_ShouldReplaceTheOriginalUserInstanceWithOneReturnedFromModel()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            var dialog = MockRepository.GenerateMock&lt;IModalWindowView&gt;();
            dialog.Expect(p =&gt; p.DialogResult).Return(true);

            var mockViewModel = MockRepository.GenerateStub&lt;EditUserModalDialogViewModel&gt;();
            mockViewModel.User = new User() {Username = &quot;mocked&quot;};

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                    Is.Same(userToSend),
                    Is.TypeOf(typeof (Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once().WhenCalled(
                    m =&gt;
                        {
                            var action = (m.Arguments[1] as Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;);
                            if (action != null)
                            {
                                action.Invoke(dialog, mockViewModel);
                            }
                        });

            viewModel.ShowUserCommand.Execute(userToSend);

            Assert.AreEqual(&quot;mocked&quot;, viewModel.Users[1].Username);
        }

        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUserAndOnModalDialogResultIsFalse_ShouldNotReplaceTheItemInViewModelWithOneReceivedFromDialog()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            var dialog = MockRepository.GenerateMock&lt;IModalWindowView&gt;();
            dialog.Expect(p =&gt; p.DialogResult).Return(false);

            var mockViewModel = MockRepository.GenerateStub&lt;EditUserModalDialogViewModel&gt;();
            mockViewModel.User = new User() { Username = &quot;mocked&quot; };

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                    Is.Same(userToSend),
                    Is.TypeOf(typeof(Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once().WhenCalled(
                    m =&gt;
                    {
                        var action = (m.Arguments[1] as Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;);
                        if (action != null)
                        {
                            action.Invoke(dialog, mockViewModel);
                        }
                    });

            viewModel.ShowUserCommand.Execute(userToSend);

            Assert.AreNotEqual(&quot;mocked&quot;, viewModel.Users[1].Username);
        }

        [TestMethod]
        public void ShowUserCommand_WhenCalledWithSpecificUserAndOnModalDialogResultIsNull_ShouldNotReplaceTheItemInViewModelWithOneReceivedFromDialog()
        {
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            var dialog = MockRepository.GenerateMock&lt;IModalWindowView&gt;();
            dialog.Expect(p =&gt; p.DialogResult).Return(null);

            var mockViewModel = MockRepository.GenerateStub&lt;EditUserModalDialogViewModel&gt;();
            mockViewModel.User = new User() { Username = &quot;mocked&quot; };

            modalDialogService.Expect(
                p =&gt; p.ShowDialog&lt;EditUserModalDialogViewModel&gt;(null, null))
                .Constraints(
                    Is.Same(userToSend),
                    Is.TypeOf(typeof(Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;)))
                .Repeat.Once().WhenCalled(
                    m =&gt;
                    {
                        var action = (m.Arguments[1] as Action&lt;IModalWindowView, EditUserModalDialogViewModel&gt;);
                        if (action != null)
                        {
                            action.Invoke(dialog, mockViewModel);
                        }
                    });

            viewModel.ShowUserCommand.Execute(userToSend);

            Assert.AreNotEqual(&quot;mocked&quot;, viewModel.Users[1].Username);
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUser_ShouldCallMessageBoxServiceWithSomeTextThatContainsThatUsersUsername()
        {

            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Matching&lt;string&gt;(txt =&gt; txt.Contains(userToSend.Username)), Is.Anything(),
                Is.Equal(GenericMessageBoxButton.OkCancel)).Return(GenericMessageBoxResult.Ok);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert
            this.messageBoxService.VerifyAllExpectations();
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUser_ShouldCallMessageBoxServiceWithOkCancelParamForButtons()
        {

            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Equal(GenericMessageBoxButton.OkCancel)).Return(GenericMessageBoxResult.Ok);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert
            this.messageBoxService.VerifyAllExpectations();
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUserAndCallToMessageBoxServiceReturnsOk_ShouldDeleteThatUser()
        {
            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Anything()).Return(GenericMessageBoxResult.Ok);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert user is not there anymore
            Assert.IsFalse(viewModel.Users.Any( u =&gt; u.Username == userToSend.Username));
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUserAndCallToMessageBoxServiceReturnsCancel_ShouldNOTDeleteThatUser()
        {
            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Anything()).Return(GenericMessageBoxResult.Cancel);

            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert user is not there anymore
            Assert.IsTrue(viewModel.Users.Any(u =&gt; u.Username == userToSend.Username));
        }

        [TestMethod]
        public void DeleteUserCommand_WhenCalledWithSpecificUserAndCallToMessageBoxServiceReturnsCancel_ShouldNOTDeleteAnyUser()
        {
            // arrange
            var viewModel = GetInitializedAndMockedViewModel();

            viewModel.Users = GenerateSampleUsers();

            var userToSend = viewModel.Users[1];

            this.messageBoxService.Expect(p =&gt; p.Show(null, null, GenericMessageBoxButton.OkCancel)).Constraints(
                Is.Anything(), Is.Anything(),
                Is.Anything()).Return(GenericMessageBoxResult.Cancel);

            var usersCountBefore = viewModel.Users.Count;
            // act
            viewModel.DeleteUserCommand.Execute(userToSend);

            // assert user is not there anymore
            Assert.AreEqual(usersCountBefore, viewModel.Users.Count);
        }

    }
}
</pre>
<p>If you want to investigate further <a href="http://demos.roboblob.com/Silverlight4/MVVM//MvvmModalDialogsUnitTesting/UnitTestingModalDialogsSolution.zip" target="_self">download the Visual Studio 2010 solution </a>and play with it &#8211; feel free to use the code as you wish and remember to have fun!</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;headline=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testing+Modal+Dialogs+in+MVVM+and+Silverlight+4&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F21%2Funit-testing-modal-dialogs-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/04/21/unit-testing-modal-dialogs-in-mvvm-and-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Silverlight 4 is over and out so &#8216;the dude abides&#8217;</title>
		<link>http://blog.roboblob.com/2010/04/17/silverlight-4-is-over-and-out-and-so-the-dude-abides/</link>
		<comments>http://blog.roboblob.com/2010/04/17/silverlight-4-is-over-and-out-and-so-the-dude-abides/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 14:08:53 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=311</guid>
		<description><![CDATA[Number of View: 21814 Finally Visual Studio 2010 is out and so is the Silverlight 4. I got few complaints that my MVVM demo applications are not working properly for people that have the new Silverlight 4 runtime installed so i updated all the examples so they run properly. Also all solutions files with code]]></description>
			<content:encoded><![CDATA[Number of View: 21814<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Finally Visual Studio 2010 is out and so is the Silverlight 4.</p>
<p>I got few complaints that my <a title="mvvm in silverlight 4 blog posts" href="http://blog.roboblob.com/category/mvvm/" target="_blank">MVVM demo applications</a> are not working properly for people that have the new Silverlight 4 runtime installed so i updated all the examples so they run properly.</p>
<p>Also all solutions files with code are recompiled and checked in final version of VS 2010 so this should run fine now.</p>
<p>Expect soon more MVVM goodness on this blog, and until then &#8211; just enjoy the spring!  <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F&amp;title=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F&amp;title=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F&amp;title=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F&amp;headline=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F&amp;title=Silverlight+4+is+over+and+out+so+%27the+dude+abides%27&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F17%2Fsilverlight-4-is-over-and-out-and-so-the-dude-abides%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/04/17/silverlight-4-is-over-and-out-and-so-the-dude-abides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit Testable WCF Web Services in MVVM and Silverlight 4</title>
		<link>http://blog.roboblob.com/2010/04/11/unit-testable-wcf-web-services-in-mvvm-and-silverlight-4/</link>
		<comments>http://blog.roboblob.com/2010/04/11/unit-testable-wcf-web-services-in-mvvm-and-silverlight-4/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 21:00:19 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[DataBinding]]></category>
		<category><![CDATA[Mocking]]></category>
		<category><![CDATA[Mocks]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[ViewModel]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=255</guid>
		<description><![CDATA[Number of View: 28643 In all my previous MVVM in Silverlight 4 posts i was avoiding to address one painful aspect of the Silverlight: calling WCF Web Services. And it was not without reason. Lets face it, consuming WCF Web Services from your Silverlight application can be pretty hard. I mean hard to do it]]></description>
			<content:encoded><![CDATA[Number of View: 28643<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>In all my previous <a title="mvvm in silverlight 4 blog posts" href="http://blog.roboblob.com/tag/mvvm/" target="_blank">MVVM in Silverlight 4 posts</a> i was avoiding to address one painful aspect of the Silverlight: calling WCF Web Services.</p>
<p>And it was not without reason. Lets face it, consuming WCF Web Services from your Silverlight  application can be pretty hard.</p>
<p>I mean hard to do it in a clean way off course.</p>
<p>Yes we all know how to create a Silverlight enabled WCF Web Service from Visual Studio but things become messy from that point.</p>
<p>First question is how to invoke methods of the web service?</p>
<p>Should we use Add Web Service Reference from the Visual Studio and and get the service proxy generated for us by the IDE?</p>
<p>If you go down that route, its easy to start and you will be invoking web service methods asynchronously in no time, but you will pay the price for that simplicity later, that is for sure.</p>
<p>Next problem is how to Unit Test those web service calls &#8211; its impossible to abstract the generated proxy in a clean way.</p>
<p>Then if you change your Web Service signature, you have to rebuild your Proxy. This can be troublesome especially if more than one person is working on the same project (can be avoided using build scripts to rebuild proxy automatically during compilation but still i don&#8217;t like that).</p>
<p>Also invoking web service methods asynchronously is tedious work in terms of writing the same code over and over again.</p>
<p>You have to subscribe to the OnCompleted event, and then invoke the actual asynchronous method, and then when your OnComplete handler is invoked, you can process the results of the web service method.</p>
<p>Not to mention the lifetime of the generated proxy, and handling exceptions that could be thrown in the service etc.</p>
<p>So as we see Visual Studio (or command line) proxy generating helps us in many ways but also brings new problems that are hard to solve.</p>
<p>I figured that there has to be a better way to solve this everyday problem so while working on my personal MVVM framework (yes, everyone is building one these days) i was setting these goals regarding the Web Service calls from my MVVM applications:</p>
<ol>
<li>simplify as much as possible asynchronous invocation of Web Service methods (avoid writing boring boilerplate code for each call)</li>
<li>get rid of the Add Service Reference approach completely if possible</li>
<li>make the Web Services unit testable (hide them behind some interface so we can mock them in our unit tests)</li>
<li>simplify exception handling</li>
<li>fault tolerance (if web service client is faulted by exception it should be automatically recreated)</li>
</ol>
<p>If this list of features looks interesting to you then you will soon see that all this is possible in a simple way by using ChannelFactory&lt;T&gt; and creating the Web Service client channel for the web service manually.</p>
<p>So lets start:  In our example we will be using a fake WeatherForecast web service that will have just one method GetForecast and it will accept DateTime as parameter and return a simple class DailyForecast as a result that will have some fake data just to have something to work with.</p>
<p>First of all we need to create a service contract interface for WeatherForecastWebService and since we must allow the Silverlight client to call this web service asynchronously we will add conditional compilation code regions in the interface with additional asynchronous signatures for the GetForecast method (BeginGetForecast and EndGetForecast) like this:</p>
<pre class="brush: csharp;">
namespace Abstractions
{
    [ServiceContract]
    public interface IWeatherForecastService
    {

#if SILVERLIGHT
        [OperationContract(AsyncPattern=true)]
        IAsyncResult BeginGetForecast(DateTime day, AsyncCallback callback, object state);
        DailyForecast EndGetForecast(IAsyncResult result);
#else

        [OperationContract]
        DailyForecast GetForecast(DateTime day);
#endif
    }
}
</pre>
<p>and here is the DailyForecast Data Transfer Object (DTO) class that we will receive from the web service:</p>
<pre class="brush: csharp;">
namespace Abstractions
{
    [DataContract]
    public class DailyForecast
    {
        [DataMember]
        public DateTime Date { get; set; }

        [DataMember]
        public string Description { get; set; }
    }
}
</pre>
<p>Note the DataContract and DataMember attributes, they must be provided in order to receive the class on the client properly.</p>
<p>Since we are to consume the web service on the Silverlight client we must make available all the classes to the client side.</p>
<p>Here is how we are going to accomplish this: We must define service contract interface and all the classes that the service will return both on server and on the Silverlight client.  We will do that by creating a <strong>Abstractions.Web</strong> class library project that will hold the service contract interface IWeatherForecastService all the needed Data Transfer Object classes (in this example its just DailyForecast class), and then we will also create <strong>Abstractions.Silverlight </strong>- Silverlight class library project where we will add the same classes (DTO&#8217;s and service contract interface) as links &#8211; by going to to right click menu on the project and choose Add -&gt; Existing Item and add all needed files and click on Add As Link button instead of Add button.</p>
<p>here is how this setup looks in my Visual Studio instance:  <a href="http://blog.roboblob.com/wp-content/uploads/2010/04/AbstractionsProjectsVisualStudio.jpg"><img class="aligncenter size-medium wp-image-260" title="AbstractionsProjectsVisualStudio" src="http://blog.roboblob.com/wp-content/uploads/2010/04/AbstractionsProjectsVisualStudio-300x272.jpg" alt="" width="300" height="272" /></a> So now that we have same set of shared classes on client and on the server we can proceed with creating a web service helper class that will allow us to invoke asynchronous methods in a simple way without having to do lot of boilerplate code.  As we said we want to be able to mock that helper in our Unit Tests we need to have an interface for it so lets define that first:</p>
<pre class="brush: csharp;">
namespace Framework.Abstractions.Silverlight.WebServices
{
    public interface IWebServiceClientFactory&lt;TWebService&gt; :  IDisposable
    {
        TWebService WebServiceInstance
        {
            get;
        }

        void Invoke&lt;TParam, TResult&gt;(TParam param, object state,
                                     Func&lt;TParam, AsyncCallback, object, IAsyncResult&gt; beginOp,
                                     Func&lt;IAsyncResult, TResult&gt; endOp,
                                     Action&lt;AsyncWebServiceCallResult&lt;TResult&gt;&gt; onComplete);

    }
}
</pre>
<p>As you can see we are defining the WebServiceClientFactory of TWebService that will expose a web service client instance WebServiceInstance if we want to call it directly but more important will be the generic <strong>Invoke </strong>method for generic asynchronous calls that will allow to call any method on any web service in a simple way just by specifying the parameter, then the begin and end method we want to calla and a method that should be called with the received results when web service call is finished.</p>
<p>Our helper class will also implement IDisposable so we can cleanup properly.</p>
<p>Let us investigate the Invoke method. From its signature we see that it is a generic function and that it has two type parameters, <strong>TParam </strong>that is the type of the parameter sent to our web service when we invoke the web method, and <strong>TResult </strong>that is the type of the result we expect from the method.</p>
<p>Then there is a object state that we want to send to the web service method (we can pass NULL there if we don&#8217;t need it).</p>
<p>And then comes the fun part: Parameter <strong>beginOp </strong>is a BEGIN* method that will be invoked, and parameter <strong>endOp </strong>is the END* method that will be invoked for the web service call. In our case we will supply here BeginGetForecast and EndGetForecast methods using the WebServiceInstance property of the same factory class. But its important to note here that if our web service would have other methods that support asynchronous invoking with these BEGIN* and END* signatures, we could call them in same way, just passing another pair of Begin* and End* methods.</p>
<p>Last parameters is an Action&gt; that will be called when the web method call is finished. This action will receive the instance of custom generic class AsyncWebServiceCallResult whose type parameter is the DailyForecast &#8211; result we would normally expect from the web method.  So here is the definition of generic AsyncWebServiceCallResult class:</p>
<pre class="brush: csharp;">
namespace Framework.Abstractions.Silverlight.WebServices
{
    public class AsyncWebServiceCallResult&lt;TResult&gt;
    {
        public TResult Result { get; set; }
        public bool WasSuccessfull { get; set;}
        public Exception Exception { get; set; }
    }
}
</pre>
<p>So this class is just a wrapper around the TResult we would usually receive from the web service method call and it adds just two more properties: boolean <strong>WasSuccessfull </strong>and <strong>Exception</strong>.  If web method call is executed without problems WasSuccessfull is set to true and Exception is null, and on the other hand if there is some exception thrown during the invocation of the web service method call Exception will hold the Exception thrown and WasSuccessfull will be set to false.</p>
<p>So lets see how we would use this Web Service factory to call our WeatherForecastService:</p>
<pre class="brush: csharp;">
var weatherServiceFactory = SimpleServiceLocator.Instance.Retrieve&lt;IWebServiceClientFactory&lt;IWeatherForecastService&gt;&gt;();
weatherServiceFactory.Invoke(date, null,
                                          weatherServiceFactory.WebServiceInstance.BeginGetForecast,
                                          weatherServiceFactory.WebServiceInstance.EndGetForecast,
                                          this.OnResultReceived);
</pre>
<p>And the method that will be called when results is received would look like this:</p>
<pre class="brush: csharp;">
        private void OnResultReceived(AsyncWebServiceCallResult&lt;DailyForecast&gt; asyncResult)
        {
            if (asyncResult.WasSuccessfull)
            {
                this.StatusMessage = &quot;New forecast received ok.&quot;;
                this.ForecastThatWasReceived = asyncResult.Result;

            }
            else
            {
                this.ForecastThatWasReceived = null;
                this.StatusMessage = &quot;Error result received: Error description: &quot; + asyncResult.Exception.Message;
            }
        }
</pre>
<p>And you can use this generic helper class to create wrapper around ANY web service exposed to your Silverlight application.</p>
<p>You just instantiate this class giving it the contract interface of the desired web service and URL of the web service.</p>
<p>WebServiceClientFactory will do all the plumbing for you and create ChannelFactory and web service client and expose it in WebServiceInstance property.</p>
<p>Then you can use Invoke method of the class to call ANY web service method with single line of code (you need on complete action to receive the result but you cannot avoid that &#8211; its asynchronous call after all).</p>
<p>Usable?  <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So now that you have seen how we would use the interface of our web service factory, lets see how its really implemented:</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Windows;
using Framework.Abstractions.Silverlight.WebServices;
using System.Linq.Expressions;

namespace Framework.Implementors.Silverlight.WebServices
{
    public class WebServiceClientFactory&lt;TWebService&gt; : IWebServiceClientFactory&lt;TWebService&gt; where  TWebService : class
    {
        private CustomBinding binding;
        private readonly string endpointAddress;
        private ChannelFactory&lt;TWebService&gt; channelFactory;

        public WebServiceClientFactory(CustomBinding binding, string endpointAddress)
        {
            this.binding = binding;
            this.endpointAddress = endpointAddress;
        }

        public WebServiceClientFactory(string endpointAddress)
        {
            this.endpointAddress = endpointAddress;
        }

        public TWebService WebServiceInstance
        {
            get
            {
                if (this.channelFactory == null || this.channel == null)
                {
                    this.InitializeWeatherServiceClient();
                }

                return this.channel;
            }

            private set
            {
                this.channel = value;
            }
        }
        private TWebService channel;

        private void InitializeWeatherServiceClient()
        {
            Debug.WriteLine(&quot;Initializing factory and channel in &quot; + this.GetType().Name);
            if (this.binding == null)
            {
                var elements = new List&lt;BindingElement&gt;();
                elements.Add(new BinaryMessageEncodingBindingElement());
                elements.Add(new HttpTransportBindingElement());
                this.binding = new CustomBinding(elements);
            }

            channelFactory = new ChannelFactory&lt;TWebService&gt;(this.binding, new EndpointAddress(endpointAddress));
            channel = this.GetNewChannelFromCurrentFactory();
        }

        public void Invoke&lt;TParam, TResult&gt;(TParam param, object state, Func&lt;TParam, AsyncCallback, object, IAsyncResult&gt; beginOp, Func&lt;IAsyncResult, TResult&gt; endOp, Action&lt;AsyncWebServiceCallResult&lt;TResult&gt;&gt; onComplete)
        {
            beginOp(param, (ar) =&gt;
                {
                    var asyncResult = new AsyncWebServiceCallResult&lt;TResult&gt;();
                    try
                    {
                        asyncResult.Result = endOp(ar);
                        asyncResult.WasSuccessfull = true;
                    }
                    catch (Exception e)
                    {
                        asyncResult.WasSuccessfull = false;
                        asyncResult.Exception = e;
                    }

                    if (Deployment.Current.Dispatcher.CheckAccess())
                    {
                        onComplete(asyncResult);
                    }
                    else
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt; onComplete(asyncResult));
                    }

                }, state );
        }

        private TWebService GetNewChannelFromCurrentFactory()
        {

            var newChannel = channelFactory.CreateChannel();

            var channelAsCommunicationObject = (newChannel as ICommunicationObject);
            if (channelAsCommunicationObject != null)
            {
                channelAsCommunicationObject.Faulted += ChannelFaulted;
            }

            return newChannel;
        }

        void ChannelFaulted(object sender, EventArgs e)
        {
            Debug.WriteLine(&quot;Service channel faulted in &quot; + this.GetType().Name);
            var communicationObject = (this.channel as ICommunicationObject);
            if (communicationObject != null)
            {
                communicationObject.Abort();

                this.channel = this.GetNewChannelFromCurrentFactory();
            }
        }

        ~WebServiceClientFactory()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                // dispose managed stuff
                Debug.WriteLine(&quot;Disposing managed resources in &quot; + this.GetType().Name);
                var communicationObject = (this.channel as ICommunicationObject);
                if (communicationObject != null)
                {
                    communicationObject.Faulted -= this.ChannelFaulted;

                    try
                    {
                        communicationObject.Close();
                    }
                    catch (Exception)
                    {
                        try
                        {
                            communicationObject.Abort();
                        }
                        catch
                        {
                        }
                    }
                }
            }

            // here we would dispose unmanaged stuff
        }

    }
}
</pre>
<p>Class has multiple constructors so you can choose how to set it up. The simplest usage is just to specify the string URL of the web service. Here is how i setup my IOC in the bootstrapper of my Silverlight application:</p>
<pre class="brush: csharp;">
SimpleServiceLocator.Instance.RegisterAsSingleton&lt;IWebServiceClientFactory&lt;IWeatherForecastService&gt;&gt;
(new WebServiceClientFactory&lt;IWeatherForecastService&gt;(&quot;http://localhost:1000/WeatherForecastService.svc&quot;));
</pre>
<p>When constucted like this factory class uses standard Binding that would be created for you if you would add the Web Service Reference from visual studio and it will use that Binding and that given URL as endpoint to create a generic ChannelFactory of the web service type provided in  type param</p>
<p>&lt;TWebService&gt; and then it will create a communication channel to communicate with web service of given type on the given URL.</p>
<p>Here is the code that is doing this part:</p>
<pre class="brush: csharp;">
        private void InitializeWeatherServiceClient()
        {
            Debug.WriteLine(&quot;Initializing factory and channel in &quot; + this.GetType().Name);
            if (this.binding == null)
            {
                var elements = new List&lt;BindingElement&gt;();
                elements.Add(new BinaryMessageEncodingBindingElement());
                elements.Add(new HttpTransportBindingElement());
                this.binding = new CustomBinding(elements);
            }

            channelFactory = new ChannelFactory&lt;TWebService&gt;(this.binding, new EndpointAddress(endpointAddress));
            channel = this.GetNewChannelFromCurrentFactory();
        }
</pre>
<p>There is a another constructor that accepts Binding if you want to provide your own.<br />
Next interesting part of the class is the Invoke method:</p>
<pre class="brush: csharp;">
        public void Invoke&lt;TParam, TResult&gt;(TParam param, object state, Func&lt;TParam, AsyncCallback, object, IAsyncResult&gt; beginOp, Func&lt;IAsyncResult, TResult&gt; endOp, Action&lt;AsyncWebServiceCallResult&lt;TResult&gt;&gt; onComplete)
        {
            beginOp(param, (ar) =&gt;
                {
                    var asyncResult = new AsyncWebServiceCallResult&lt;TResult&gt;();
                    try
                    {
                        asyncResult.Result = endOp(ar);
                        asyncResult.WasSuccessfull = true;
                    }
                    catch (Exception e)
                    {
                        asyncResult.WasSuccessfull = false;
                        asyncResult.Exception = e;
                    }

                    if (Deployment.Current.Dispatcher.CheckAccess())
                    {
                        onComplete(asyncResult);
                    }
                    else
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() =&gt; onComplete(asyncResult));
                    }

                }, state );
        }
</pre>
<p>As you can see no big deal there, we just invoke the BEGIN* operation with lambda method as complete handler where we wrap the call to END* operation in Try..Catch so we can recover from any exception.<br />
If there was an exception we set WasSuccessfull to false and Exception property.<br />
If all went ok we populate the Result property with the result of the web method call and then we invoke the onComplete action that was supplied by the user of the class.<br />
But we make sure that we invoke it on the UI thread just as a convenience for the user so he does not need to do it by himself.</p>
<p>One more important thing is that if our web service channel gets faulted by some communication error we will catch that event and recreate the channel:</p>
<pre class="brush: csharp;">
        void ChannelFaulted(object sender, EventArgs e)
        {
            Debug.WriteLine(&quot;Service channel faulted in &quot; + this.GetType().Name);
            var communicationObject = (this.channel as ICommunicationObject);
            if (communicationObject != null)
            {
                communicationObject.Abort();

                this.channel = this.GetNewChannelFromCurrentFactory();
            }
        }
</pre>
<p>Previously, we subscribed that method to the OnFaulted event on the channel.</p>
<p>Other parts of the class are not too much interesting so you can dig yourself if you want.</p>
<p>So lets see how we would use the class in our view model.<br />
Here is the listing of the ForecastViewModel that will allow us to invoke the WeatherForecast web service:</p>
<pre class="brush: csharp;">
using System;
using Abstractions;
using Framework.Abstractions.Silverlight.Intefaces;
using Framework.Abstractions.Silverlight.WebServices;
using Framework.Implementors.Silverlight.Comanding;
using Framework.Implementors.Silverlight.MVVM;

namespace ViewModels
{
    public class ForecastViewModel : ViewModel
    {
        private readonly IWebServiceClientFactory&lt;IWeatherForecastService&gt; weatherServiceFactory;

        public ForecastViewModel(IWebServiceClientFactory&lt;IWeatherForecastService&gt; weatherServiceFactory)
        {
            this.weatherServiceFactory = weatherServiceFactory;

            this.GetForecastCommand =
                new DelegateCommand&lt;DateTime&gt;(
                    date =&gt;
                    {
                        this.StatusMessage = string.Format(&quot;Invoking web service with parameter {0}&quot;, date.ToString());
                        this.weatherServiceFactory.Invoke(
date,
null,
this.weatherServiceFactory.WebServiceInstance.BeginGetForecast,

this.weatherServiceFactory.WebServiceInstance.EndGetForecast,

this.OnResultReceived);

                    });

        }

        private void OnResultReceived(AsyncWebServiceCallResult&lt;DailyForecast&gt; asyncResult)
        {
            if (asyncResult.WasSuccessfull)
            {
                this.StatusMessage = &quot;New forecast received ok.&quot;;
                this.ForecastThatWasReceived = asyncResult.Result;

            }
            else
            {
                this.ForecastThatWasReceived = null;
                this.StatusMessage = &quot;Error result received: Error description: &quot; + asyncResult.Exception.Message;
            }
        }

        private IDelegateCommand getForecastCommand;

        public IDelegateCommand GetForecastCommand
        {
            get { return getForecastCommand; }
            set { getForecastCommand = value;
                this.OnPropertyChanged(&quot;GetForecastCommand&quot;);
            }
        }

        private DailyForecast forecastThatWasReceived;

        public DailyForecast ForecastThatWasReceived
        {
            get { return forecastThatWasReceived; }
            set { forecastThatWasReceived = value;
            this.OnPropertyChanged(&quot;ForecastThatWasReceived&quot;);
            }
        }

        public DateTime ValidForecastDate
        {
            get
            {
                return DateTime.Now;
            }
        }

        public DateTime BadForecastDate
        {
            get
            {
                return DateTime.MinValue;
            }
        }

        private string statusMessage;
        public string StatusMessage
        {
            get { return statusMessage; }
            set { statusMessage = value;
            this.OnPropertyChanged(&quot;StatusMessage&quot;);
            }
        }
    }
}
</pre>
<p>As you can see from the ForecastViewModel we have a command that&#8217;s invoking the web service called GetForecastCommand and we have a action method OnResultReceived that receives the result.</p>
<p>If the web service call fails we set the ForecastThatWasReceived to null and we set the StatusMessage to the Message of the Exception we received from server.</p>
<p>So here is our simple ForecastView:</p>
<pre class="brush: xml;">
&lt;UserControl x:Class=&quot;Views.ForecastView&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable=&quot;d&quot;
    d:DesignHeight=&quot;300&quot; d:DesignWidth=&quot;400&quot; MinHeight=&quot;400&quot; MinWidth=&quot;400&quot;&gt;

    &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;Red&quot;&gt;

        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
            &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
            &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
        &lt;/Grid.RowDefinitions&gt;
        &lt;StackPanel Orientation=&quot;Vertical&quot; Grid.Row=&quot;0&quot;&gt;
            &lt;Button Content=&quot;Invoke valid web service call&quot; Command=&quot;{Binding GetForecastCommand}&quot; CommandParameter=&quot;{Binding ValidForecastDate}&quot; HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot; Margin=&quot;10&quot; /&gt;

            &lt;Button Content=&quot;Invoke web service call that throws exception on server&quot; Command=&quot;{Binding GetForecastCommand}&quot; CommandParameter=&quot;{Binding BadForecastDate}&quot; HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot; Margin=&quot;10&quot; /&gt;

        &lt;/StackPanel&gt;

        &lt;Grid Grid.Row=&quot;1&quot;&gt;
            &lt;StackPanel Orientation=&quot;Vertical&quot;&gt;
                &lt;TextBlock Text=&quot;{Binding ForecastThatWasReceived.Date, StringFormat='Date: {0}', FallbackValue=' ?'}&quot; /&gt;
                &lt;TextBlock Text=&quot;{Binding ForecastThatWasReceived.Description, StringFormat='Description: {0}', FallbackValue=' ?'}&quot; /&gt;

            &lt;/StackPanel&gt;
        &lt;/Grid&gt;

        &lt;Grid Grid.Row=&quot;2&quot;&gt;
            &lt;TextBlock Text=&quot;{Binding StatusMessage}&quot; TextWrapping=&quot;Wrap&quot; /&gt;

        &lt;/Grid&gt;

    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre>
<p>As you can see we have two buttons, each wired up to the same GetForecastCommand but with different parameters.<br />
One is sending the current date to the server and other is using the BadForecastDate databound from ViewModel which is set to DateTime.Min. When web service receives any other date then DateTime.Min it returns valid instance of DailyForecast class and if it receives DateTime.Min it throws some bogus exception.<br />
This is how we will test our WebServiceFactory class to see if it can handle the exceptions thrown on server side or not.</p>
<p>you can test the <a title="Unit Testable Web Service in MVVM and Silverlight 4 demo application" href="http://demos.roboblob.com/demos/Silverlight4/MVVM/TestableWebServices/" target="_blank">live sample application here</a>.</p>
<p>So here is screenshot of the app (in case you dont have the <a href="http://www.silverlight.net/getstarted/" target="_self">Silverlight 4 runtime</a> installed) when we invoke the web service with current date:</p>
<p><a href="http://blog.roboblob.com/wp-content/uploads/2010/04/WebServiceCallOk.jpg"><img class="aligncenter size-medium wp-image-268" title="WebServiceCallOk" src="http://blog.roboblob.com/wp-content/uploads/2010/04/WebServiceCallOk-300x248.jpg" alt="" width="300" height="248" /></a></p>
<p>As you can see when we click on first button we receive the valid forecast and when we click the second one, we will receive the error but it will be catched and wrapped in our AsyncWebServiceCallResult class and our UI won&#8217;t hang and we will be able to recover from that error and immediately invoke the web service call again with different parameters.</p>
<p>Here is the same app when we invoke the web service method with invalid (min) date so it throws exception:</p>
<p><a href="http://blog.roboblob.com/wp-content/uploads/2010/04/WebServiceCallBad.jpg"><img class="aligncenter size-medium wp-image-269" title="WebServiceCallBad" src="http://blog.roboblob.com/wp-content/uploads/2010/04/WebServiceCallBad-300x248.jpg" alt="" width="300" height="248" /></a></p>
<p>So this should help us handle the web service with greater ease right ?  <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>But wait! We are not finished yet! Those of you that were paying attention noticed i promised a unit testable web services.</p>
<p>So lets do that also.</p>
<p>We will add another SIlverlight application to our sample code and set it up with Silverlight Unit Testing Framework.</p>
<p>Also we will reference all the needed projects &#8211; ViewModels, Abstractions.Silverlight, Framework.Abstractions and Framework.Implementors.</p>
<p>Also we need to make a fake WebServiceClientFactory and IWeatherService implementations so we can use them in our tests instead of the real implementations.</p>
<p>So lets do that first. here is the FakeWebServiceClientFactory:</p>
<pre class="brush: csharp;">
using System;
using Abstractions;
using Framework.Abstractions.Silverlight.WebServices;

namespace Silverlight.Tests
{
    public class FakeWebServiceClientFactory : IWebServiceClientFactory&lt;IWeatherForecastService&gt;
    {
        public FakeWebServiceClientFactory()
        {
            this.WebServiceInstance = new FakeWeatherService();
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public IWeatherForecastService WebServiceInstance { get; private set; }

        public object LastParameterSentToInvoke;

        public object NextResultToReturn;

        public void Invoke&lt;TParam, TResult&gt;(TParam param, object state, Func&lt;TParam, AsyncCallback, object, IAsyncResult&gt; beginOp, Func&lt;IAsyncResult, TResult&gt; endOp, Action&lt;AsyncWebServiceCallResult&lt;TResult&gt;&gt; onComplete)
        {
            this.LastParameterSentToInvoke = param;

            var nextResult = NextResultToReturn as AsyncWebServiceCallResult&lt;TResult&gt;;

            if (nextResult != null)
            {
                onComplete(nextResult);
            }
            else
            {
                onComplete(new AsyncWebServiceCallResult&lt;TResult&gt;
                               {Exception = new Exception(&quot;Some exception&quot;), WasSuccessfull = false});
            }
        }
    }
}
</pre>
<p>As you can see it does not do much, its just a manually written mock class we can use in our test instead of the real web service client factory.<br />
It allows us to check what was sent to the Invoke method as parameter and it allows us to set what will be sent to the OnComplete handler when client code invokes some web service call.</p>
<p>Also we need a stub for the IWeatherForecastService so here it is:</p>
<pre class="brush: csharp;">
using System;
using Abstractions;

namespace Silverlight.Tests
{
    public class FakeWeatherService : IWeatherForecastService
    {
        public IAsyncResult BeginGetForecast(DateTime day, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public DailyForecast EndGetForecast(IAsyncResult result)
        {
            throw new NotImplementedException();
        }
    }
}
</pre>
<p>Again its very simple its just a Stub class that allows us to instantiate and use it without really calling it.<br />
So now we can write few tests for our ForecastViewModel:</p>
<pre class="brush: csharp;">
using System;
using Abstractions;
using Framework.Abstractions.Silverlight.WebServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ViewModels;

namespace Silverlight.Tests
{
    [TestClass]
    public class ForecastViewModelTests
    {
        [TestMethod]
        public void GetForecastCommand_WhenExecutedWithParam_InvokesCallOnWebServiceClientFactoryInstance()
        {
            var fakeFactory = new FakeWebServiceClientFactory();
            var viewModel = new ForecastViewModel(fakeFactory);

            var date = DateTime.Now;

            viewModel.GetForecastCommand.Execute(date);

            Assert.AreEqual(date, fakeFactory.LastParameterSentToInvoke);
        }

        [TestMethod]
        public void GetForecastCommand_WhenExecutedWithMinDateANdWebserviceReturnsUnsuccessfullResult_SetsTheForecastThatWasReceivedToNull()
        {
            var fakeFactory = new FakeWebServiceClientFactory();
            var viewModel = new ForecastViewModel(fakeFactory);
            viewModel.ForecastThatWasReceived = new DailyForecast() {Description = &quot;just dummy so we can test if it was set to null.&quot;};

            fakeFactory.NextResultToReturn = new AsyncWebServiceCallResult&lt;DailyForecast&gt;() {WasSuccessfull = false, Exception = new Exception(&quot;Bad error.&quot;)};
            viewModel.GetForecastCommand.Execute(DateTime.MinValue);

            Assert.IsNull(viewModel.ForecastThatWasReceived);
        }

        [TestMethod]
        public void GetForecastCommand_WhenExecutedWithMinDateANdWebserviceReturnsUnsuccessfullResult_SetsTheStatusMessageToErrorFromReturnedException()
        {
            var fakeFactory = new FakeWebServiceClientFactory();
            var viewModel = new ForecastViewModel(fakeFactory);
            viewModel.ForecastThatWasReceived = new DailyForecast() { Description = &quot;just dummy so we can test if it was set to null.&quot; };

            fakeFactory.NextResultToReturn = new AsyncWebServiceCallResult&lt;DailyForecast&gt;() { WasSuccessfull = false, Exception = new Exception(&quot;Bad error.&quot;) };
            viewModel.GetForecastCommand.Execute(DateTime.MinValue);

            Assert.IsTrue(viewModel.StatusMessage.Contains(&quot;Bad error.&quot;));
        }

        [TestMethod]
        public void GetForecastCommand_WhenExecutedWithOkDateANdWebserviceReturnsSuccessfullResult_SetsTheStatusMessageToOkMessage()
        {
            var fakeFactory = new FakeWebServiceClientFactory();
            var viewModel = new ForecastViewModel(fakeFactory);
            viewModel.ForecastThatWasReceived = null;

            fakeFactory.NextResultToReturn = new AsyncWebServiceCallResult&lt;DailyForecast&gt;() { WasSuccessfull = true};
            viewModel.GetForecastCommand.Execute(DateTime.Now);

            Assert.IsTrue(viewModel.StatusMessage.Contains(&quot;New forecast received ok.&quot;));
        }

    }
}
</pre>
<p>And when we run them, as you can see from the screenshot below, they are all <span style="color: #008000;">GREEN!</span></p>
<p><span style="color: #008000;"><a href="http://blog.roboblob.com/wp-content/uploads/2010/04/AllTestsAreGreenAndTheWorldIsSafeAgain.jpg"><img class="aligncenter size-medium wp-image-271" title="AllTestsAreGreenAndTheWorldIsSafeAgain" src="http://blog.roboblob.com/wp-content/uploads/2010/04/AllTestsAreGreenAndTheWorldIsSafeAgain-300x178.jpg" alt="" width="300" height="178" /></a></span></p>
<p><span style="color: #008000;"><span style="color: #000000;">So there you go, we have completed in this lengthy posts most of the tasks we set in the beginning. Off course there are many places for improvement but the basis of a simple way to invoke WCF web services from Silverlight and MVVM and Unit Testability are there.</span></span></p>
<p><span style="color: #008000;"><span style="color: #000000;">If you have some comments and improvements to the solutions presented here i would be happy to hear them out.</span></span></p>
<p><span style="color: #008000;"><span style="color: #000000;">You can <a title="Unit Testable Web Service in MVVM and Silverlight 4 Solution Visual Studio 2010" href="http://demos.roboblob.com/demos/Silverlight4/MVVM/TestableWebServices/TestableWebServicesInMVVMSilverlight4Solution.zip" target="_self">download Visual Studio 2010 Solution</a> with the code from this post if you want to run it locally.<br />
</span></span></p>
<p><span style="color: #008000;"><span style="color: #000000;">Until then, happy testing!<br />
</span></span></p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;headline=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F&amp;title=Unit+Testable+WCF+Web+Services+in+MVVM+and+Silverlight+4&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F04%2F11%2Funit-testable-wcf-web-services-in-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/04/11/unit-testable-wcf-web-services-in-mvvm-and-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Back online</title>
		<link>http://blog.roboblob.com/2010/03/31/back-online/</link>
		<comments>http://blog.roboblob.com/2010/03/31/back-online/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 19:57:28 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[Hosting]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=251</guid>
		<description><![CDATA[Number of View: 1251 We are back online again! I had some problems with hosting of this blog on GoDaddy and their tech support was not really being helpful so it took a while to put everything back in place. At the end i had to figure everything out by myself since their comment was]]></description>
			<content:encoded><![CDATA[Number of View: 1251<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>We are back online again!</p>
<p>I had some problems with hosting of this blog on <a href="http://godaddy.com" target="_blank">GoDaddy</a> and their tech support was not really being helpful so it took a while to put everything back in place.</p>
<p>At the end i had to figure everything out by myself since their comment was something like &#8216;All is fine on our side, its your scripts that are causing problems&#8230;&#8217;</p>
<p>Never mind that, the important thing is that its fixed now. Next time when i will be buying hosting i will definitely be more careful.</p>
<p>I took this chance and converted all the <a title="MVVM demos and source code" href="http://blog.roboblob.com/tag/mvvm/" target="_blank">MVVM demos and solution files for Visual Studio 2010 RC and Silverlight 4 RC</a>.</p>
<p>So if you had some problems running the sample apps or building projects, try again now all should be working fine.</p>
<p>Soon i will be posting some new MVVM patterns implementations that could be interesting to many of you so stay tuned!</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F&amp;title=Back+online" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F&amp;title=Back+online" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F&amp;title=Back+online" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F&amp;headline=Back+online" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Back+online&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Back+online&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Back+online&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Back+online&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Back+online&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F&amp;title=Back+online&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F03%2F31%2Fback-online%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/03/31/back-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit testing and mocking internal interfaces with RhinoMocks</title>
		<link>http://blog.roboblob.com/2010/02/18/unit-testing-and-mocking-internal-interfaces-with-rhinomocks/</link>
		<comments>http://blog.roboblob.com/2010/02/18/unit-testing-and-mocking-internal-interfaces-with-rhinomocks/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 21:48:07 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Mocking]]></category>
		<category><![CDATA[Mocks]]></category>
		<category><![CDATA[RhinoMocks]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=234</guid>
		<description><![CDATA[Im not the kind of purist that will avoid unit testing internal classes. If its some very important code i want to test it even if its internal.

Another case when i want to access internal classes is when i want to test some public class that uses some internal classes (via their interfaces).
In this scenario i need to be able to mock those internal interfaces that the public class is using in order to be able to instantiate it and unit test it.]]></description>
			<content:encoded><![CDATA[Number of View: 2274<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Im working on a project that i want to cover with unit tests as much as possible.</p>
<p>Problem is that most of the things i need to test are kept internal inside some libraries.</p>
<p>Im not the kind of purist that will avoid unit testing internal classes. If its some very important code i want to test it even if its internal.</p>
<p>Another case when i want to access internal classes is when i want to test some public class that uses some internal classes (via their interfaces).<br />
In this scenario i need to be able to mock those internal interfaces that the public class is using in order to be able to instantiate it and unit test it.</p>
<p>Now some of you experienced TDD people will shout: &#8220;Ha haaa that&#8217;s easy just use the</p>
<p>[assembly: InternalsVisibleTo("Some.TestAssembly.Name")] and your are cool&#8221;.</p>
<p>But this is only partial true. Here is why:<br />
Using the InternalsVisibleTo attribute will allow you to access internal members of assembly from the test assembly and use them in unit tests, but if you try to mock them (lets say we use the fantastic <a href="http://www.ayende.com/projects/rhino-mocks.aspx" target="_blank">RhinoMocks</a>), you will get exception similar to this one:</p>
<p><span style="color: #ff0000;">Castle.DynamicProxy.Generators.GeneratorException: Type is not public, so a proxy cannot be generated. </span></p>
<p><span style="color: #ff0000;">Type: Roboblob.Implementors.Interfaces.ICookieService</span></p>
<p>So in this concrete case I have added the <strong>InternalsVisibleTo </strong>attribute to my main assembly and this allowed the other assembly where my unit tests are to access the internal interface ICookieService but this helped me only half-way. I forgot about RhinoMocks!.</p>
<p>So RhinoMocks cannot create proxy that implements this interface in order to create a mock and throws this exception.</p>
<p>I tried few things to solve this and then i found this link: <a href="http://ayende.com/Wiki/Rhino+Mocks+-+Internal+Methods.ashx" target="_blank">Rhino Mocks Internal Members</a>.</p>
<p>As most things in life, its very simple once you figure it out: In order to be able to mock internal members of some class you need to allow the RhinoMocks to &#8216;see&#8217; internals of this class by placing this in your AssemblyInfo.cs:</p>
<pre class="brush: csharp;">
[assembly: InternalsVisibleTo (&quot;DynamicProxyGenAssembly2&quot;)]
</pre>
<p>Since RhinoMocks must create a proxy class to create a mock and definition for that proxy is in DynamicProxyGenAssembly2 &#8211; we need to allow this assembly to access internal members of the assembly holding the class we are testing.</p>
<p>So with this new trick I&#8217;m ready to dive into my mocking adventures&#8230;.</p>
<p>Wish me luck <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;headline=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F&amp;title=Unit+testing+and+mocking+internal+interfaces+with+RhinoMocks&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F18%2Funit-testing-and-mocking-internal-interfaces-with-rhinomocks%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/02/18/unit-testing-and-mocking-internal-interfaces-with-rhinomocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>List of useful WordPress plugins to use on your Blog</title>
		<link>http://blog.roboblob.com/2010/02/07/list-of-useful-wordpress-plugins-to-use-on-your-blog/</link>
		<comments>http://blog.roboblob.com/2010/02/07/list-of-useful-wordpress-plugins-to-use-on-your-blog/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 13:33:52 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=222</guid>
		<description><![CDATA[Number of View: 4757 Let&#8217;s face it, Blogging is fun. Why else would millions of people do it? Its creative, it allows you to speak out to the community, to receive feedback and criticism from people that share your interests or hobbies. On the other side, Blogging can be quite tedious activity if you don&#8217;t]]></description>
			<content:encoded><![CDATA[Number of View: 4757<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Let&#8217;s face it, Blogging is fun. Why else would millions of people do it?</p>
<p>Its creative, it allows you to speak out to the community, to receive feedback and criticism from people that share your interests or hobbies.</p>
<p>On the other side, Blogging can be quite tedious activity if you don&#8217;t use the right tools for it.</p>
<p>To be honest initially i started using <a href="http://wordpress.org/" target="_blank">WordPress</a> for this blog just because i had some brief experience with it few years ago, and my hosting was supporting it out of the box so i looked no further. And boy was i lucky <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>WordPress really is powerful blogging and CMS platform. Its main strength comes from thousands of various <a href="http://wordpress.org/extend/plugins/" target="_blank">plugins </a>that can be used to extend and customize it beyond recognition.</p>
<p>I won&#8217;t go into details on how to add or setup your WordPress installation since this is trivial.</p>
<p>I will just list some cool WordPress plugins i use on regular basis that make my life as blogger much easier and more fun.</p>
<p>So here they are, in (almost) random order:</p>
<ol>
<li><strong><a href="http://www.callum-macdonald.com/code/wp-mail-smtp/" target="_blank">WP-Mail-SMTP</a> &#8211; </strong>this one is my favorite. It allows you to use custom SMTP server for sending any email from your blog. Since many hosting providers block the default PHP email command to prevent spamming, you have to use this plugin to setup WordPress to use your SMTP server to send outgoing emails. If you happen to be one of the (un)fortunate users of GoDaddy&#8217;s hosting like myself, make sure you use these settings for the WP-Mail-SMTP plugin instead of the settings you received from their support when you created the email account:
<p style="padding-left: 30px;">SMTP Server: relay-hosting.secureserver.net</p>
<p style="padding-left: 30px;">SMTP port: 25</p>
<p style="padding-left: 30px;">Encryption: No encryption</p>
<p style="padding-left: 30px;">Authentication: Do not use SMTP authentication</p>
</li>
<li><a href="http://www.ajaxeditcomments.com/" target="_blank"><strong>WP Ajax Edit Comments</strong></a> &#8211; this one allows your users to alter their comments on your posts if they made some mistake or just want to add more text etc. Everything is highly configurable and you can set time limits, configure which fields can be modified etc. Its very annoying for blog visitors when they realize that they made a typo in their comment so this nice plugin gives them opportunity to fix this easily so its must have in my opinion.</li>
<li><a href="http://fairyfish.net/2008/11/03/comment-reply-notification/" target="_blank"><strong>Comment Reply Notification</strong></a> &#8211; this plugin is also comment related and allows users to be notified if someone replies to their comment on your blog. Its user friendly so they can uncheck a checkbox and do not receive notifications etc</li>
<li><a href="http://akismet.com/" target="_blank"><strong>Akismet</strong></a> &#8211; this is installed by default with WordPress but still i want to mention it. Akismet filters spam comments based on large online spammers list so it makes your life easier &#8211; you dont have to constantly waste your time on marking bogus comments as spam &#8211; this plugin does this automatically for you. One drawback is that in order to use it you have to create an WordPress API account but this is very easy and its worth it i can tell you that from my personal experience.</li>
<li><a href="http://www.aldentorres.com/light-social-wordpress-plugin/" target="_blank"><strong>Light Social</strong></a> &#8211; this plugin ads small social bookmarking widget on bottom of the each page and post that allows your readers to bookmark your content on various social bookmarking websites. It has it all: Delicious, DotNetKicks, Reddit, Digg, Stumbleupon, Tecnorati etc)</li>
<li><a href="http://www.642weather.com/weather/scripts-wordpress-si-contact.php" target="_blank"><strong>Fast and Secure Contact Form</strong></a> &#8211; with this one you can easily put contact forms on your blog (on posts, pages, widgets etc) to allow you readers to send you some feedback. Its highly customizable and currently i use only small part of its features but still i find it very useful. Off course there is an option to protect your forms from spammers by adding CAPTCHA otherwise it would be useless.</li>
<li><a href="http://www.viper007bond.com/wordpress-plugins/syntaxhighlighter/" target="_blank"><strong>SyntaxHighlighter Evolved</strong></a> &#8211; if you are posting sourecode on your blog then this plugin you simply cannot avoid. It uses the <a onclick="javascript:pageTracker._trackPageview('/outbound/article/http://alexgorbatchev.com/wiki/SyntaxHighlighter');" href="http://alexgorbatchev.com/wiki/SyntaxHighlighter" target="_blank">SyntaxHighlighter JavaScript package by Alex Gorbatchev</a> to do the highlighting and therefore supports all of the popular programming languages and works and looks very nice.</li>
<li><a href="http://www.arnebrachhold.de/redir/sitemap-home/" target="_blank"><strong>Google XML Sitemaps</strong></a> &#8211; Search Engine Optimization is very important if you want your blog to reach your readers so be sure to install this plugin. It adds XML sitemaps to your blog for all important search engines and it will instantly increase the visibility of your posts.</li>
<li><a href="http://nooshu.com/wordpress-plug-in-post-ideas-plus/" target="_blank"><strong>Post Ideas+</strong></a> &#8211; this one helps you easily write down ideas for future blog posts directly on your blog so you don&#8217;t have to memorize them or write on small papers that you will later lose. If you keep forgetting things like me you will use this plugin very often <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
<li><a href="http://www.642weather.com/weather/scripts-wordpress-visitor-maps.php" target="_blank"><strong>Visitor Maps and Who&#8217;s Online</strong></a> &#8211; this plugin keeps track of all your visitors on all pages of your Blog and then allows you to see detailed statistics about every visit. It uses <a href="http://www.maxmind.com" target="_blank"><strong>GeoLiteCity</strong></a> free online database to determine the city of the visitor based on his IP Address. So you can see and publicly show map of the world with pinpoint markers of cities of your visitors &#8211; very nice!</li>
<li><a href="http://www.backupify.com/" target="_blank"><strong>Backupify for WordPress</strong></a> &#8211; this plugin allows you to make full backup of your WordPress blog &#8211; Just in case! You have to create an account with Backupify.com but this you should do anyway since it supports backups of many other services like Twitter, GMail etc. Backup everything i say!</li>
</ol>
<p>Without all these cool plugins it would be so hard to create content for my blog that i would probably gave it up long time ago (or never even started it in the first place).</p>
<p>So i recommend you to take a look on each of them and try them out on your WordPress blog &#8211; it is very likely that some of them they will become natural part of your Dashboard.</p>
<p>For those of you not using WordPress: what can i say, maybe its time for you to consider a change of Blogging platform? <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>And last but not the least, I&#8217;m sending a <strong><span style="font-size: 20px;">BIG THANK YOU</span></strong> to the authors of WordPress and all its plugins wishing them that they continue with the great work they have been doing so far.</p>
<p>Happy blogging!</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F&amp;title=List+of+useful+WordPress+plugins+to+use+on+your+Blog" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F&amp;title=List+of+useful+WordPress+plugins+to+use+on+your+Blog" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F&amp;title=List+of+useful+WordPress+plugins+to+use+on+your+Blog" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F&amp;headline=List+of+useful+WordPress+plugins+to+use+on+your+Blog" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=List+of+useful+WordPress+plugins+to+use+on+your+Blog&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=List+of+useful+WordPress+plugins+to+use+on+your+Blog&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=List+of+useful+WordPress+plugins+to+use+on+your+Blog&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=List+of+useful+WordPress+plugins+to+use+on+your+Blog&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=List+of+useful+WordPress+plugins+to+use+on+your+Blog&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F&amp;title=List+of+useful+WordPress+plugins+to+use+on+your+Blog&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F02%2F07%2Flist-of-useful-wordpress-plugins-to-use-on-your-blog%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/02/07/list-of-useful-wordpress-plugins-to-use-on-your-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Binding UI Events from View to commands in ViewModel in Silverlight 4</title>
		<link>http://blog.roboblob.com/2010/01/26/binding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4/</link>
		<comments>http://blog.roboblob.com/2010/01/26/binding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 16:05:34 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Behavior]]></category>
		<category><![CDATA[Behaviors]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[DataBinding]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[EventTrigger]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[View]]></category>
		<category><![CDATA[ViewModel]]></category>
		<category><![CDATA[Xaml]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=171</guid>
		<description><![CDATA[Number of View: 39034 In previous two posts we covered wiring up the Views and ViewModels and Blendability and showing ModalDialogs in MVVM way. Today we will touch another problem that people starting with MVVM very often fail to address properly: Handling the UI Events of the View in the ViewModel while avoiding placing any]]></description>
			<content:encoded><![CDATA[Number of View: 39034<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>In previous two posts we covered <a href="http://blog.roboblob.com/2010/01/17/wiring-up-view-and-viewmodel-in-mvvm-and-silverlight-4-blendability-included/">wiring up the Views and ViewModels and Blendability</a> and <a href="http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/">showing ModalDialogs in MVVM way</a>.</p>
<p>Today we will touch another problem that people starting with MVVM very often fail to address properly:</p>
<p><strong>Handling the UI Events of the View in the ViewModel while avoiding placing any logic in code behind of the View.</strong></p>
<p><span style="text-decoration: underline;">So our design goals for this post are:</span></p>
<ul>
<li>We want to be able to wire-up UI Events to the commands in ViewModel via DataBinding in Xaml without any code behind in the View</li>
</ul>
<ul>
<li>View should not be aware of the ViewModel&#8217;s type or any other details of its existence &#8211; View should just use Silverlight&#8217;s DataBinding to access its ViewModel public properties (its DataContext) regardless of what is actually set to be there</li>
</ul>
<ul>
<li>We want to be able to handle any event that occurs in View (that includes not only Button clicks but also Mouse events,  Drag and Drop events, Loaded events etc).</li>
</ul>
<p>When i was trying to solve this problem, i made a mistake.</p>
<p>I coupled the View with ViewModel,  made the View aware of the ViewModel via interface of the ViewModel.</p>
<p>View held the instance of ViewModel in its DataContext.</p>
<p>And then when some event fires in the View i would call a ViewModel method in code behind of the View (accessing it via local variable holding the ViewModel instance casted to interface that ViewModel is implementing).</p>
<p>While this approach works for all events in the View because you can create event handler for any View event, it has many drawbacks.</p>
<p>Main problems are:</p>
<ul>
<li>View has to know about the ViewModel and it has to have a instance of the ViewModel injected somehow</li>
<li>we have to create event handlers in the View code behind .cs file for each event (this can be really boring, and im lazy to do repetitive code so that was really hard for me).</li>
</ul>
<p>I didn&#8217;t like this solution at all and I immediately abandoned it.</p>
<p>Then i tried searching for possible solutions on the web and found the magical <a title="Expression Blend Samples" href="http://expressionblend.codeplex.com/" target="_blank">Expression Blend Samples</a>.</p>
<p>Microsoft introduced Behaviors in Silverlight 3 with Blend 3 to help UI designers to have a flexible new way to add interactivity to applications.</p>
<p>Behaviors allow interactivity to be added to elements directly on the design surface in XAML without having to write additional code.</p>
<p>I will not go into details on Behaviors since there are tons of resources on the web on the subject,  you can read the <a href="http://team.silverlight.net/product-technology-deep-dive/product-feature-highlight-expression-blend-3-ndash-behaviors/">original Blend 3 Behaviors announcement</a> to get more info.</p>
<p>The great thing about Behaviors is that they introduced Triggers and very handy  <a href="http://msdn.microsoft.com/en-us/library/system.windows.eventtrigger%28VS.95%29.aspx" target="_blank">EventTrigger</a> and <a href="http://msdn.microsoft.com/en-us/library/system.windows.triggeraction%28VS.95%29.aspx" target="_blank">TriggerAction</a> classes that are perfect match for our MVVM events scenario.</p>
<p>As you can read on the MSDN link EventTrigger  &#8216;<em>Represents a trigger that applies a set of actions &#8230; in response to an event&#8217;</em>.</p>
<p>So we can create a EventTrigger for some UI event in our View that will fire a custom TriggerAction that will call a method on our ViewModel with some parameters.</p>
<p>On the mentioned Expression Blend Samples page there is already implemented basic class for this &#8211; its called InvokeDataCommand and we will just customize it and extend (generalize it) so it serves our needs.</p>
<p>In the end we want to accomplish something like this in our View&#8217;s Xaml:</p>
<pre class="brush: xml;">
    &lt;Interactivity:Interaction.Triggers&gt;
        &lt;Interactivity:EventTrigger EventName=&quot;MouseMove&quot;&gt;
            &lt;TriggerActions:MapMouseEventToCommand Command=&quot;{Binding Path=ShowMousePositionCommand}&quot; /&gt;
        &lt;/Interactivity:EventTrigger&gt;
    &lt;/Interactivity:Interaction.Triggers&gt;
</pre>
<p>So this is instructing our View to call the command called ShowMousePositionCommand on its ViewModel when mouse pointer is moved over some control.</p>
<p>So lets get started!</p>
<p>First we need to create a command class that we will be able to call from our Events.</p>
<p>Silverlight has only partial support for commanding.</p>
<p>Until Silverlight 4 <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand%28VS.95%29.aspx">ICommand</a> interface was available &#8211; but without any real support or use.<br />
In Silverlight 4 this interface is supported by Button type controls in again partial way:  in <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.buttonbase%28VS.96%29.aspx">ButtonBase</a> class from which all button-like controls inherit, there are two properties: <strong>Command </strong>and <strong>CommandParameter </strong>that you can point to a command that implements ICommand interface and pass it some parameter.</p>
<p>This can be done via DataBinding and when you click the button this command will be executed with the specified parameter. No code solution, pure XAML!<br />
The problem is that Silverlight 4 Beta does not offer any implementation of the ICommand interface so we have to do this by ourselves.</p>
<p>Here is the ICommand interface:</p>
<pre class="brush: csharp;">
namespace System.Windows.Input
{
    public interface ICommand
    {
        bool CanExecute(object parameter);
        void Execute(object parameter);
        abstract event EventHandler CanExecuteChanged;
    }
}
</pre>
<p>So it basically defines a contract: Any command that will implement this interface we we will be able to query it if we can ececute it (CanExecute) and execute it with parameter via its Execute method,  also there is an event CanExecuteChanged so that anyone can subscribe to it in order to be notified if CanExecute status of command has changed (this is used by UI controls so that buttons become disabled if command is disabled etc).</p>
<p>But before we implement this lets make a slight modification and create another interface <strong>IDelegateCommand </strong>that will implement ICommand interface and just add one method RaiseCanExecuteChanged();</p>
<p>This new method is there so that we can invoke it from code if we know that status of our command has changed &#8211; so by invoking it we can notify the UI of this change.</p>
<p>So here is the new IDelegateCommand interface:</p>
<pre class="brush: csharp;">
    public interface IDelegateCommand : ICommand
    {
        void RaiseCanExecuteChanged();
    }
</pre>
<p>And here is our generic version of DelegateCommand class that implements IDelegateCommand and ICommand:</p>
<pre class="brush: csharp;">
  public class DelegateCommand&lt;T&gt; : IDelegateCommand
  {
    private readonly Action&lt;T&gt; executeAction;
    private readonly Func&lt;T, bool&gt; canExecuteAction;

    public DelegateCommand(Action&lt;T&gt; executeAction, Func&lt;T, bool&gt; canExecuteAction)
    {
      this.executeAction = executeAction;
      this.canExecuteAction = canExecuteAction;
    }

    public DelegateCommand(Action&lt;T&gt; executeAction) : this(executeAction, null)
    {
    }

    /// &lt;summary&gt;
    /// Defines the method that determines whether the command can execute in its current state.
    /// &lt;/summary&gt;
    /// &lt;returns&gt;
    /// true if this command can be executed; otherwise, false.
    /// &lt;/returns&gt;
    /// &lt;param name=&quot;parameter&quot;&gt;Data used by the command. If the command does not require data to be passed, this object can be set to null. &lt;/param&gt;
    public bool CanExecute(object parameter)
    {
      if (canExecuteAction != null)
      {
        return canExecuteAction((T) parameter);
      }
      return true;
    }

    /// &lt;summary&gt;
    /// Defines the method to be called when the command is invoked.
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;parameter&quot;&gt;Data used by the command. If the command does not require data to be passed, this object can be set to null. &lt;/param&gt;
    public void Execute(object parameter)
    {
      if (CanExecute(parameter))
      {
        executeAction((T) parameter);
      }
    }

    protected void OnCanExecuteChanged(object sender, EventArgs args)
    {
        var handler = this.CanExecuteChanged;
        if (handler != null)
        {
            handler(sender, args);
        }
    }

    public void RaiseCanExecuteChanged()
    {
        this.OnCanExecuteChanged(this, EventArgs.Empty);
    }

    public event EventHandler CanExecuteChanged;
  }
</pre>
<p>Its simple generic class that allows us to create commands on our ViewModels that will be triggered when needed.</p>
<p>I wont go into much details of this class since there are a lot of posts on this on the web. Be sure to check out <a href="http://compositewpf.codeplex.com/sourcecontrol/changeset/view/26112?projectName=CompositeWPF#498103">Prism DelegateCommand</a> version since my implementation is mostly based on their code.</p>
<p>Now that we have a way of specifying the commands that we will trigger let&#8217;s see how we will trigger them.</p>
<p>Back to our Behaviors:  We will create base generic class that will inherit from TriggerAction&lt;FrameworkElement&gt; and we will use this class to build specific TriggerActions for different UI events:</p>
<pre class="brush: csharp;">
    public abstract class MapEventToCommandBase&lt;TEventArgsType&gt; : TriggerAction&lt;FrameworkElement&gt;
        where TEventArgsType : EventArgs
    {
        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(&quot;Command&quot;, typeof(IDelegateCommand), typeof(MapEventToCommandBase&lt;TEventArgsType&gt;), new PropertyMetadata(null, OnCommandPropertyChanged));
        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(&quot;CommandParameter&quot;, typeof(object), typeof(MapEventToCommandBase&lt;TEventArgsType&gt;), new PropertyMetadata(null, OnCommandParameterPropertyChanged));

        private static void OnCommandParameterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var invokeCommand = d as MapEventToCommand;
            if (invokeCommand != null)
            {
                invokeCommand.SetValue(CommandParameterProperty, e.NewValue);
            }
        }

        private static void OnCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var invokeCommand = d as MapEventToCommand;
            if (invokeCommand != null)
            {
                invokeCommand.SetValue(CommandProperty, e.NewValue);
            }
        }

        protected override void Invoke(object parameter)
        {
            if (this.Command == null)
            {
                return;
            }

            if (this.Command.CanExecute(parameter))
            {
                var eventInfo = new EventInformation&lt;TEventArgsType&gt;
                                    {
                                        EventArgs = parameter as TEventArgsType,
                                        Sender = this.AssociatedObject,
                                        CommandArgument = GetValue(CommandParameterProperty)
                                    };
                this.Command.Execute(eventInfo);
            }
        }

        public IDelegateCommand Command
        {
            get
            {
                return (IDelegateCommand)base.GetValue(CommandProperty);
            }
            set
            {
                base.SetValue(CommandProperty, value);
            }
        }

        public object CommandParameter
        {
            get
            {
                return base.GetValue(CommandParameterProperty);
            }
            set
            {
                base.SetValue(CommandParameterProperty, value);
            }
        }
    }
</pre>
<p>Our MapEventToCommandBase class simply adds Command and CommandParameter DependencyProperties so we can set via DataBinding the command and (optionally) parameter for the event.<br />
It has one type parameter TEventArgsType that it uses so it can send the appropriate EventArgs from the Event that occurred to the command we are calling.<br />
That is why TEventArgsType has a constraint that it has to inherit from EventArgs since every UI event sends some information in a class that inherits from EventArgs or sends EventArgs.Empty.</p>
<p>The meat of this class is the method <strong>Invoke </strong>that overrides the method in its base class TriggerAction.<br />
This method is called from the Silverlight runtime when some event occurs in the UI and the parameter sent is the instance of class that inherits from EventArgs and carries the information specific to that event (MouseEventArgs, DragEventArgs, KeybardEventArgs etc).</p>
<p>What we do in this method is that we take that event information we received and pack it into new class that we will send to our command.</p>
<p>Its this part of code:</p>
<pre class="brush: csharp;">
            if (this.Command.CanExecute(parameter))
            {
                var eventInfo = new EventInformation&lt;TEventArgsType&gt;
                                    {
                                        EventArgs = parameter as TEventArgsType,
                                        Sender = this.AssociatedObject,
                                        CommandArgument = GetValue(CommandParameterProperty)
                                    };
                this.Command.Execute(eventInfo);
            }
</pre>
<p>So we construct the instance of generic EventInformation class of certain EventArgs inheritor type and we include there the sender of the event and the optional argument we sent from XAML binding.</p>
<p>Here is how the generic EventInformation class looks like:</p>
<pre class="brush: csharp;">
    public class EventInformation&lt;TEventArgsType&gt; where TEventArgsType : EventArgs
    {
        public object Sender { get; set; }
        public TEventArgsType EventArgs { get; set; }
        public object CommandArgument { get; set; }
    }
</pre>
<p>It allows us to easily create strongly typed class for each of possible events that can occur in the UI.<br />
For RoutedEvents like Loaded event the RoutedEventArgs will be passed there.</p>
<p>Lets continue. Since our MapEventToCommandBase is abstract and generic class we need to inherit it to be able to actually use it in Xaml so here are some examples of concrete MapSOMEKINDOFEventToCommand implementations:</p>
<p>First <strong>MapMouseEventToCommand</strong>:</p>
<pre class="brush: csharp;">
    public class MapMouseEventToCommand : MapEventToCommandBase&lt;MouseEventArgs&gt;
    {

    }
</pre>
<p>So as you see there is nothing we need to implement here, just to specify the type of the event we want to handle.<br />
If Xaml would support generics we could make the MapEventToCommandBase not to be abstract and use it directly but until Xaml learns to accept generics this is the best way i could figure out.</p>
<p>Then there is the <strong>MapKeyboardEventToCommand</strong>:</p>
<pre class="brush: csharp;">
    public class MapKeyboardEventToCommand : MapEventToCommandBase&lt;KeyEventArgs&gt;
    {

    }
</pre>
<p>So we can do this for any type of event that we need (see the <a href="http://demos.roboblob.com/Silverlight4/MVVM/EventCommands/EventCommandsSolution.zip" target="_self">sample Visual Studio 2010 Project</a> for more examples)</p>
<p>If we don&#8217;t need the specific EventArgs we can also use the MapEventToCommand class that uses EventArgs as its type so it can be used with ANY event.<br />
The drawback is that in the command we will receive the EventInformation&lt;EventArgs&gt; so we need to cast the EventArgs property of that class to some specific EventArgs inheritor class so we lose type safety.</p>
<p>So now that all is in place lets see how we can use our new magic classes from Xaml in Views.</p>
<p>First the simplest event: <strong>Loaded</strong>.</p>
<p>In Xaml of our View we must place this code:</p>
<pre class="brush: xml;">
    &lt;Interactivity:Interaction.Triggers&gt;
        &lt;Interactivity:EventTrigger EventName=&quot;Loaded&quot;&gt;
            &lt;TriggerActions:MapEventToCommand Command=&quot;{Binding Path=LoadedCommand}&quot; CommandParameter=&quot;Shell view loaded at {0:d/M/yyyy HH:mm:ss:fff tt}&quot; /&gt;
        &lt;/Interactivity:EventTrigger&gt;
    &lt;/Interactivity:Interaction.Triggers&gt;
</pre>
<p>So we are creating EventTrigger for event with name &#8220;Loaded&#8221; and for this event we are setting TriggerAction to our MapEventToCommand. This event will trigger when control is loaded and since we use DataBinding to set the Command property, when the event occurs, LoadedCommand on our DataContext will be invoked with the string parameter we hard coded in CommandParameter (we could used DataBinding there also but i skipped this for now to keep things simple).</p>
<p>Next, in our ViewModel we have to define the actual LoadedCommand command.</p>
<p><strong>Important note</strong>: <span style="color: #ff0000;">DO NOT</span><span style="color: #ff0000;"> FORGET</span> to always use OnPropertyChanged in the command&#8217;s property setter if you want all of this to work properly:</p>
<pre class="brush: csharp;">
        private ICommand loadedCommand;
        public ICommand LoadedCommand
        {
            get { return loadedCommand; }
            private set
            {
                loadedCommand = value;
                this.OnPropertyChanged(&quot;LoadedCommand&quot;);
            }
        }
</pre>
<p>Another note: we are defining our command as ICommand property and later we will set them with DelegateCommands instances but this is off course perfectly fine since DelegateCommand implements IDelegateCommand that implements ICommand interface.</p>
<p>And in the constructor of ViewModel with single lambda we added the actual code that will run when command is executed (we just set some string property called LoadedTime to the current DateTime formated by the format text given in the parameter).</p>
<p>Since the View is bound to this LoadedTime property it&#8217;s shown on the control when its changed, triggered by INotifyPropertyChanged:</p>
<pre class="brush: csharp;">
        this.LoadedCommand
            = new DelegateCommand&lt;EventInformation&lt;EventArgs&gt;&gt;
                (p =&gt;
                     {
                         LoadedTime = string.Format(p.CommandArgument.ToString(), DateTime.Now);
                     });
</pre>
<p>Lets see how we would map a <strong>MouseMove </strong>event:</p>
<pre class="brush: xml;">
    &lt;Interactivity:Interaction.Triggers&gt;

        &lt;Interactivity:EventTrigger EventName=&quot;MouseMove&quot;&gt;
            &lt;TriggerActions:MapMouseEventToCommand Command=&quot;{Binding Path=ShowMousePositionCommand}&quot; /&gt;
        &lt;/Interactivity:EventTrigger&gt;

    &lt;/Interactivity:Interaction.Triggers&gt;
</pre>
<p>So we are doing the same thing here only we are using <strong>MapMouseEventToCommand </strong>in stead of the basic MapEventToCommand &#8211; we are doing this so we get strongly typed MouseEventArgs from the original event passed as EventArgs parameter in the EventInformation class that will be passed to the command.</p>
<p>Here is the command definition from our ViewModel:</p>
<pre class="brush: csharp;">
        private ICommand showMousePositionCommand;
        public ICommand ShowMousePositionCommand
        {
            get { return showMousePositionCommand; }
            set { showMousePositionCommand = value;
            this.OnPropertyChanged(&quot;ShowMousePositionCommand&quot;);

            }
        }
</pre>
<p>And here is part of the ViewModel constructor where we actually define the code triggered inside the command:</p>
<pre class="brush: csharp;">
        this.ShowMousePositionCommand
            = new DelegateCommand&lt;EventInformation&lt;MouseEventArgs&gt;&gt;(
            p =&gt;
            {
                this.MousePosition = string.Format(&quot;x:{0} y:{1}&quot;,
                    p.EventArgs.GetPosition(null).X, p.EventArgs.GetPosition(null).Y);
            });
</pre>
<p>What happens here is that when our command is invoked (this is triggered when user moves his mouse pointer in our View) we use the received MouseEventArgs (from EventArgs property) of the EventInformation instance to get the current mouse position and we create a string representation of it and we set a public property on our ViewModel.</p>
<p>And our View is again data-bound to this property &#8211; so it will get notification that its value has changed and re-display it on screen so we will have realtime coordinates of our mouse pointer displayed in the view as we move the pointer.</p>
<p>Check out the <a href="http://demos.roboblob.com/Silverlight4/MVVM/EventCommands/" target="_blank">demo application</a> to see this in action.</p>
<p>So we managed to wire up events from View to the ViewModel in Xaml via DataBinding.</p>
<p>Here is how our View&#8217;s backend code .cs file looks like:</p>
<pre class="brush: csharp;">
using System.Windows.Controls;

namespace EventCommands.Views
{
    public partial class ShellView : UserControl
    {
        public ShellView()
        {
            InitializeComponent();
        }
    }
}
</pre>
<p>As you can see we added zero logic to our View &#8211; its only code generated by the Visual Studio when we created the UserControl for the, so its clean design, decoupled View from the ViewModel, and we can later change our Views and our ViewModels won&#8217;t event notice <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>For those that do not have Silverlight 4 installed yet, here is the screen shot of the running <a href="http://demos.roboblob.com/Silverlight4/MVVM/EventCommands/" target="_blank">demo application</a> showing all the code we have written for this experiment:</p>
<p style="text-align: center;"><a href="http://blog.roboblob.com/wp-content/uploads/2010/01/EventsToCommandsSampleApplication.jpg"><img class="size-medium wp-image-196 aligncenter" title="EventsToCommandsSampleApplication" src="http://blog.roboblob.com/wp-content/uploads/2010/01/EventsToCommandsSampleApplication-300x211.jpg" alt="" width="300" height="211" /></a></p>
<p style="text-align: left;">If you run the application you will see two independent instances of the small sample EventsWidget for showing Events triggered on View.</p>
<p style="text-align: left;">Currently im demonstrating MouseMove event, DragAndDrop event, KeyDown event and also Loaded event.</p>
<p style="text-align: left;">Other UI events can be easily added and are completely supported by the given code.</p>
<p style="text-align: left;">I deliberately added two instances of same widget on the main page so its clear that data binding works independently and that each control can has its own ViewModel and DataBinds events to Commands in its own ViewModel.</p>
<p style="text-align: left;">In same way the main control (ShellView) has its own ViewModel and its own Events DataBound to commands in its own ViewModel etc.</p>
<p style="text-align: left;">You can download the sample application Visual Studio 2010 solution <a href="http://demos.roboblob.com/Silverlight4/MVVM/EventCommands/EventCommandsSolution.zip" target="_self">here</a>.</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F&amp;title=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F&amp;title=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F&amp;title=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F&amp;headline=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F&amp;title=Binding+UI+Events+from+View+to+commands+in+ViewModel+in+Silverlight+4&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F26%2Fbinding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/01/26/binding-ui-events-from-view-to-commands-in-viewmodel-in-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Modal dialogs with MVVM and Silverlight 4</title>
		<link>http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/</link>
		<comments>http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 14:15:39 +0000</pubDate>
		<dc:creator>roboblob</dc:creator>
				<category><![CDATA[MVVM]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[ModalDialog]]></category>
		<category><![CDATA[View]]></category>
		<category><![CDATA[ViewModel]]></category>

		<guid isPermaLink="false">http://blog.roboblob.com/?p=109</guid>
		<description><![CDATA[In this post i would like to tackle another problem that is very common in MVVM and yet very rarely done correctly.

I will try to provide simple and platform agnostic way of showing Modal Dialogs in MVVM manner without any code in View (later in the post we will reuse same concept and provide way to show simple message dialogs in the same way).]]></description>
			<content:encoded><![CDATA[Number of View: 16772<br/><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>In the <a href="http://blog.roboblob.com/2010/01/17/wiring-up-view-and-viewmodel-in-mvvm-and-silverlight-4-blendability-included/" target="_blank">previous post</a> we covered how to show Views and how to wire them up with their ViewModels while preserving ability to correctly see their preview in Visual Studio and Blend design mode.</p>
<p>In this post i would like to tackle another problem that is very common in MVVM and yet very rarely done correctly.</p>
<p>I will try to provide simple and platform agnostic way of showing Modal Dialogs in MVVM manner without any code in View (later in the post we will reuse same concept and provide way to show simple message dialogs in the same way).</p>
<p>For those of you that have no patience here is the <a href="http://demos.roboblob.com/Silverlight4/MVVM/ModalDialogs/" target="_blank">demo application</a> that shows dialogs in action. On the main page there are two identical views each of them showing a list of users. For each user if you click the Edit button you will see the modal dialog to edit users properties.<br />
Del button shows the message dialog to confirm deleting of the user n or to cancel it.</p>
<p>So lets begin: Actual implementation of the concept will be done in Silverlight 4 but it can be easily and without any pain converted to any other UI platform like WPF etc.</p>
<p>Our main design goals are:</p>
<ol>
<li>Platform agnostic solution to show modal dialogs that could be easily reused in WPF (or any other platform that supports concept of dialogs)</li>
<li>We want our modal dialogs to be triggered by some UI event in our Views (like click on the button etc) but not from codebehind of the view</li>
<li>Actual logic of showing dialogs must reside in ViewModel and NEVER (oh never) in code behind of the dialog (View)</li>
<li>Dialogs must support MVVM pattern themselves so they should be able to bind to their ViewModel if needed</li>
<li>Dialogs should be able to return result to the caller (maybe we wont need this always but there must be a way if needed)</li>
</ol>
<p>Nice thing that could help us a lot is that Silverlight 3/4 comes with very handy <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.childwindow%28VS.95%29.aspx" target="_blank">ChildWindow</a> control that is perfect fit for what we are trying to do, so we will try to reuse it in smart way.</p>
<p>The question remains how to use Silverlight ChildWindow class with MVVM pattern and to remain decoupled from anything that is platform specific about it.</p>
<p>We will first take the most important things that each Modal Dialog should have and extract this to separate interface IModalWindow:</p>
<pre class="brush: csharp;">
  public interface IModalWindow
  {
    bool? DialogResult { get; set; }
    event EventHandler Closed;
    void Show();
    object DataContext { get; set; }
    void Close();
  }
</pre>
<p>As you can see IModalWindow is almost like an 1:1 abstraction of ChildWindow class <img src='http://blog.roboblob.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
But its important to note here that IModalWindow contains only pure .NET constructs so it does not have anything Silverlight specific so that means we can implement this interface and create modal dialog controls in any .NET platform (WPF, WinForms etc).</p>
<p>IModalWindow has Show and Close methods, then it has DataContext so we can bind it to its ViewModel, then there is DialogResult boolean property to tell us if user confirmed the action or not, and it has event handler so we can hook to it when dialog is closed to pickup some results or do other actions (if we need it).</p>
<p>In order to be able to actually show dialogs that implement IModalWindow to our user we will introduce another layer of abstraction &#8211; it will be service that implements IModalDialogService interface that will have generic methods for showing the dialogs and completely hide the details of the implementation &#8211; as we said this should be platform agnostic so interface will contain nothing specific to Silverlight.</p>
<p>here is how the IModalDialogService interface looks:</p>
<pre class="brush: csharp;">
  public interface IModalDialogService
  {
    void ShowDialog&lt;TViewModel&gt;(IModalWindow view, TViewModel viewModel, Action&lt;TViewModel&gt; onDialogClose);

    void ShowDialog&lt;TDialogViewModel&gt;(IModalWindow view, TDialogViewModel viewModel);
  }
</pre>
<p>Our service interface defines two methods, first is one when when we want to specify OnClose handler so that we can do some action when dialog is closed and second overload is for showing modal dialogs in &#8216;Fire and forget&#8217; mode without knowing when or how the dialog is closed.</p>
<p>Both ShowDialog methods are generic, accepting TViewModel type where we specify type of the ViewModel for our dialog (usually this is ViewModel interface). If we don&#8217;t need ViewModel for the dialog we can always set this to null.</p>
<p>So when showing dialog we pass the actual dialog &#8211; the View (i will explain later how we will get it) and its ViewModel and optionally we define an Action that is called when the dialog is closed (with the ViewModel instance of the dialog as the parameter &#8211; this is how we can get the results of the dialog or data user entered on the dialog etc).</p>
<p>And finally lets see how the Silverlight version of the ModalDialogService is implemented:</p>
<pre class="brush: csharp;">
  public class ModalDialogService : IModalDialogService
  {
    public void ShowDialog&lt;TDialogViewModel&gt;(IModalWindow view, TDialogViewModel viewModel, Action&lt;TDialogViewModel&gt; onDialogClose)
    {
      view.DataContext = viewModel;
      if (onDialogClose != null)
      {
        view.Closed += (sender, e) =&gt; onDialogClose(viewModel);
      }
      view.Show();
    }

    public void ShowDialog&lt;TDialogViewModel&gt;(IModalWindow view, TDialogViewModel viewModel)
    {
      this.ShowDialog(view, viewModel, null);
    }
  }
</pre>
<p>Implementation as you can see is very simple.<br />
Service just sets the passed ViewModel to the DataContext of the passed dialog view, attaches the OnClose handler if we provided it and finally shows the view.</p>
<p>Now lets see the XAML and codebehind of one simple dialog we defined in sample application &#8211; dialog to edit user detials:</p>
<pre class="brush: xml;">
&lt;controls:ChildWindow x:Class=&quot;MvvmModalDialogs.Views.EditUserModalDialogView&quot;
           xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
           xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
           xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
           xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot; mc:Ignorable=&quot;d&quot;
           xmlns:controls=&quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls&quot; xmlns:DummyViewModels=&quot;clr-namespace:MvvmModalDialogs.ViewModels.DummyViewModels&quot; Width=&quot;400&quot; Height=&quot;300&quot;
           Title=&quot;Edit User&quot; d:DataContext=&quot;{Binding Source={StaticResource viewModel}}&quot; &gt;
    &lt;controls:ChildWindow.Resources&gt;
        &lt;DummyViewModels:DummyEditUserModalDialogViewModel x:Key=&quot;viewModel&quot; &gt;&lt;/DummyViewModels:DummyEditUserModalDialogViewModel&gt;
    &lt;/controls:ChildWindow.Resources&gt;
  &lt;Grid x:Name=&quot;LayoutRoot&quot; Margin=&quot;2&quot;&gt;
    &lt;Grid.RowDefinitions&gt;
      &lt;RowDefinition /&gt;
      &lt;RowDefinition Height=&quot;Auto&quot; /&gt;
    &lt;/Grid.RowDefinitions&gt;

        &lt;TextBlock Text=&quot;{Binding Path=User.FullName}&quot; HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot; /&gt;

        &lt;StackPanel Orientation=&quot;Horizontal&quot; Grid.Row=&quot;1&quot; HorizontalAlignment=&quot;Right&quot; VerticalAlignment=&quot;Center&quot;&gt;
            &lt;Button x:Name=&quot;CancelButton&quot; Content=&quot;Cancel&quot; Click=&quot;CancelButton_Click&quot; Width=&quot;75&quot; Height=&quot;23&quot; HorizontalAlignment=&quot;Right&quot; Margin=&quot;0,5,20,5&quot;  /&gt;
            &lt;Button x:Name=&quot;OKButton&quot; Content=&quot;OK&quot; Click=&quot;OKButton_Click&quot; Width=&quot;75&quot; Height=&quot;23&quot; HorizontalAlignment=&quot;Right&quot; Margin=&quot;0,5,20,5&quot;  /&gt;
        &lt;/StackPanel&gt;

        &lt;Grid Height=&quot;142&quot; HorizontalAlignment=&quot;Center&quot; Margin=&quot;30,17,0,0&quot; Name=&quot;grid1&quot; VerticalAlignment=&quot;Center&quot; Width=&quot;310&quot;&gt;
            &lt;Grid.RowDefinitions&gt;
                &lt;RowDefinition Height=&quot;32*&quot; /&gt;
                &lt;RowDefinition Height=&quot;33*&quot; /&gt;
                &lt;RowDefinition Height=&quot;32*&quot; /&gt;

            &lt;/Grid.RowDefinitions&gt;
            &lt;Grid.ColumnDefinitions&gt;
                &lt;ColumnDefinition Width=&quot;84*&quot; /&gt;
                &lt;ColumnDefinition Width=&quot;31*&quot; /&gt;
                &lt;ColumnDefinition Width=&quot;195*&quot; /&gt;
            &lt;/Grid.ColumnDefinitions&gt;
            &lt;TextBlock Grid.Row=&quot;0&quot; Grid.Column=&quot;0&quot; Height=&quot;23&quot; HorizontalAlignment=&quot;Right&quot;  Text=&quot;User Id:&quot; VerticalAlignment=&quot;Center&quot;  /&gt;
            &lt;TextBlock Height=&quot;23&quot; HorizontalAlignment=&quot;Stretch&quot;  Text=&quot;{Binding User.Id}&quot; VerticalAlignment=&quot;Center&quot; Grid.Row=&quot;0&quot; Grid.Column=&quot;2&quot; /&gt;

            &lt;TextBlock Grid.Row=&quot;1&quot; Grid.Column=&quot;0&quot; Height=&quot;23&quot; HorizontalAlignment=&quot;Right&quot;  Text=&quot;Username:&quot; VerticalAlignment=&quot;Center&quot;  /&gt;
            &lt;TextBox Height=&quot;23&quot; HorizontalAlignment=&quot;Stretch&quot;  Text=&quot;{Binding User.Username, Mode=TwoWay}&quot; VerticalAlignment=&quot;Center&quot; Grid.Row=&quot;1&quot; Grid.Column=&quot;2&quot; /&gt;

            &lt;TextBlock Grid.Row=&quot;2&quot; Grid.Column=&quot;0&quot; Height=&quot;23&quot; HorizontalAlignment=&quot;Right&quot;  Text=&quot;Is Admin:&quot; VerticalAlignment=&quot;Center&quot;  /&gt;
            &lt;CheckBox Height=&quot;23&quot; HorizontalAlignment=&quot;Stretch&quot; IsChecked=&quot;{Binding User.IsAdmin, Mode=TwoWay}&quot; VerticalAlignment=&quot;Center&quot; Grid.Row=&quot;2&quot; Grid.Column=&quot;2&quot; /&gt;

        &lt;/Grid&gt;
    &lt;/Grid&gt;
&lt;/controls:ChildWindow&gt;
</pre>
<p>So its just simple ChildWindow control, that has few TextBoxes to show and edit details of one User instance.</p>
<p>And in the codebehind of the ChildWindow control we just mark it as implementor of our IChildWindow interface (and we set the DialogResult to true if user clicked OK button, but this can be done in &#8216;pure&#8217; way via DelegateCommand i just used codebehind here for simplicity and because its not part of the business logic, its concern of the UI to tell us if the user closed dialog by clicking on OK button or not).</p>
<pre class="brush: csharp;">
    public partial class EditUserModalDialogView : IModalWindow
    {
        public EditUserModalDialogView()
        {
            InitializeComponent();
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }
    }
 </pre>
<p>So all this gives us a completely platform agnostic solution to modal dialogs, and yet we used the powerful ChildWindow control that comes with Silverlight.<br />
If we later decide to implement our modal dialogs in a different way we can do this easily just by creating a different control that implements IChildWindow and we are cool, nothing needs to be changed in our code that shows the dialogs.</p>
<p>So now how would we use this dialog in code?</p>
<p>There is one more peace of the puzzle to solve. We need to register our dialog controls somehow so we can easily pass them to our IModalService to show them so i will use <a href="http://en.wikipedia.org/wiki/Service_locator_pattern" target="_blank">ServiceLocator</a> pattern for this.</p>
<p>We will create a Bootstrapper class that will be called in App.xaml.cs on application startup and this class will have task to register all common dialogs that we will be using in our application:</p>
<pre class="brush: csharp;">
public class Bootstrapper
    {
        public static void InitializeIoc()
        {
            SimpleServiceLocator.SetServiceLocatorProvider(new UnityServiceLocator());
            SimpleServiceLocator.Instance.Register&lt;IModalDialogService, ModalDialogService&gt;();
            SimpleServiceLocator.Instance.Register&lt;IMessageBoxService, MessageBoxService&gt;();
            SimpleServiceLocator.Instance.Register&lt;IMainPageViewModel, MainPageViewModel&gt;();

            SimpleServiceLocator.Instance.Register&lt;IModalWindow, EditUserModalDialogView&gt;(Constants.EditUserModalDialog);
        }
    }
</pre>
<p>As you can see we are registering (among other things) EditUserModalDialogView that is in fact ChildWindow control as implementor of IModalWindow interface under a name from constants (Constants is the class holding distinct string names for each of the dialog types we want to use in application).</p>
<p>So now that everything is set, and our ServiceLocator knows of our dialogs, we can retrieve new instance of any of our dialogs to show them from the ViewModel of some view (when some button is clicked inside a DelegateCommand etc).</p>
<p>In this example i have only one dialog type that is implementing IModalWindow interface &#8211; EditUserModalDialogView, but i could have had many different types of dialogs that i will be showing to users so i would register them all in the Boostrapper as implementors of IModalWindow but under different named constants.<br />
Then i would just retrieve the one i need by asking my service locator for a type that implements IModalWindow and supplying a string key that would determine which dialog exactly i need.</p>
<p>For example to retrieve instance of EditUserModalDialogView i would type this:</p>
<pre class="brush: csharp;">
var dialog = SimpleServiceLocator.Instance.Get&lt;IModalWindow&gt;(Constants.EditUserModalDialog);
</pre>
<p>In order to just show dialog without any ViewModel or OnClose callback i would do this:</p>
<pre class="brush: csharp;">
var dialog = SimpleServiceLocator.Instance.Get&lt;IModalWindow&gt;(Constants.EditUserModalDialog);
this.modalDialogService.ShowDialog(dialog, null);
</pre>
<p>or to set ViewModel for the dialog i could do this:</p>
<pre class="brush: csharp;">
var dialog = SimpleServiceLocator.Instance.Get&lt;IModalWindow&gt;(Constants.EditUserModalDialog);
this.modalDialogService.ShowDialog(dialog, new EditUserModalDialogViewModel
{
User = userInstanceToEdit
});
</pre>
<p>These were all simple cases. Now lets see how we can show dialog from DelegateCommand in ViewModal when user clicks on some Button in View, and also let&#8217;s set a callback function to be called when dialog is closed so we can do something meaningful like updating user details:</p>
<p>First we crate button on View to trigger the action and bind its Command property to a DelegateCommand in ViewModel and use binding for CommandParameter (in this case binding is the actual User instance):</p>
<pre class="brush: xml;">
&lt;Button Content=&quot;Edit&quot; Command=&quot;{Binding Source={StaticResource viewModelLocator}, Path=ViewModel.ShowUserCommand}&quot; CommandParameter=&quot;{Binding}&quot; /&gt;
</pre>
<p>And now in the ViewModel in the ShowUserCommand DelegateCommand we place the code to show the dialog and update Users collection afterwards if needed:</p>
<pre class="brush: csharp;">
        this.ShowUserCommand = new DelegateCommand&lt;User&gt;(userInstanceToEdit =&gt;
        {
          var dialog = SimpleServiceLocator.Instance.Get&lt;IModalWindow&gt;(Constants.EditUserModalDialog);
          this.modalDialogService.ShowDialog(dialog, new EditUserModalDialogViewModel
          {
            User = userInstanceToEdit
          },
          returnedViewModelInstance =&gt;
          {
            if (dialog.DialogResult.HasValue &amp;&amp; dialog.DialogResult.Value)
            {
            var oldPos = this.Users.IndexOf(userInstanceToEdit);
            this.Users.RemoveAt(oldPos);
            this.Users.Insert(oldPos, returnedViewModelInstance.User);
            }
            });
        });
</pre>
<p>So basically im setting the DelegateCommand (see details of the DelegateCommand implementation in the <a href="http://demos.roboblob.com/Silverlight4/MVVM/ModalDialogs/MvvmModalDialogsInSL4.zip">project attached to the post</a>) with code to retrieve the Edit User dialog from the ServiceLocator.<br />
Then im calling services ShowDialog method, passing the new instance of EditUserModalDialogViewModel as the ViewModel of the dialog (containing the user instance i want to edit) and im passing lamda for onDialogClose callback to remove old instance of the User from Users collection on ViewModel and replace it with the new one we received from the dialog.<br />
Off course im first checking if user clicked on Ok button (using dialog.DialogResult property to check that).</p>
<p>And there you have it: simple MVVM solution for modal dialogs that you can port to any platform and implement with any kind of control or popup you want.</p>
<p>To show this concept in more detail i created another similar service to show message boxes to the user.<br />
Again we have the service interface &#8211; IMessageBoxService that offers two ways of showing message boxes, first one more complex where we specify message, caption and buttons displayed on the message box and second one, simpler where we just specify message and caption, so only OK button is shown to the user:</p>
<pre class="brush: csharp;">
  public interface IMessageBoxService
  {
    GenericMessageBoxResult Show(string message, string caption, GenericMessageBoxButton buttons);
    void Show(string message, string caption);
  }
</pre>
<p>I also created abstractions for the common button types and return results so we don&#8217;t depend on Silverlight MessageBox class (that we will use underneath) is using:</p>
<pre class="brush: csharp;">
  public enum GenericMessageBoxButton
  {
    Ok,
    OkCancel
  }

  public enum GenericMessageBoxResult
  {
    Ok,
    Cancel
  }
</pre>
<p>So lets see how the actual Silverlight implementation of IMessageBoxService interface would look like:</p>
<pre class="brush: csharp;">
  public class MessageBoxService : IMessageBoxService
  {
    public GenericMessageBoxResult Show(string message, string caption, GenericMessageBoxButton buttons)
    {
      var slButtons = buttons == GenericMessageBoxButton.Ok
                        ? MessageBoxButton.OK
                        : MessageBoxButton.OKCancel;

      var result = MessageBox.Show(message, caption, slButtons);

      return result == MessageBoxResult.OK ? GenericMessageBoxResult.Ok : GenericMessageBoxResult.Cancel;
    }

      public void Show(string message, string caption)
      {
          MessageBox.Show(message, caption, MessageBoxButton.OK);
      }
  }
</pre>
<p>Again its very simple, we are using the built in Silverlight&#8217;s MessageBox class to show the actual message box but later we can decide its not good enough and implement it in another way (maybe with 3rd party message box component etc) yet our code in ViewModel wont change since it will be talking only to our interface.</p>
<p>Here is the example of how i use this MessageBoxService in the demo project for this post:</p>
<pre class="brush: csharp;">
        this.DeleteUserCommand = new DelegateCommand&lt;User&gt;(p =&gt;
        {
          var result = this.messageBoxService.Show(string.Format(&quot;Are you sure you want to delete user {0} ???&quot;, p.Username),
              &quot;Please Confirm&quot;, GenericMessageBoxButton.OkCancel);
          if (result == GenericMessageBoxResult.Ok)
          {
            this.Users.Remove(p);
          }
        });
</pre>
<p>What i do here is just set the DelegateCommand in ViewModel to first show the message box with Ok and Cancel buttons and if user pressed Ok do some action &#8211; delete from the list.</p>
<p>So i think this two solutions covered all design goals we set on the start: we have decoupled way of showing modal dialogs and message boxes currently done in Silverlight but they could be easily converted to another platform.<br />
Also approach is MVVM friendly without any hacks so any pattern purist can be satisfied with it.<br />
If you have some concerns or suggestions on this approach i would be happy to hear it!</p>
<p>Here is the attached <a href="http://demos.roboblob.com/Silverlight4/MVVM/ModalDialogs/MvvmModalDialogsInSL4.zip" target="_self">VS 2010 solution with full source code</a> from the post.<br />
<a href="http://demos.roboblob.com/Silverlight4/MVVM/ModalDialogs/" target="_blank">Live demo</a> of the application showing modal dialogs and message boxes flying around the screen.</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F&amp;title=Modal+dialogs+with+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F&amp;title=Modal+dialogs+with+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F&amp;title=Modal+dialogs+with+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F&amp;headline=Modal+dialogs+with+MVVM+and+Silverlight+4" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Modal+dialogs+with+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Modal+dialogs+with+MVVM+and+Silverlight+4&amp;u=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Modal+dialogs+with+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Modal+dialogs+with+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Modal+dialogs+with+MVVM+and+Silverlight+4&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F&amp;title=Modal+dialogs+with+MVVM+and+Silverlight+4&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fblog.roboblob.com%2F2010%2F01%2F19%2Fmodal-dialogs-with-mvvm-and-silverlight-4%2F" ><img class="lightsocial_img" src="http://blog.roboblob.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
	</channel>
</rss>
