<?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>Christopher Bennage : WPF, Caliburn, Silverlight</title><link>http://devlicio.us/blogs/christopher_bennage/archive/tags/WPF/Caliburn/Silverlight/default.aspx</link><description>Tags: WPF, Caliburn, Silverlight</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>1 Simple Step for Commanding in Silverlight</title><link>http://devlicio.us/blogs/christopher_bennage/archive/2010/03/03/1-simple-step-for-commanding-in-silverlight.aspx</link><pubDate>Wed, 03 Mar 2010 16:24:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55619</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;Silverlight 4 is now supporting the commanding that we’ve come to love from WPF. Commanding was a foundational feature for MVVM. It’s what enabled us to bind to methods on our view models.&lt;/p&gt;  &lt;p&gt;John Papa has an excellent introductory post on &lt;a href="http://johnpapa.net/silverlight/5-simple-steps-to-commanding-in-silverlight"&gt;using commands in Silverlight 4&lt;/a&gt;. This pattern is called the DelegatingCommand pattern (or sometimes RelayingCommand). &lt;/p&gt;  &lt;p&gt;I’d like to show you the &lt;a title="free WPF and Silverlight from the stone" href="http://www.codeplex.com/caliburn"&gt;Caliburn&lt;/a&gt; way of handling this. I’m going to steal John’s viewmodel from the aforementioned post (and hope he doesn’t sue).&lt;/p&gt;  &lt;p&gt;The viewmodel presents a collection of all products and a filtered collection of products. You can modify the filter by calling LoadProducts().&lt;/p&gt;  &lt;pre class="c#:nogutter:nocontrols" name="code"&gt;public class ProductViewModel
{
    public ProductViewModel()
    {
        Products = new ObservableCollection&amp;lt;Product&amp;gt;();

        AllProducts = new ObservableCollection&amp;lt;Product&amp;gt;
                          {
                              new Product {ProductId = 1, ProductName = &amp;quot;Apple&amp;quot;},
                              new Product {ProductId = 2, ProductName = &amp;quot;Orange&amp;quot;},
                              new Product {ProductId = 3, ProductName = &amp;quot;Banana&amp;quot;},
                              new Product {ProductId = 4, ProductName = &amp;quot;Pear&amp;quot;},
                              new Product {ProductId = 5, ProductName = &amp;quot;Grape&amp;quot;},
                              new Product {ProductId = 6, ProductName = &amp;quot;Grapefruit&amp;quot;},
                              new Product {ProductId = 7, ProductName = &amp;quot;Strawberry&amp;quot;},
                              new Product {ProductId = 8, ProductName = &amp;quot;Melon&amp;quot;},
                              new Product {ProductId = 9, ProductName = &amp;quot;Guava&amp;quot;},
                              new Product {ProductId = 10, ProductName = &amp;quot;Kiwi&amp;quot;},
                              new Product {ProductId = 11, ProductName = &amp;quot;Pineapple&amp;quot;},
                              new Product {ProductId = 12, ProductName = &amp;quot;Mango&amp;quot;}
                          };
    }

    public ObservableCollection&amp;lt;Product&amp;gt; AllProducts { get; set; }

    public ObservableCollection&amp;lt;Product&amp;gt; Products { get; set; }

    public void LoadProducts(string filter)
    {
        Products.Clear();
        var query = from p in AllProducts
                    where p.ProductName.ToLower().StartsWith(filter.ToLower())
                    select p;
        foreach (var item in query)
        {
            Products.Add(item);
        }
    }

    public bool CanLoadProducts
    {
        get { return true; }
    }
}&lt;/pre&gt;

&lt;p&gt;Let me point out a few notable differences between John’s original and my version of the viewmodel.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There is no ICommand property. &lt;/li&gt;

  &lt;li&gt;CanLoadProducts is a property on my model, it was a method on the original &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The snippet from the corresponding view would look like this:&lt;/p&gt;

&lt;pre class="xml:nogutter:nocontrols" name="code"&gt;&amp;lt;StackPanel&amp;gt;
    &amp;lt;TextBox x:Name=&amp;quot;filter&amp;quot; /&amp;gt;
    &amp;lt;Button x:Name=&amp;quot;LoadProducts&amp;quot; Content=&amp;quot;Load&amp;quot; /&amp;gt;
