<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET &amp; Funky Fresh : databinding, NHProf</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/NHProf/default.aspx</link><description>Tags: databinding, NHProf</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Porting NHProf from WPF to Silverlight – Day 7</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/06/porting-nhprof-from-wpf-to-silverlight-day-7.aspx</link><pubDate>Wed, 07 Apr 2010 02:21:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56774</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=56774</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/06/porting-nhprof-from-wpf-to-silverlight-day-7.aspx#comments</comments><description>&lt;p&gt;Today I worked on statements.&amp;nbsp; They flow pretty naturally out of the sessions functionality.&amp;nbsp; I still have a lot of work ahead of me, so fortunately I only found two new issues today.&amp;nbsp; I was able to rework Xaml in both cases fairly easily.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Binding in it&amp;rsquo;s Element form is not allowed.&amp;nbsp; Fortunately, I was able to rework it as a markup extension.&lt;/li&gt;
&lt;li&gt;ContentControl.ContentStringFormat is missing. I was able to use the StringFormat built into the BindingExtension instead.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Screenshot is below.&amp;nbsp; Aside from the hideous styles&amp;hellip;it&amp;rsquo;s actually &lt;a href="http://nhprof.com/"&gt;starting to resemble itself&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay7_5F00_55BB9924.jpg"&gt;&lt;img height="829" width="1104" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay7_5F00_thumb_5F00_506CB273.jpg" alt="NHProf Day 7" border="0" title="NHProf Day 7" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56774" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHProf/default.aspx">NHProf</category></item><item><title>Porting NHProf from WPF to Silverlight – Day 6</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/05/porting-nhprof-from-wpf-to-silverlight-day-6.aspx</link><pubDate>Mon, 05 Apr 2010 21:44:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56743</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=56743</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/05/porting-nhprof-from-wpf-to-silverlight-day-6.aspx#comments</comments><description>&lt;p&gt;I started working on the most complicated part of the UI: Sessions. There are a lot of different view models and views related to this part. Fortunately, by now, I think I have found most of the issues. But I&amp;rsquo;m still encountering a few new issues here on day six. Below is the customary screenshot and issue list.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay6_5F00_12B943FD.jpg"&gt;&lt;img height="758" width="1004" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay6_5F00_thumb_5F00_4DA076C6.jpg" alt="NHProf Day 6" border="0" title="NHProf Day 6" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Styles don&amp;rsquo;t have Resources. We are probably going to have to re-write all of our styles and control template. So, our new solution will take this into account.&lt;/li&gt;
&lt;li&gt;ControlTemplate cannot have triggers.&amp;nbsp; See above.&lt;/li&gt;
&lt;li&gt;ControlTemplate cannot have resources. See above.&lt;/li&gt;
&lt;li&gt;Uri is missing PathAndQuery &amp;ndash; I implemented this manually by combinding AbsoluteUri and QueryString with a &amp;lsquo;?&amp;rsquo; in between.&lt;/li&gt;
&lt;li&gt;MultiBinding is missing. We are going to do some major rework on that view unfortunately. I&amp;rsquo;ll try and provide more details later. Skipped it for now&amp;hellip;&lt;/li&gt;
&lt;li&gt;No ReaderWriterLockSlim. This was surprising. I really wasn&amp;rsquo;t sure what to do, so I used a standard lock for now.&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56743" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Control+Templates/default.aspx">Control Templates</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHProf/default.aspx">NHProf</category></item><item><title>Porting NHProf from WPF to Silverlight – Day 5</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/02/porting-nhprof-from-wpf-to-silverlight-day-5.aspx</link><pubDate>Fri, 02 Apr 2010 16:31:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56534</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=56534</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/02/porting-nhprof-from-wpf-to-silverlight-day-5.aspx#comments</comments><description>&lt;p&gt;Well, I&amp;rsquo;m pleased to say that on Wednesday I only encountered one new* issue during the port.&amp;nbsp; ListBox does not support grouping.&amp;nbsp; One neat thing in WPF is that all the items controls supported grouping.&amp;nbsp; One of the reports we had was a set of master/details grids where the master was a grouped ListBox. Needless to say, this entire report had to be redesigned to work around this issue. Truth be told, I never really liked the way that report was set up. As a solution I decided to use the Silverlight DataGrid with two levels of grouping. That issue aside, it was pretty quick work to port all the reports.&amp;nbsp; As part of the process, I made the reports mechanism a little easier to maintain. Basically, anything that implements IReport will appear in the report list, will be added to the reports menu and will automatically have its view bound appropriately.&amp;nbsp; Yay for IoC and Caliburn!&amp;nbsp; Here&amp;rsquo;s a screenshot:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay5_5F00_33E94A78.jpg"&gt;&lt;img height="715" width="947" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay5_5F00_thumb_5F00_03C1FFB5.jpg" alt="NHProf Day 5" border="0" title="NHProf Day 5" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;*Just as a reminder: When I say &amp;ldquo;new&amp;rdquo; issues I don&amp;rsquo;t want to insinuate that it is the &amp;ldquo;only&amp;rdquo; issue I encountered while working. I have encountered dozens of issues every day. But I am only recording here issues that I find that I haven&amp;rsquo;t previously encountered on this project.&amp;nbsp; Trying to track every &amp;ldquo;instance&amp;rdquo; of an issue would be unmanageable.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56534" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHProf/default.aspx">NHProf</category></item><item><title>Porting NHProf from WPF to Silverlight – Day 4</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/01/porting-nhprof-from-wpf-to-silverlight-day-4.aspx</link><pubDate>Thu, 01 Apr 2010 18:36:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56450</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=56450</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/01/porting-nhprof-from-wpf-to-silverlight-day-4.aspx#comments</comments><description>&lt;p&gt;On Tuesday I spent a decent amount of time fleshing out the last remaining features under the Options menu. I then did some general reorganization to the project structure. Along with the port to Silverlight, I&amp;rsquo;ve been upgrading the application to use Caliburn 2.0 which is working out exceedingly well :) In fact, some of Caliburn&amp;rsquo;s features are making it very easy to work around the differences between the WPF and Silverlight platforms. After the reorganization, I decided I would start porting over the reports.&amp;nbsp; As has been my pattern, below is a screenshot and the list of *new* issues I encountered. I&amp;rsquo;m really glad there weren&amp;rsquo;t as many as on Monday&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay4_5F00_7D40096B.jpg"&gt;&lt;img height="650" width="880" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay4_5F00_thumb_5F00_1F2B6BF0.jpg" alt="NHProf Day 4" border="0" title="NHProf Day 4" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;UpdateSourceTrigger=PropertyChanged is missing.&amp;nbsp; There are workarounds which wire for events and manually update the bindings. I used Caliurn 2.0&amp;rsquo;s C over C binding to do this automatically :)&lt;/li&gt;
&lt;li&gt;RelativeSource FindAncestor is missing. Fortunately, I replaced our homegrown grid with the Silverlight DataGrid and was able to eliminate the need for this in this scenario.&lt;/li&gt;
&lt;li&gt;Hyperlink.Tag is is missing. Strange isn&amp;rsquo;t it.&amp;nbsp; I reworked the code to use a HyperlinkButton.&lt;/li&gt;
&lt;li&gt;Binding.StringFormat syntax is different. In WPF, you escape like this Text=&amp;quot;{Binding AverageStatementsPerSession, StringFormat={}{0:0.#},FallbackValue=0}&amp;quot;&amp;nbsp; but that causes a compile-time error in Silverlight.&amp;nbsp; What is worse is that it doesn&amp;rsquo;t tell you where. It just complains that there is something wrong with a markup extensions somewhere in your Xaml. I fixed it with the following change&amp;nbsp; Text=&amp;quot;{Binding AverageStatementsPerSession, StringFormat=\{0:0.#\},FallbackValue=0}&amp;quot;&lt;/li&gt;
&lt;li&gt;GridSplitter is missing ResizeBehavior and ResizeDirection.&amp;nbsp; Fortunately, it seams to work pretty well without them. I have a couple of issues with this that I still need to look into though.&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56450" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Control+Templates/default.aspx">Control Templates</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHProf/default.aspx">NHProf</category></item><item><title>Porting NHProf from WPF to Silverlight - Day 3</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/31/porting-nhprof-from-wpf-to-silverlight-day-3.aspx</link><pubDate>Wed, 31 Mar 2010 13:58:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56354</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=56354</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/31/porting-nhprof-from-wpf-to-silverlight-day-3.aspx#comments</comments><description>&lt;p&gt;On Monday I spent a good four hours working on the port. I decided to flesh out the functionality of the Main Menu. &lt;a href="http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/29/porting-nhprof-from-wpf-to-silverlight-day-2.aspx"&gt;As I mentioned before&lt;/a&gt;, none of the menu controls available support commanding. Fortunately, &lt;a href="http://caliburn.codeplex.com/"&gt;Caliburn&lt;/a&gt; has its own mechanism which is much richer than what you get out of the box anyways. So, I began hooking this up, fleshing out the appropriate commands and implementing the various features of the application related to them. This approach actually brought me in touch with a very wide range of the application&amp;rsquo;s features. As a result, I ended up hitting a lot of issues. I calculated, that on average, I was hitting a *new* API issue (one I hadn&amp;rsquo;t seen previously on this project) every ten minutes for the entire four hour period. That was frustrating to say the least. Below is a (hideous) screenshot and a list of the issues I hit.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay3_5F00_0A10ECDC.jpg"&gt;&lt;img height="686" width="898" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfDay3_5F00_thumb_5F00_1BF0115A.jpg" alt="NHProf Day 3" border="0" title="NHProf Day 3" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Style.Triggers are not supported. Ultimately this means we are going to have to refactor a lot of styles. Temporary fix to get things running was to comment out the triggers ;(&lt;/li&gt;
&lt;li&gt;DataTrigger not supported either. We&amp;rsquo;ll probably end up refactoring to VSM. Unfortunately, many of our DataTriggers are in Styles&amp;hellip;Fixing this is going to be interesting.&lt;/li&gt;
&lt;li&gt;Custom Markup Extensions are &lt;em&gt;still &lt;/em&gt;not supported in SL4, even after they completely re-wrote their Xaml parser from the ground up to support greater extensibility. My particular scenario was easy to work around by creating a custom IValueConverter. Another reasonable solution might be to create custom attached properties.&lt;/li&gt;
&lt;li&gt;Lack of Command Support on Menu controls &amp;ndash; This is not a problem with SL4 (except that it doesn&amp;rsquo;t have any menu controls), but is an issue with the current 3rd party controls. As I mentioned above, Caliburn made this easy enough to work around.&lt;/li&gt;
&lt;li&gt;OpenFileDialog is missing CheckFileExists, Title, FileName and RestoreDirectory &amp;ndash; We can work around all of this. The major consequence is that the user&amp;rsquo;s experience with the OpenFileDialog will be degraded.&lt;/li&gt;
&lt;li&gt;Missing Timeline.DesiredFrameRate &amp;ndash; Apparently you can&amp;rsquo;t control animation frame rate in Silverlight. I don&amp;rsquo;t think this will be a major issue.&lt;/li&gt;
&lt;li&gt;The following simple storyboard scenario does not work.&amp;nbsp; There&amp;rsquo;s seams to be a problem setting Storyboards with StaticResource. I used a bit of code-behind to start the animation. There&amp;rsquo;s probably a better way. Anyone have an idea?&lt;/li&gt;
&amp;lt;UserControl.Triggers&amp;gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;EventTrigger RoutedEvent=&amp;quot;FrameworkElement.Loaded&amp;quot;&amp;gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;BeginStoryboard Storyboard=&amp;quot;{StaticResource RhinoCharging}&amp;quot; /&amp;gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/EventTrigger&amp;gt;     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/UserControl.Triggers&amp;gt;
&lt;li&gt;SaveFileDialog missing Title and FileName &amp;ndash; Again, this can be worked around. Mostly it involves a degraded user experience.&lt;/li&gt;
&lt;li&gt;Process.Start is missing &amp;ndash; There was talk of getting something like this into SL4.&amp;nbsp; It would have been nice. We need it to open default apps for certain file types on the OS. We&amp;rsquo;ll either do without this or push it to our backend (which is not Silverlight).&lt;/li&gt;
&lt;li&gt;Enum.GetValues is missing!&amp;nbsp; I found this nice workaround:&amp;nbsp; &lt;a href="http://www.dolittle.com/blogs/einar/archive/2008/01/13/missing-enum-getvalues-when-doing-silverlight-for-instance.aspx"&gt;http://www.dolittle.com/blogs/einar/archive/2008/01/13/missing-enum-getvalues-when-doing-silverlight-for-instance.aspx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;File.WriteAllText is internal. It would have been nice to have this, but we can work around it using Streams, etc.&lt;/li&gt;
&lt;li&gt;Missing SystemParameters.PrimaryScreenHeight and SystemParameters.PrimaryScreenWidth.&amp;nbsp; We&amp;rsquo;ll just have to do without&amp;hellip;&lt;/li&gt;
&lt;li&gt;Missing Serializable and BinaryFormatter.&amp;nbsp; This is a &lt;em&gt;real&lt;/em&gt; pain. Many people have asked for this since SL2, but the SL team hasn&amp;rsquo;t shown any interest in providing this. We are going to have re-write our user settings mechanism.&lt;/li&gt;
&lt;li&gt;Missing Button.IsDefault and Button.IsCancel. This can be worked around. It means adding custom keyboard wire-ups for modal dialogs. Yuck.&lt;/li&gt;
&lt;li&gt;No Label control &amp;ndash; Now that we have ElementName binding why don&amp;rsquo;t we have a decent label control with Target and ActivatorKey? In the mean time I am using a TextBox.&amp;nbsp; We&amp;rsquo;ll probably have to fix this with a custom control.&lt;/li&gt;
&lt;li&gt;Bindings on DPs don&amp;rsquo;t default to TwoWay where appropriate. This is mostly an annoyance.&lt;/li&gt;
&lt;li&gt;No ValueConversionAttribute to decorate value converters with. Not a big issue. But you need to remove it before you can compile.&lt;/li&gt;
&lt;li&gt;Missing Visibility.Hidden. Again, not a big issue. But, you will need to rework code that uses this to use Opacity and IsHitTestVisible.&lt;/li&gt;
&lt;li&gt;Missing DependencyPropertyKey. &amp;ndash; We had a custom control that required this. We will have to re-write this control.&lt;/li&gt;
&lt;li&gt;Missing FrameworkPropertyMetadata. &amp;ndash; Same as above.&lt;/li&gt;
&lt;li&gt;DependencyProperty is missing OverrideMetadata &amp;ndash; Same as above.&lt;/li&gt;
&lt;li&gt;TextBox is missing MinLines and MaxLines &amp;ndash; We&amp;rsquo;ll manage without this by hardcoding height in pixels (yuck!)&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56354" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Animation/default.aspx">Animation</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHProf/default.aspx">NHProf</category></item><item><title>Porting NHProf from WPF to Silverlight - Day 2</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/29/porting-nhprof-from-wpf-to-silverlight-day-2.aspx</link><pubDate>Mon, 29 Mar 2010 21:04:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56327</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=56327</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/29/porting-nhprof-from-wpf-to-silverlight-day-2.aspx#comments</comments><description>&lt;p&gt;Friday I only had a few hours to work on the port. I thought I might look into what it would take to add the main menu. It&amp;rsquo;s an important part of the shell that I completely skipped in my first pass. Unfortunately, there aren&amp;rsquo;t really any free or open source menu controls that I could find which fit the bill exactly. I wanted to use &lt;a href="http://www.vectorlight.net/controls/main_menu.aspx"&gt;VectorLight&amp;rsquo;s Menu&lt;/a&gt;, but I couldn&amp;rsquo;t get it to work in SL4. So, I ended up using the free DevExpress menu control. Unfortunately, I&amp;rsquo;m probably going to have to rip that out eventually because it doesn&amp;rsquo;t support shortcut keys.&amp;nbsp; Neither of these controls support SL4&amp;rsquo;s ICommand interface. Thankfully, &lt;a href="http://caliburn.codeplex.com/wikipage?title=Command%20Basics&amp;amp;referringTitle=Documentation"&gt;Caliburn has a better way&lt;/a&gt; to handle commands, so that didn&amp;rsquo;t set me back. When &lt;a href="http://www.vectorlight.net/controls/main_menu.aspx"&gt;VectorLight&amp;rsquo;s control&lt;/a&gt; is fixed, I&amp;rsquo;ll probably end up switching to that, but I wanted to get something up and running in the mean time. I also started porting a few other parts of the shell, such as the header and chrome. This brought me to the second major shortcoming in Silverlight: No DynamicResource. I spent a good deal of time trying to figure out a workaround for that. I came up with something that I think will work for our purposes, but definitely isn&amp;rsquo;t generalizable. Lack of this functionality is a real problem in Silverlight. Below is a screen shot of the shell after day two. It&amp;rsquo;s not pretty and won&amp;rsquo;t be for a while, but I wanted to include it for &lt;em&gt;historical &lt;/em&gt;purposes.&amp;nbsp; After that you will find a list of a few other compatibility issues I encountered while working on the above two areas.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/PortDay2_5F00_1F6EB4D3.jpg"&gt;&lt;img height="646" width="865" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/PortDay2_5F00_thumb_5F00_634579DB.jpg" alt="Port Day 2" border="0" title="Port Day 2" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Issues from Day 2&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Control.MouseDoubleClick event is missing. Eventually, I will have to implement it manually, probably with an attached property.&lt;/li&gt;
&lt;li&gt;TextBlock.Foreground and TextBlock.FontFamily are missing. It&amp;rsquo;s quite convenient to use these attached properties in WPF, but they simply don&amp;rsquo;t exist in Silverlight. Their absence causes a good deal of additional markup and sometimes &amp;ldquo;hacks&amp;rdquo; to get certain controls in certain parts of the visual tree to look right.&lt;/li&gt;
&lt;li&gt;No *Connection, *Reader, etc. This is pretty obvious. But, I wanted to include it for completeness. I didn&amp;rsquo;t expect to deal with this, but it turns out the profiler&amp;rsquo;s front and backend are not as isolated as I thought they were. We&amp;rsquo;ll have to do some re-architecture in order to fix this.&lt;/li&gt;
&lt;li&gt;There is no MainMenu control as I mentioned above. Currently, there&amp;rsquo;s a lack of good free or open source options for SL4. I&amp;rsquo;m expecting this to be improved upon shortly. Regardless, none of the controls available have an API that is compatible with WPF (especially if you used databinding or commands with your menu). So, if you are porting anything with menus, you are going to have to redo the whole thing.&lt;/li&gt;
&lt;li&gt;Drawing Brush is missing. For that matter, drawings are missing&amp;hellip;I&amp;rsquo;m not sure what we will replace this with just yet. Fortunately, it&amp;rsquo;s only used in one place in our application.&lt;/li&gt;
&lt;li&gt;x:Array is missing. We originally uses this to store the alternating background color array for all our grids as a resource. But, since ItemControl doesn&amp;rsquo;t support that in Silverlight, we won&amp;rsquo;t be using this in the end.&lt;/li&gt;
&lt;li&gt;No DynamicResource support, as mentioned above. For the profiler we have to load different color schemes based on which version you are using. I ended up creating an attached property to place on resource dictionaries, which allowed me to merge the dynamic color scheme in at the appropriate time during initialization. It seams to work so far. But, it&amp;rsquo;s not a generalizable solution, because you can&amp;rsquo;t change the &amp;ldquo;dynamic resources&amp;rdquo; on the fly. My solution only helps solve the issue of resource discoverability in complex scenarios, which is a common use for DynamicResource in WPF.&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56327" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.0/default.aspx">.NET 3.0</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/RIA/default.aspx">RIA</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHProf/default.aspx">NHProf</category></item><item><title>Porting NHProf from WPF to Silverlight – Day 1</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/25/porting-nhprof-from-wpf-to-silverlight-day-1.aspx</link><pubDate>Thu, 25 Mar 2010 20:33:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56277</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=56277</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/25/porting-nhprof-from-wpf-to-silverlight-day-1.aspx#comments</comments><description>&lt;p&gt;This is a true story. It&amp;rsquo;s a story about porting a non-trivial WPF application, &lt;a href="http://nhprof.com/"&gt;NHProf&lt;/a&gt;, to Silverlight 4. The story begins today with my first actual work on the porting process. Microsoft has been preaching how easy it is to move between these platforms. Are they telling the truth? I&amp;rsquo;ll (try to) let you be the judge. I&amp;rsquo;ve been a bit lax in my blogging lately, but I&amp;rsquo;m going to try and give a semi-regular account of my progress on this port along with the challenges I meet along the way. Perhaps I&amp;rsquo;ll be able to offer some meaningful workarounds that others can use; perhaps not. Maybe, dear reader, you can recommend some solutions to me. &lt;/p&gt;
&lt;p&gt;Today I spent about 6 hours on the Silverlight version of NHProf. I basically did a File-&amp;gt;New Project and began moving small pieces of the application shell over to Silverlight. The new application is not much to see at this point&amp;hellip;most of the UI is missing entirely.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfSilverlightProgressDay1_5F00_15941C27.jpg"&gt;&lt;img height="610" width="855" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/rob_5F00_eisenberg/NHProfSilverlightProgressDay1_5F00_thumb_5F00_5E4D94EB.jpg" alt="NHProf Silverlight Progress Day 1" border="0" title="NHProf Silverlight Progress Day 1" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Below is a summary of the platform inconsistencies I came across in the first six hours of work:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Xmlns &amp;ndash; Silverlight 4 allows assemblies to define custom Uri-based Xml namespaces. Unfortunately, Microsoft has done a rather poor job of using this feature themselves. The first issue I came up against today was related to this. It&amp;rsquo;s not a big problem, but rather an annoyance. The reason is that some controls are in different assmelbies/namespaces in Silverlight than in WPF. Take DockPanel, for example. It&amp;rsquo;s a core Panel in WPF, but not in Silverlight. Microsoft hasn&amp;rsquo;t patched up the namespaces for this, so if you port code using DockPanel, you have to go add custom xmlns everythwere. Yuck. This is true of everything in the Silverlight Toolkit. It would be really nice if they took everything in the SDK and everything in the Toolkit and just put them in the default namespace. Unfortunately, this one issue is probably going to prevent a direct reuse of any of our views.&lt;/li&gt;
&lt;li&gt;TabControl &amp;ndash; If you have seen the NHProf UI, It&amp;rsquo;s fairly obvious that we rely heavily on the TabControl. Unfortunately, the Silverlight TabControl is completely broken for data binding. Furthermore, it doesn&amp;rsquo;t have all the necessary template properties either. Basically, it&amp;rsquo;s completely different from the WPF version and completely unusable if you are using an MVVM architecture. My work around has been to use a horizontal ListBox for the &amp;ldquo;tabs&amp;rdquo; and a ContentControl for the &amp;ldquo;SelectedItem,&amp;rdquo; then rely on styling to make it look like a tab control. You can see this in the screenshot above (minus the styling of coarse).&lt;/li&gt;
&lt;li&gt;ToolTip vs. ToolTipService &amp;ndash; In WPF, every control has a ToolTip property; not so in Silverlight. You have to use an attached property called ToolTipService.ToolTip instead. Again, not a big problem, but it forces me to change every view.&lt;/li&gt;
&lt;li&gt;Grid.IsSharedSizeScope and ColumnDefinition.SharedSizeGroup &amp;ndash; Missing. There&amp;rsquo;s no way I know of to do a shared size scope layout in Silverlight. We used this quite a bit in the WPF version. Most of our &amp;ldquo;data grids&amp;rdquo; are actually list boxes with shared size scope layout. It was just simpler and more light weight. To solve this, I&amp;rsquo;m actually using the Sivlerlight DataGrid control. You can see it in the screen shot above displaying the Session Statistics. Ultimately, I think this will be an improvement to the UI. It just seams a bit heavy-weight considering that all of our grids are readonly. Suggestions?&lt;/li&gt;
&lt;li&gt;ItemsControl.AlternationCount &amp;ndash; Missing. This was primarily used in the style to generate alternating row colors. Since most of our ItemsControls/ListBoxes are going to be switched to DataGrid, this probably won&amp;rsquo;t be a big deal in the end. Still, I&amp;rsquo;d be interested in knowing what the proper way to do alternating row styles in Silverlight is.&lt;/li&gt;
&lt;li&gt;TextTrimming=&amp;quot;CharacterEllipsis&amp;quot; &amp;ndash; Missing.&amp;nbsp; We just have to go with WordEllipsis or roll our own ;(&lt;/li&gt;
&lt;li&gt;DynamicResource &amp;ndash; Missing. I&amp;rsquo;ve temporarily removed all the styles for the views I have ported. I&amp;rsquo;m really not sure what the ramifications of the missing DynamicResource will be in the end.&lt;/li&gt;
&lt;li&gt;HeaderedContentControl Template uses a StackPanel &amp;ndash; The HeaderedItemsControl&amp;rsquo;s template is built wrong&amp;hellip;Period. It uses a StackPanel for layout and that prevents styling the control to expand properly. It should use a DockPanel. As I mentioned above, DockPanel is not in the core, which is probably why the HeaderedItemsControl is broken. Now, if they would just move the DockPanel&amp;hellip;.&lt;/li&gt;
&lt;li&gt;ContextMenu &amp;ndash; Missing. Silverlight offers mouse right-click support, but no ContextMenu out of the box. We are going to have to build this one from scratch.&lt;/li&gt;
&lt;li&gt;DispatcherTimer(DispatcherPriority.Normal) &amp;ndash; There&amp;rsquo;s no notion of DispatcherPriority in silverlight! So usage of the Dispatcher and DispatcherTimer can be quite different. Unfortunately, I won&amp;rsquo;t know the full effect of this until we start pushing lots of data through this thing&amp;hellip;I don&amp;rsquo;t think it will be a problem. But, when it comes to SL vs. WPF, I&amp;rsquo;ve learned not to take anything for granted.&lt;/li&gt;
&lt;li&gt;RegexOptions.Compiled &amp;ndash; Missing. We&amp;rsquo;ll just have to do without that.&lt;/li&gt;
&lt;li&gt;String.StartsWith - Missing overload for culture. Created an extension method as workaround.&lt;/li&gt;
&lt;li&gt;StringBuilder - Missing overload to insert a character. Created an extension method as workaround.&lt;/li&gt;
&lt;li&gt;DateTimeFormatInfo - Missing GetAllDateTimePatterns. Created an extension method as workaround. Faked the implementation&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hmm.&amp;nbsp; That&amp;rsquo;s a bit disconcerting for a mere six hours in. What&amp;rsquo;s interesting to note are the the differences in core APIs. I expected the graphics stack to have some inconsistencies, but I didn&amp;rsquo;t expect to hit BCL differences so quickly. I also expected to get a lot more of the shell done today. Looking at the screenshot above&amp;hellip;.I&amp;rsquo;m a bit embarrassed at the lack of progress. So far, porting WPF to Silverlight is &lt;em&gt;slow&lt;/em&gt; going.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56277" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Xaml/default.aspx">Xaml</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Control+Templates/default.aspx">Control Templates</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF_2F00_e/default.aspx">WPF/e</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Featured/default.aspx">Featured</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHProf/default.aspx">NHProf</category></item><item><title>NHProf and Caliburn Testability</title><link>http://devlicio.us/blogs/rob_eisenberg/archive/2009/10/30/nhprof-and-caliburn-testability.aspx</link><pubDate>Fri, 30 Oct 2009 19:07:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53240</guid><dc:creator>Rob Eisenberg</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/rob_eisenberg/rsscomments.aspx?PostID=53240</wfw:commentRss><comments>http://devlicio.us/blogs/rob_eisenberg/archive/2009/10/30/nhprof-and-caliburn-testability.aspx#comments</comments><description>&lt;p&gt;I&amp;rsquo;ve heard some developers asking about UI testing lately.&amp;nbsp; Specifically, there have been some questions about what we did with NHProf.&amp;nbsp; So, I thought I would write a little bit about that here.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;There are a variety of different types of tests you can do.&amp;nbsp; In my experience some have a better ROI than others.&amp;nbsp; For example, we don&amp;rsquo;t do any UI testing with automation APIs.&amp;nbsp; Those are pretty painful, brittle tests to write and we haven&amp;rsquo;t worked in scenarios where they would really help us.&amp;nbsp; The two main types of UI testing we tend to do are Unit Tests of the View Model and Binding Validation Tests against the Views.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;View Model Tests&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are many advantages in taking a View Model approach to building your UI.&amp;nbsp; When we build VMs we try and push as much of the UI state into our models as possible.&amp;nbsp; By doing this we &amp;ldquo;virtualize&amp;rdquo; our entire UI, allowing us to simulate a large percentage of the UI behavior without ever opening a Window or showing anything on screen.&amp;nbsp; This is great for testability.&amp;nbsp; It means, we can use simple state based unit tests to verify the behavior of our UI.&amp;nbsp; Here&amp;rsquo;s a simple example from NHProf:&lt;/p&gt;
&lt;pre name="code" class="c#"&gt;public class StatementFilterTestFixture
{
    private readonly FilterServiceModel service;
    private readonly IList&amp;lt;IStatementSnapshot&amp;gt; statements;

    public StatementFilterTestFixture()
    {
        statements = new List&amp;lt;IStatementSnapshot&amp;gt;
                         {
                             create_a_statement(100, &amp;quot;hello&amp;quot;),
                             create_a_statement(200, &amp;quot;select * from something&amp;quot;),
                             create_a_statement(300, &amp;quot;select field1 from something&amp;quot;),
                             create_a_statement(400, &amp;quot;select monkey,ninja,pirate,robot from floating_island&amp;quot;),
                             create_a_statement(500, &amp;quot;&amp;quot;),
                         };

        service = new FilterServiceModel();
    }

    [Fact]
    public void Can_filter_by_both_duration_for_values_less_than_300_and_contains_text()
    {
        var filters = new ObservableCollection&amp;lt;IFilter&amp;gt;
                          {
                              new FilterByDuration
                              {
                                  Operator = ExpressionType.LessThan, 
                                Value = &amp;quot;300&amp;quot;
                              },
                              new FilterBySqlContains {Text = &amp;quot;something&amp;quot;}
                          };

        service.Filters = filters;

        Assert.Equal(1, statements.Where(x =&amp;gt; service.FilterStatement(x)).Count());
    }
}&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Binding Validation Tests&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While the WPF/SL data binding mechanism opens the door to building rich View Models, it also introduces a new problem: potential binding expression errors.&amp;nbsp; Because we didn&amp;rsquo;t want to give up the productivity benefits of databinding and View Models, we chose to take some time to build a binding validation framework.&amp;nbsp; We then write simple tests to insure that there are no typos or silly mistakes in our binding expressions.&amp;nbsp; Here&amp;rsquo;s an example test from NHProf:&lt;/p&gt;
&lt;pre name="code" class="c#"&gt;public class StatisticsDetailsTestFixture : ViewTestFixtureBase
{
    private readonly ValidationResult&amp;lt;StatisticsModel&amp;gt; bindings;

    public StatisticsDetailsTestFixture()
    {
        bindings = Validator.For&amp;lt;StatisticDetailsView, StatisticsModel&amp;gt;()
            .Validate();
    }

    [Fact]
    public void BindingsDoNotHaveErrors()
    {
        Assert.False(bindings.HasErrors, bindings.ErrorSummary);
    }

    [Fact]
    public void NameIsBound()
    {
        Assert.True(bindings.WasBoundTo(x =&amp;gt; x.DisplayName));
    }

    [Fact]
    public void StatisticsAreBound()
    {
        Assert.True(bindings.WasBoundTo(x =&amp;gt; x.SortedStatistics));
    }
}&lt;/pre&gt;
&lt;p&gt;You can actually take this one step farther as &lt;a href="http://nhforge.org/blogs/nhibernate/archive/2009/08/19/nhibernate-and-wpf-viewmodels-and-views.aspx"&gt;Jos&amp;eacute; Romaniello&lt;/a&gt; has in testing his Chinook Media Manager.&amp;nbsp; Take a look at &lt;a href="http://code.google.com/p/unhaddins/source/browse/trunk/Examples/uNHAddIns.Examples.WPF/ChinookMediaManager.View.Test/TestDataBindings.cs"&gt;this sweet piece of code&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53240" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/databinding/default.aspx">databinding</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/MVVM/default.aspx">MVVM</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/UI+Architecture/default.aspx">UI Architecture</category><category domain="http://devlicio.us/blogs/rob_eisenberg/archive/tags/NHProf/default.aspx">NHProf</category></item></channel></rss>