&amp;lt;/StackPanel&amp;gt;&lt;/pre&gt;

&lt;h3&gt;The Explanation&lt;/h3&gt;

&lt;p&gt;It’s &lt;em&gt;binding by convention&lt;/em&gt;, and it is a new feature of Caliburn added after the 1.1 release&lt;sup&gt;&lt;a id="fn1" title="see footnote"&gt;[1]&lt;/a&gt;&lt;/sup&gt;. So you’ll need to get the &lt;a href="http://caliburn.codeplex.com/SourceControl/list/changesets"&gt;trunk&lt;/a&gt; to do this. &lt;/p&gt;

&lt;p&gt;When you have a button named LoadProducts, Caliburn will look for a method on your viewmodel named LoadProducts and automagically handle the binding for you. In addition, it will check for either a method or property (as in this example) named CanLoadProducts that it will use to toggle the enable/disabled for the button. Also, since we have a parameter named “filter” on LoadProducts, Caliburn will check to see if there is an element in the view name “filter” and pull the value from that.&lt;/p&gt;

&lt;p&gt;There’s a great deal more that you can do with conventions (and you can even plug in your own conventions). &lt;/p&gt;

&lt;p&gt;This also works for Silverlight 3 and WPF. &lt;/p&gt;

&lt;p&gt;You can also see an example of this in &lt;a title="can I get a book?" href="http://github.com/ayende/Alexandria"&gt;Ayende’s sample app Alexandria&lt;/a&gt;.&lt;/p&gt;

&lt;div id="footnote"&gt;
  &lt;ol&gt;
    &lt;li id="1"&gt;&lt;em&gt;&lt;font size="2"&gt;Actually, you can do some of this in 1.0, but it is easier and much richer in the trunk. Ping &lt;/font&gt;&lt;a href="http://caliburn.codeplex.com/Thread/List.aspx"&gt;&lt;font size="2"&gt;the forums&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; if you have a need to use it in 1.x.&lt;/font&gt; &lt;/em&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55619" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/mvvm/default.aspx">mvvm</category></item><item><title>Things I’d Like To Present</title><link>http://devlicio.us/blogs/christopher_bennage/archive/2010/01/08/things-i-d-like-to-present.aspx</link><pubDate>Fri, 08 Jan 2010 11:32:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54940</guid><dc:creator>Christopher Bennage</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;In case you are not familiar with &lt;a href="http://visitmix.com/" target="_blank"&gt;MIX&lt;/a&gt;, it is a conference from Microsoft focusing on the collaboration of design and development. Admittedly, the sessions tend to favor the developer, but there is always excellent design and UX content.&lt;/p&gt;  &lt;p&gt;&lt;a title="voting for MIX sessions" href="http://visitmix.com/opencallvote/?query=Christopher%20Bennage" target="_blank"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" title="Mix10_Vote_grn_240" border="0" alt="Mix10_Vote_grn_240" align="right" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/christopher_5F00_bennage/Mix10_5F00_Vote_5F00_grn_5F00_240_5F00_44742D31.jpg" width="184" height="244" /&gt;&lt;/a&gt; There was an open call for presentations this year and the community gets to choose which of the proposals will be selected. There are a number of &lt;a href="http://visitmix.com/opencallvote/" target="_blank"&gt;excellent proposals&lt;/a&gt; and I encourage you to go check out the list and vote for the sessions that you are genuinely interested in. (Even if you won’t be attending, the sessions will be broadcast.)&lt;/p&gt;  &lt;p&gt;Here are some sessions that I proposed for MIX10:&lt;/p&gt;  &lt;h3&gt;Cross Compiling Games for Silverlight &amp;amp; XNA&lt;/h3&gt;  &lt;p&gt;Our friend and Silverlight MVP, &lt;a href="http://blogs.silverarcade.com/silverlight-games-101/" target="_blank"&gt;Bill Reiss&lt;/a&gt;, has created an incredible library that enables you to cross compile XNA games for Silverlight. The library is called &lt;a title="a library for cross compiling XNA and Silverlight games" href="http://silversprite.codeplex.com/" target="_blank"&gt;SilverSprite&lt;/a&gt; and we feature it on Silver Arcade. (Wow, that’s a lot of ‘silvers’ in one paragraph.)&lt;/p&gt;  &lt;p&gt;In this session, we’d write a simple game for XNA (discussing some of the basic of game dev along the way) and then port the game over to Silverlight.&lt;/p&gt;  &lt;p&gt;This is an area where I wish I could spend more time. I love game development, but it’s always taking a back burner to other projects.   &lt;br /&gt;&lt;a title="Cross Compiling Games for Silverlight &amp;amp; XNA" href="http://visitmix.com/opencallvote/Entry?entryId=CROSSC046" target="_blank"&gt;[vote for this]&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;LinqToSQL and EntityFramework Profilers: Case Study&lt;/h3&gt;  &lt;p&gt;If you aren’t already familiar with the UberProf suite of ORM profilers, you can read tales of the development on &lt;a href="http://ayende.com/Blog/category/561.aspx" target="_blank"&gt;Ayende’s blog&lt;/a&gt;. Rob and I built the UI side of the application, and we learned a lot in the process. I’d like to do a talk were we discuss the challenges of the project, how we solved them, and what we did wrong. &lt;/p&gt;  &lt;p&gt;Yes, NHProf will be included too. (I submitted a case study for it last year, and it didn’t get picked. I have to sneak it in).&amp;#160; &lt;/p&gt;  &lt;p&gt;A few interesting aspects: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;we built this using MVVM, but well before &lt;a href="http://www.codeplex.com/caliburn" target="_blank"&gt;Caliburn&lt;/a&gt; reached maturity. &lt;/li&gt;    &lt;li&gt;the four separate apps (NHProf, EFProf, L2SProf, HProf) all use a single code base.&lt;/li&gt;    &lt;li&gt;we’re about to port the project from WPF to Silverlight.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a title="LinqToSQL and EntityFramework Profilers: Case Study" href="http://visitmix.com/opencallvote/Entry?entryId=LINQTO047" target="_blank"&gt;[vote for this]&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Silver Arcade: Case Study&lt;/h3&gt;  &lt;p&gt;This is a presentation that Rob and I have made a couple of times. Most recently at the Orlando .NET Users Group. We walk through the actual code for &lt;a href="http://www.silverarcade.com" target="_blank"&gt;Silver Arcade&lt;/a&gt; explaining the philosophy, design choices and mistakes we made along the way.&lt;/p&gt;  &lt;p&gt;For MIX, we would focus more design and UX choices, such as the separation of the behaviors from the views. However, we like to have a lot of audience interaction and tend to follow where ever the questions led (especially those leading questions that &lt;a href="http://scottdensmore.typepad.com/" target="_blank"&gt;Scott Densmore&lt;/a&gt; tends to ask). &lt;/p&gt;  &lt;p&gt;Silver Arcade is also interesting because&amp;#160; we deliberately used a number of newer hipper technologies; including Azure, ASP.NET MVC, jQuery, MEF, NHibernate and so on.   &lt;br /&gt; &lt;a title="case study of Silver Arcade" href="http://visitmix.com/opencallvote/Entry?entryId=SILVER048" target="_blank"&gt;[vote for this]&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Thanks!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54940" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/WPF/default.aspx">WPF</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Game+Development/default.aspx">Game Development</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/fun/default.aspx">fun</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/XNA/default.aspx">XNA</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Software+Architecture/default.aspx">Software Architecture</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/web/default.aspx">web</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/MVC/default.aspx">MVC</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Presentations/default.aspx">Presentations</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/UI/default.aspx">UI</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/UI+Patterns/default.aspx">UI Patterns</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/XAML/default.aspx">XAML</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/UX/default.aspx">UX</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/Caliburn/default.aspx">Caliburn</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/viewmodel/default.aspx">viewmodel</category><category domain="http://devlicio.us/blogs/christopher_bennage/archive/tags/mvvm/default.aspx">mvvm</category></item></channel></rss>