<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>tom beeby blogs</title>
	<atom:link href="http://tombeeby.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://tombeeby.com</link>
	<description>i wrote some code</description>
	<lastBuildDate>Wed, 05 May 2010 14:31:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='tombeeby.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>tom beeby blogs</title>
		<link>http://tombeeby.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://tombeeby.com/osd.xml" title="tom beeby blogs" />
	<atom:link rel='hub' href='http://tombeeby.com/?pushpress=hub'/>
		<item>
		<title>free data (when you need a lot of it)</title>
		<link>http://tombeeby.com/2010/05/06/free-data-when-you-need-a-lot-of-it/</link>
		<comments>http://tombeeby.com/2010/05/06/free-data-when-you-need-a-lot-of-it/#comments</comments>
		<pubDate>Wed, 05 May 2010 14:31:08 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://tombeeby.com/?p=63</guid>
		<description><![CDATA[i&#8217;ve spent a lot of time lately searching around for data sets that are sufficiently big to run search / indexing benchmarks. i&#8217;m reading up on lucene.net at the moment, and while it&#8217;s all very well to talk about lightening performance, i&#8217;m not going to believe it till i see it. finding good data is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=63&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>i&#8217;ve spent a lot of time lately searching around for data sets that are sufficiently big to run search / indexing benchmarks. i&#8217;m reading up on <a href="http://lucene.apache.org/lucene.net/">lucene.net</a> at the moment, and while it&#8217;s all very well to talk about lightening performance, i&#8217;m not going to believe it till i see it. finding good data is not as easy as you might think. Here are a couple of good source i&#8217;ve been using:</p>
<p><a href="http://www.archive.org/details/ol_data">http://www.archive.org/details/ol_data</a></p>
<p>among other things, archive.org provides library catalogues for download in various formats (json, xml, marc). some of these are very, very big. a particularly good one i&#8217;ve used a lot is the &#8216;open library json dump&#8217; &#8211; 20gigs (43,000,000+ records) of juicy data.</p>
<p><a href="http://blog.stackoverflow.com/2009/06/stack-overflow-creative-commons-data-dump/">http://blog.stackoverflow.com/2009/06/stack-overflow-creative-commons-data-dump/</a></p>
<p>a big chunk of posts, comments, authors etc. good data and very useful for simulating real-world scenarios</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/63/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=63&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2010/05/06/free-data-when-you-need-a-lot-of-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>
	</item>
		<item>
		<title>otto</title>
		<link>http://tombeeby.com/2010/05/05/otto/</link>
		<comments>http://tombeeby.com/2010/05/05/otto/#comments</comments>
		<pubDate>Wed, 05 May 2010 11:41:15 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://tombeeby.wordpress.com/?p=32</guid>
		<description><![CDATA[Meet Otto @ 4 months.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=32&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://tombeeby.files.wordpress.com/2010/05/photo443.jpg"><img class="aligncenter size-medium wp-image-33" title="SAMSUNG" src="http://tombeeby.files.wordpress.com/2010/05/photo443.jpg?w=300&#038;h=225" alt="" width="300" height="225" /></a>Meet Otto @ 4 months.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/32/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=32&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2010/05/05/otto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/photo443.jpg?w=300" medium="image">
			<media:title type="html">SAMSUNG</media:title>
		</media:content>
	</item>
		<item>
		<title>Silverlight 3 Behaviors – Double click selection on a DataGrid</title>
		<link>http://tombeeby.com/2009/07/15/silverlight-3-behaviors-e28093-double-click-selection-on-a-datagrid/</link>
		<comments>http://tombeeby.com/2009/07/15/silverlight-3-behaviors-e28093-double-click-selection-on-a-datagrid/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 00:51:16 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[behaviors]]></category>
		<category><![CDATA[prism]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">https://tombeeby.wordpress.com/2010/05/05/silverlight-3-behaviors-e28093-double-click-selection-on-a-datagrid/</guid>
		<description><![CDATA[If you hadn’t noticed, behaviors created in Silverlight 3 beta will be broken in Silverlight 3 release. The reason for this is that the assembly Microsoft.Expression.Interactivty.dll (that used to be found in C:\Program Files\Microsoft Expression\Blend 3\Libraries\Silverlight\v3.0) no longer exists. Instead, it’s replaced by System.Windows.Interactivity.dll (which is found in C:\Program Files\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\Silverlight). Seems simple enough, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=17&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you hadn’t noticed, behaviors created in Silverlight 3 beta will be broken in Silverlight 3 release. The reason for this is that the assembly <strong>Microsoft.Expression.Interactivty.dll</strong> (that used to be found in <em>C:\Program Files\Microsoft Expression\Blend 3\Libraries\Silverlight\v3.0</em>) no longer exists. Instead, it’s replaced by <strong>System.Windows.Interactivity.dll</strong> (which is found in <em>C:\Program Files\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\Silverlight</em>). Seems simple enough, sure, but it took a good hour (with fists clenched) for me to work this out today since I couldn’t find any docs on it at all.</p>
<p>So, to turn this rant into something useful, I’ll talk about a useful trigger for grabbing a double click on <em>UIElements</em> (such as <em>DataGrid</em>).</p>
<p>The scenario is you have a list of items displayed in a <em>DataGrid</em> and want to select one by double clicking it. We’ll need to code two classes: 1. a trigger that fires on double click; 2. an action that can be fired in response to the trigger (e.g. an action that executes an <em>ICommand</em>).</p>
<p>The first step, is to create the trigger .cs file. Visual Studio 2008 and Blend 3 now provide templates for <em>Triggers</em>, <em>Actions</em> &amp; <em>Behaviors</em> to get you started. Here’s what the template looks like in Visual Studio:</p>
<p><a href="http://tombeeby.files.wordpress.com/2010/05/15072009101113pm.png"><img style="display:inline;border-width:0;" title="15-07-2009 10-11-13 PM" src="http://tombeeby.files.wordpress.com/2010/05/15072009101113pm_thumb.png?w=604&#038;h=332" border="0" alt="15-07-2009 10-11-13 PM" width="604" height="332" /></a></p>
<p>This creates the class, adds the necessary overrides and adds a reference to <strong>System.Windows.Interactivity.dll</strong>.</p>
<p>Now to implement the double click trigger. There’s not a lot of mystery about how to do this, and I borrowed the logic from this useful blog post: <a href="http://compiledexperience.com/Blog/post/Silverlight-3-Behaviors-Double-Click-Trigger.aspx" target="_blank">Silverlight 3 Behaviors : Double Click Trigger</a> – but extended it in several key areas.</p>
<p>Firstly, I used<em> UIElement.Addhandler()</em> to attach the mouse events (<em>MouseLeftButtonDown</em>, <em>MouseLeftButtonUp</em>) in order to ensure the trigger works on <em>UIElements</em> that mark these events <em>handled</em> (like Button for instance).</p>
<p>Secondly, I wanted to be selective and intelligent about the parameter passed in to <em>TriggerBase.InvokeActions()</em>. The important thing here is that, in different circumstances, I’ll want to pass in different parameters. For instance, if the control that fired the trigger is a <em>DataGrid</em>, I’ll want to pass in the <em>SelectedItem</em>; if the control is a <em>Selector</em>, I’ll want to pass in the <em>SelectedItem</em>; or if the control is something else, I may want to pass in the <em>DataContext</em>.</p>
<p>In order to be as generic and extensible as possible, I decided to build a base class that I could inherit other classes from. Here’s my implementation:<br />
<pre class="brush: csharp;">
using System;
using System.Windows;
using System.Windows.Threading;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace GridClicker.Behaviors
{
    public class DoubleClickTriggerBase : TriggerBase&amp;lt;UIElement&amp;gt;
    {
        private readonly DispatcherTimer _timer;

        public DoubleClickTriggerBase()
        {
            _timer = new DispatcherTimer
            {
                Interval = new TimeSpan(0, 0, 0, 0, 200)
            };
            _timer.Tick += OnTimerTick;
        }

        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.AddHandler(UIElement.MouseLeftButtonDownEvent,
                                        new MouseButtonEventHandler(OnMouseAction), true);
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.RemoveHandler(UIElement.MouseLeftButtonDownEvent,
                                           new MouseButtonEventHandler(OnMouseAction));
            if (_timer.IsEnabled)
            {
                _timer.Stop();
            }
        }

        private void OnMouseAction(object sender, MouseButtonEventArgs e)
        {
            if (!_timer.IsEnabled)
            {
                _timer.Start();
                return;
            }
            _timer.Stop();
            DoInvoke();
        }

        private void OnTimerTick(object sender, EventArgs e)
        {
            _timer.Stop();
        }

        protected virtual void DoInvoke()
        {
            InvokeActions(null);
        }
    }
}
</pre><br />
The key thing here is the virtual<em> DoInvoke()</em> method that can be overridden in descendent classes if a special value need to be passed as parameter to <em>InvokeActions()</em>.</p>
<p>Here’s an inherited class, <strong>DataGridDoubleClickTrigger.cs</strong>:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">using System.Windows.Controls;

namespace GridClicker.Behaviors
{
    public class DataGridDoubleClickTrigger : DoubleClickTriggerBase
    {
        protected override void DoInvoke()
        {
            var dg = AssociatedObject as DataGrid;
            var o = dg == null ? null : dg.SelectedItem;
            if (o != null)
            {
                InvokeActions(o);
            }
        }
    }
}</pre>
<p>This simply passes in the <em>SelectedItem</em> of the <em>DataGrid</em> as the<em> InvokeAction()</em> parameter. Of course you could make any number of classes that inherit from <em>DoubleClickTriggerBase</em>. I should point out that there is an assumption here that the user will double click on a row of the <em>DataGrid</em> and not the header, though it will not break in any case. If a user does double click on the header of the <em>DataGrid</em>, if the <em>SelectedItem</em> is not null it will be returned, otherwise nothing will happen.</p>
<p>Now a trigger is no good without an action to fire, so here is a very quick and simplistic action that executes an <em>ICommand</em>. Firstly, create the action in Visual Studio:</p>
<p><a href="http://tombeeby.files.wordpress.com/2010/05/15072009112748pm.png"><img style="display:inline;border-width:0;" title="15-07-2009 11-27-48 PM" src="http://tombeeby.files.wordpress.com/2010/05/15072009112748pm_thumb.png?w=604&#038;h=332" border="0" alt="15-07-2009 11-27-48 PM" width="604" height="332" /></a></p>
<p>And here’s the implementation:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace GridClicker.Behaviors
{
    public class ExecuteCommandAction : TriggerAction&lt;FrameworkElement&gt;
    {
        public string CommandName { get; set; }

        protected override void Invoke(object o)
        {
            if (CommandName == null) return;
            var dataContext = AssociatedObject.DataContext;
            if (dataContext == null) return;
            var command = dataContext.GetType().GetProperty(CommandName).GetValue(dataContext, null) as ICommand;
            if (command != null &amp;&amp; command.CanExecute(o))
            {
                command.Execute(o);
            }
        }
    }
}</pre>
<p>Even though <em>TriggerAction</em> is a <em>DependencyObject</em>, it doesn’t seem to want to let you make <em>CommandName</em> a <em>DependencyProperty</em> and bind it’s value. No idea why this is, hence the roundabout route to grab the command.</p>
<p>To put it altogether, here is the XAML:<br />
 <pre class="brush: xml;">
&lt;StackPanel x:Name=&quot;ContentStackPanel&quot;&gt;

    &lt;TextBlock x:Name=&quot;HeaderText&quot; Style=&quot;{StaticResource HeaderTextStyle}&quot; 
                       Text=&quot;Home&quot;/&gt;

    &lt;data:DataGrid ItemsSource=&quot;{Binding Categories}&quot; IsReadOnly=&quot;True&quot;&gt;
        &lt;i:Interaction.Triggers&gt;
            &lt;b:DataGridDoubleClickTrigger&gt;
                &lt;b:ExecuteCommandAction CommandName=&quot;SelectCommand&quot; /&gt;
            &lt;/b:DataGridDoubleClickTrigger&gt;
        &lt;/i:Interaction.Triggers&gt;
    &lt;/data:DataGrid&gt;
    
    &lt;Button Content=&quot;Double Click Button&quot; Margin=&quot;10&quot; VerticalAlignment=&quot;Center&quot; HorizontalAlignment=&quot;Center&quot;&gt;
        &lt;i:Interaction.Triggers&gt;
            &lt;b:DoubleClickTriggerBase&gt;
                &lt;b:ExecuteCommandAction CommandName=&quot;ButtonCommand&quot;/&gt;
            &lt;/b:DoubleClickTriggerBase&gt;
        &lt;/i:Interaction.Triggers&gt;
    &lt;/Button&gt;

&lt;/StackPanel&gt;
</pre><br />
Note that I also put in a <em>Button</em> that demonstrates that the base class – <strong>DoubleClickTriggerBase</strong> &#8211; is useful in instances where you have no need to pass a parameter to the <em>InvokeActions()</em>.</p>
<p>Finally, to round things off, here is the view’s presenter:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">public class HomePresenter : INotifyPropertyChanged
{
    public ICommand SelectCommand { get; private set; }
    public ICommand ButtonCommand { get; private set; }

    public HomePresenter()
    {
        SelectCommand = new DelegateCommand&lt;object&gt;(o =&gt;
        {
            var cat = o as Category;
            var dw = new DetailsWindow {Width = 300.0, Height = 300.0};
            var g = dw.FindName("LayoutRoot") as Grid;
            g.Children.Add(new TextBlock()
            {
                Text = "Category Name: " + cat.CategoryName,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            });
            dw.Show();
        });

        ButtonCommand = new DelegateCommand&lt;object&gt;(o =&gt; HtmlPage.Window.Alert("Button was double clicked!"));
    }

    public ObservableCollection&lt;Category&gt; Categories
    {
        get { return CategoryHelper.GetCategories(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}</pre>
<p>In the example I am using <a href="http://www.codeplex.com/CompositeWPF" target="_blank">Prism’s</a> <em>DelegateCommand</em> implementation of <em>ICommand</em>.</p>
<p>There you have it!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/17/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/17/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/17/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=17&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2009/07/15/silverlight-3-behaviors-e28093-double-click-selection-on-a-datagrid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/15072009101113pm_thumb.png" medium="image">
			<media:title type="html">15-07-2009 10-11-13 PM</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/15072009112748pm_thumb.png" medium="image">
			<media:title type="html">15-07-2009 11-27-48 PM</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting confirmation on an ICommand</title>
		<link>http://tombeeby.com/2009/07/09/getting-confirmation-on-an-icommand/</link>
		<comments>http://tombeeby.com/2009/07/09/getting-confirmation-on-an-icommand/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 00:47:26 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[behaviors]]></category>
		<category><![CDATA[prism]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">https://tombeeby.wordpress.com/2010/05/05/getting-confirmation-on-an-icommand/</guid>
		<description><![CDATA[A question I asked myself the other day was &#8216;what is the most elegant way to show a confirm dialogue to a user?&#8217; Now there&#8217;s nothing hard about doing this and we all do it from time to time, but nevertheless there are many different ways one might go about doing it. My particular concern [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=12&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A question I asked myself the other day was &#8216;what is the most elegant way to show a confirm dialogue to a user?&#8217; Now there&#8217;s nothing hard about<br />
doing this and we all do it from time to time, but nevertheless there are many different ways one might go about doing it. My particular concern<br />
was firstly to invoke ICommands from the user action and secondly avoid triggering UI events from my presenter (i.e. opening dialogues).</p>
<p>The first and most obvious technique is to simply show a confirm in the event handler of the button in code behind.</p>
<p>Take the following XAML:<br />
<pre class="brush: xml;">
&lt;data:DataGrid ItemsSource=&quot;{Binding Categories}&quot; AutoGenerateColumns=&quot;False&quot;&gt;
    &lt;data:DataGrid.Columns&gt;
        &lt;data:DataGridTextColumn Header=&quot;ID&quot; Binding=&quot;{Binding CategoryID}&quot; /&gt;
        &lt;data:DataGridTextColumn Header=&quot;Name&quot; Binding=&quot;{Binding CategoryName}&quot; /&gt;
        &lt;data:DataGridTemplateColumn Header=&quot;&quot;&gt;
            &lt;data:DataGridTemplateColumn.CellTemplate&gt;
                &lt;DataTemplate&gt;
                    &lt;Button Content=&quot;Delete&quot; Click=&quot;Button_Click&quot; /&gt;
                &lt;/DataTemplate&gt;
            &lt;/data:DataGridTemplateColumn.CellTemplate&gt;
        &lt;/data:DataGridTemplateColumn&gt;
    &lt;/data:DataGrid.Columns&gt;
&lt;/data:DataGrid&gt;
</pre><br />
and the click handler in the code-behind:<br />
<pre class="brush: csharp;">
private void Button_Click(object sender, RoutedEventArgs e)
{
	Category cat = (sender as Button).DataContext as Category;
	if (HtmlPage.Window.Confirm(&quot;Are you sure you want to delete that?&quot;))
	{
		HtmlPage.Window.Alert(&quot;Deleted&quot;);
	}
}
</pre><br />
This works perfectly well, and looks something like this:</p>
<p><a href="http://tombeeby.files.wordpress.com/2010/05/907200993101pm.png"><img style="display:inline;border-width:0;" title="9-07-2009 9-31-01 PM" src="http://tombeeby.files.wordpress.com/2010/05/907200993101pm_thumb.png?w=524&#038;h=348" border="0" alt="9-07-2009 9-31-01 PM" width="524" height="348" /></a></p>
<p>Not a good solution in my case, however, as I wanted to use commanding to link my Delete button to an<em> ICommand</em> in the view’s presenter. (<a href="http://compositewpf.codeplex.com/" target="_blank">Prism</a> gives a great implementation of <em>ICommand</em> – <em>DelegateCommand&lt;T&gt;</em>).</p>
<p>When you use commanding, the obvious place to put the confirm dialogue is in the presenter:</p>
<pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">&lt;data:DataGrid ItemsSource="{Binding Categories}" AutoGenerateColumns="False"&gt;
    &lt;data:DataGrid.Columns&gt;
        &lt;data:DataGridTextColumn Header="ID" Binding="{Binding CategoryID}" /&gt;
        &lt;data:DataGridTextColumn Header="Name" Binding="{Binding CategoryName}" /&gt;
        &lt;data:DataGridTemplateColumn Header=""&gt;
            &lt;data:DataGridTemplateColumn.CellTemplate&gt;
                &lt;DataTemplate&gt;
                    &lt;Button Content="Delete" cal:Click.Command="{Binding Path=Value, Source={StaticResource DeleteCommand}}"
                            cal:Click.CommandParameter="{Binding}"/&gt;
                &lt;/DataTemplate&gt;
            &lt;/data:DataGridTemplateColumn.CellTemplate&gt;
        &lt;/data:DataGridTemplateColumn&gt;
    &lt;/data:DataGrid.Columns&gt;
&lt;/data:DataGrid&gt;</pre>
<p>and the<em> DelegateCommand</em> in the presenter:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">DeleteCommand = new DelegateCommand&lt;Category&gt;((cat) =&gt;
    {
        if (HtmlPage.Window.Confirm("Are you sure you want to delete that?"))
        {
            HtmlPage.Window.Alert("Deleted");
        }
    });</pre>
<p>NOTE: Of course there’s an obvious problem with binding to an<em> ICommand</em> inside a <em>DataTemplate</em> – the <em>DataContext </em>is not the view (e.g. the view model or presenter) but the particular data item that the <em>DataTemplate</em> is displaying. You can get around this using <em>RelativeSource</em> binding in WPF, but not in Silverlight. The solution is to make your<em> ICommand</em> a <em>StaticResource</em> using a implementation of<em> ObservableCommand</em>, as described here: <a href="http://msdn.microsoft.com/en-us/library/dd458928.aspx" target="_blank">http://msdn.microsoft.com/en-us/library/dd458928.aspx</a></p>
<p>Now in the example above, the confirm dialogue certainly displays as I’d like it to, but I have philosophical objections to taking UI components (i.e. the dialogue) out of the view and sticking it in the presenter. Doing this also makes unit testing in the presenter a lot more difficult.</p>
<p>The first alternative that came to mind was to use the code-behind again, but this time invoke the<em> ICommand</em> from there, like this:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">private void Click1(object sender, RoutedEventArgs e)
{
    ((HomePagePresenter)DataContext).DeleteCommand.Execute((sender as Button).DataContext as Category);
}</pre>
<p>This is actually a fairly nice solution- the separation between the presenter and the view is maintained, the inconvenience of declaring the <em>ICommand</em> as a <em>StaticResource</em> is avoided, and it’s quite intuitive. It still seems a little inelegant, however – since all XAML purists will tell you that binding is better in every case.</p>
<p>The next solution I implemented is really nice. I created a new attached behaviour that extends <a href="http://compositewpf.codeplex.com/" target="_blank">Prism’s</a><em> CommandBehaviorBase&lt;T&gt;</em> called <em>ConfirmClick</em>. This lets me use the following mark-up:</p>
<pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">&lt;data:DataGrid ItemsSource="{Binding Categories}" AutoGenerateColumns="False" Grid.Row="1"&gt;
    &lt;data:DataGrid.Columns&gt;
        &lt;data:DataGridTextColumn Header="ID" Binding="{Binding CategoryID}" /&gt;
        &lt;data:DataGridTextColumn Header="Name" Binding="{Binding CategoryName}" /&gt;
        &lt;data:DataGridTemplateColumn Header=""&gt;
            &lt;data:DataGridTemplateColumn.CellTemplate&gt;
                &lt;DataTemplate&gt;
                    &lt;Button Content="Delete" cal2:ConfirmClick.Command="{Binding Path=Value, Source={StaticResource DeleteCommand}}"
                            cal2:ConfirmClick.CommandParameter="{Binding}"/&gt;
                &lt;/DataTemplate&gt;
            &lt;/data:DataGridTemplateColumn.CellTemplate&gt;
        &lt;/data:DataGridTemplateColumn&gt;
    &lt;/data:DataGrid.Columns&gt;
&lt;/data:DataGrid&gt;</pre>
<p>I won’t include the two files ButtonBaseConfirmClickCommandBehavior.cs &amp; ConfirmClick.cs here as they are quite lengthy, but download the source code at the end of this post if you want them.</p>
<p>This approach totally abstracts the out the creation of the confirm dialogue so I don’t have to think about it at all. It’s neat, reusable and fits the pattern perfectly.</p>
<p>I could have stopped here, but there was one other avenue I wanted to check: the new Behaviours that come as part of Silverlight 3. Behaviours are divided into three broad categories: Triggers, Actions and Behaviors. In my case, I can use the inbuilt<em> EventTrigger</em> trigger and attach it to the <em>Click</em> event of my <em>Button</em>.</p>
<p>Don’t forget that if you want to use Behaviors, you need to reference <em>Microsoft.Expression.Interactivity.dll</em> from you project and import the namespace into the XAML.</p>
<p>Now that I can trap the Interestingly, the <em>Microsoft.Expression.Interactivity</em> implements an <em>InvokeCommandAction</em> which I couldn’t for the life of me get to work. It doesn’t help that it is not mentioned anywhere in the Silverlight 3 documentation. Not to worry, I ended up implementing my own Action which looks for an <em>ICommand</em> in the <em>FrameworkElement</em>.Tag property. Here’s the XAML:</p>
<pre class="brush: xml; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">&lt;data:DataGrid ItemsSource="{Binding Categories}" AutoGenerateColumns="False" Grid.Row="2"&gt;
    &lt;data:DataGrid.Columns&gt;
        &lt;data:DataGridTextColumn Header="ID" Binding="{Binding CategoryID}" /&gt;
        &lt;data:DataGridTextColumn Header="Name" Binding="{Binding CategoryName}" /&gt;
        &lt;data:DataGridTemplateColumn Header=""&gt;
            &lt;data:DataGridTemplateColumn.CellTemplate&gt;
                &lt;DataTemplate&gt;
                    &lt;Button Content="Delete" Tag="{Binding Path=Value, Source={StaticResource DeleteCommand}}"&gt;
                        &lt;i:Interaction.Triggers&gt;
                            &lt;i:EventTrigger EventName="Click"&gt;
                                &lt;loc:ConfirmCommandAction /&gt;
                            &lt;/i:EventTrigger&gt;
                        &lt;/i:Interaction.Triggers&gt;
                    &lt;/Button&gt;
                &lt;/DataTemplate&gt;
            &lt;/data:DataGridTemplateColumn.CellTemplate&gt;
        &lt;/data:DataGridTemplateColumn&gt;
    &lt;/data:DataGrid.Columns&gt;
&lt;/data:DataGrid&gt;</pre>
<p>And the Action looks like this:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">public class ConfirmCommandAction : TriggerAction&lt;FrameworkElement&gt;
{
    private string message;
    public string Message
    {
        get { return message ?? "Are you sure you want to do that?"; }
        set { message = value; }
    }
    protected override void Invoke(object parameter)
    {
        if (AssociatedObject.Tag is ICommand)
        {
            var cmnd = AssociatedObject.Tag as ICommand;
            if (cmnd != null &amp;&amp; cmnd.CanExecute(AssociatedObject.DataContext))
            {
                if (HtmlPage.Window.Confirm(Message))
                {
                    cmnd.Execute(AssociatedObject.DataContext);
                }
            }
        }
    }
}</pre>
<p>I should point out that my implementation of <em>ConfirmCommandAction</em> was pretty rapid  and has some holes in it. For instance, I’m not sure I like assuming that the<em> DataContext</em> of the <em>AssociatedObject</em> should be passed as the parameter of the <em>ICommand</em>. I’m also a little unsure whether the <em>Tag</em> property was really supposed to be used like that. Nevertheless it all works quite nicely.</p>
<p>So, there’s several techniques for implementing a confirm dialogue on an <em>ICommand</em>. I think each is valid in it’s own way, but my money is on the <em>ConfirmClick</em> attached behaviour as the most elegant solution – providing you’re willing to include some of the <a href="http://compositewpf.codeplex.com/" target="_blank">Prism</a> libraries in your project.</p>
<p>Hope you find it useful!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/12/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=12&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2009/07/09/getting-confirmation-on-an-icommand/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/907200993101pm_thumb.png" medium="image">
			<media:title type="html">9-07-2009 9-31-01 PM</media:title>
		</media:content>
	</item>
		<item>
		<title>UserState &amp; knowing when you’re done in .NET RIA Services</title>
		<link>http://tombeeby.com/2009/07/07/userstate-knowing-when-youe28099re-done-in-net-ria-services/</link>
		<comments>http://tombeeby.com/2009/07/07/userstate-knowing-when-youe28099re-done-in-net-ria-services/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 00:46:01 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ria services]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">https://tombeeby.wordpress.com/2010/05/05/userstate-knowing-when-youe28099re-done-in-net-ria-services/</guid>
		<description><![CDATA[UPDATE: I bumped into Nikhil Kothari on Twitter and he mentioned that the eventing model for DomainContext is changing in the July CTP (going to become a lot more intuitive when dealing with multiple concurrent calls)… The more time I spend working with .NET RIA services, the more I like it. That said, it’s not [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=9&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<blockquote><p>UPDATE: I bumped into <a href="http://www.nikhilk.net/" target="_blank">Nikhil Kothari</a> on Twitter and he mentioned that the eventing model for DomainContext is changing in the July CTP (going to become a lot more intuitive when dealing with multiple concurrent calls)…</p></blockquote>
<p>The more time I spend working with .NET RIA services, the more I like it. That said, it’s not without it’s frustrations. Today I spent a good part of the afternoon writing some Silverlight test cases and found myself repeating a stack of awkward, ugly code.</p>
<p>Most of the example code I’ve seen around the web is pretty simplistic and doesn’t deal with<em> DomainContext</em> classes that make multiple calls (submits and loads). I’m sure this will change as ria services mature, but at the moment rich examples are hard to come by.</p>
<p>The issue I was having was tracking which call was returning in two of the main events that a <em>DomainContext</em> raises:<em> Loaded </em>and<em> Submitted</em>. These  events are useful in the sense that they tell you when your call has completed, but if you’ve made multiple calls simultaneously then it’s not easy to tell which call is the one that has raised the event. For instance, when the <em>Loaded</em> event is raised, the <em>LoadedDataEventArgs</em> gives you access to a <em>LoadedEntities</em> property which holds the collection of newly loaded entities. You could then check the type of the first entity in order to see which load call has completed, but this is not a great solution as a call may have returned null (i.e. zero results)</p>
<p>Enter <em>UserState</em>. I actually couldn’t find much documentation on this one, but in a nutshell, it is a parameter of type <em>object</em> that you can pass into load and submit methods of your <em>DomainContext</em> and get back in the<em> LoadedDataEventArgs</em> and<em> SubmittedChangesEventArgs</em>.</p>
<p>On the most simple level you could call a method, say, LoadById() and pass in an <em>int</em>, say 1. When the<em> Loaded</em> event is raised after the call, you get back the <em>LoadedDataEventArgs</em> which now carries a property called <em>UserState</em> which is an int with a value of 1. Nice!</p>
<p>After reading around a bit on the Silverlight forums, I decided on the following approach to streamline things further.</p>
<p>Firstly, I created a delegate in the presenter of my view.</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">private delegate void CompletedDelegate(EventArgs args);</pre>
<p>Secondly, I hooked up a reusable method to the<em> Loaded</em> and <em>Submitted</em> events of my <em>DomainContext</em>. The idea is to take the events’ <em>EventArgs</em> and have a look if they have a <em>UserState</em> property that is the delegate type we are after. Here’s the method:<br />
<pre class="brush: csharp;">
private void contextEventHandler(EventArgs args)
{
    if (args is LoadedDataEventArgs)
    {
        if (((LoadedDataEventArgs)args).UserState is CompletedDelegate)
        {
            ((CompletedDelegate)((LoadedDataEventArgs)args).UserState).Invoke(args);
        }
    }
    else if (args is SubmittedChangesEventArgs)
    {
        if (((SubmittedChangesEventArgs)args).UserState is CompletedDelegate)
        {
            ((CompletedDelegate)((SubmittedChangesEventArgs)args).UserState).Invoke(args);
        }
    }
}
</pre><br />
And here’s the constructor of the presenter where I hooked up the method and handled events generated by the view:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">public HomePagePresenter(HomePage view)
{
    this.view = view;

    catCtxt = new CategoryDomainContext();
    catCtxt.Loaded += (s, e) =&gt; contextEventHandler(e);
    catCtxt.Submitted += (s, e) =&gt; contextEventHandler(e);

    view.Click += (s, e) =&gt;
        {
            if ((s as Button).Tag.ToString() == "Save")
            {
                catCtxt.SubmitChanges(new CompletedDelegate(dataSubmitted));
            }
            else if ((s as Button).Tag.ToString() == "Reject")
            {
                catCtxt.RejectChanges();
            }
        };

    loadData();
}</pre>
<p>The key part of the above is <strong>catCtxt.SubmitChanges(new CompletedDelegate(dataSubmitted));</strong> which sets the <em>UserState</em> as the delegate. Now, when the call to submit completes, the method <strong>dataSubmitted</strong> will be called. Here is that method:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">private void dataSubmitted(EventArgs e)
{
    SubmittedChangesEventArgs args = e as SubmittedChangesEventArgs;
    if (args.Error != null)
    {
        HtmlPage.Window.Alert(args.Error.Message);
    }
    else
    {
        HtmlPage.Window.Alert("Data submission complete");
    }
}</pre>
<p>Finally, it’s worth taking a look at the <strong>loadData()</strong> method which again passes in a delegate as <em>UserState</em>:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">private void loadData()
{
    catCtxt.LoadCategories(null, new CompletedDelegate(dataLoaded));
}</pre>
<p>And the dataLoaded method:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">private void dataLoaded(EventArgs e)
{
    notifyChange("Categories");
}</pre>
<p>And to road off the code bits, here’s the simplistic <em>DomainService</em> class I used in the example:</p>
<pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">[EnableClientAccess()]
public class CategoryDomainService : DomainService
{
    public IQueryable&lt;Category&gt; GetCategories()
    {
        return CategoryHelper.GetCategories().AsQueryable();
    }

    public void InsertCategory(Category cat)
    {
    }

    public void UpdateCategory(Category newCat, Category originalCat)
    {
    }

    public void DeleteCategory(Category cat)
    {
    }
}</pre>
<p>All in all I was pretty happy with this technique. It seemed to make ria services a little more WCF-like to me, while still retaining all the major benefits of ria services. The code is still pretty rough, but hey – all my test cases are now passing and the code is a lot more readable than it was. Happy days!</p>
<blockquote><p><span style="background-color:#ffffff;">NOTE: It’s probably worth pointing out that the July CTP of ria services may well render this example obsolete when it comes out. soon i hope!!!</span></p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/9/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=9&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2009/07/07/userstate-knowing-when-youe28099re-done-in-net-ria-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>
	</item>
		<item>
		<title>Building a .NET RIA service project as a Silverlight class library</title>
		<link>http://tombeeby.com/2009/06/30/building-a-net-ria-service-project-as-a-silverlight-class-library/</link>
		<comments>http://tombeeby.com/2009/06/30/building-a-net-ria-service-project-as-a-silverlight-class-library/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 10:44:15 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ria services]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">https://tombeeby.wordpress.com/2010/05/05/building-a-net-ria-service-project-as-a-silverlight-class-library/</guid>
		<description><![CDATA[I’ve spent a lot of time over the past few days playing with the new .NET RIA services which can be installed alongside Silverlight 3. RIA services are great, and one thing I’m really liking is how much old code I’ll be able to throw away (like stacks of custom WCF wrappers on the Silverlight [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=8&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I’ve spent a lot of time over the past few days playing with the new .NET RIA services which can be installed alongside Silverlight 3. RIA services are great, and one thing I’m really liking is how much old code I’ll be able to throw away (like stacks of custom WCF wrappers on the Silverlight side to manage async state and batching multiple service requests).</p>
<p>The original pressure for my team to adopt RIA services was mainly driven by the nice end-to-end data validation framework that it ships with. We started rolling our own and it quickly became clear how much work it was going to take, and – let’s be fair – nobody likes writing that sort of code. If you haven’t checked it out already, a good place to start is over at <a href="http://blogs.msdn.com/brada/archive/2009/03/19/what-is-net-ria-services.aspx" target="_blank">Brad Abrams’ blog</a>.</p>
<p>A key goal of RIA services is to simplify n-tier architectures, and it does this by creating a link between a ASP.NET web application project and a Silverlight application project and generating a lot of code that is magically shared between the two. I won’t go into this in any detail, because it’s not the point of this post.</p>
<p>One of the big issues I hit first up is this: once you install the RIA services pack, you are given the ability to link a ASP.NET web application project with a Silverlight application, but not a Silverlight class library. My particular usage scenario means I need to share a service DLL  amongst a bunch of XAPs (i.e. modules of a Prism solution) , so it’s no good for me to have a direct link between the RIA services web app and a Silverlight app (e.g. the Prism shell). I need a library I can share between all my modules.</p>
<p>When you create a new web application project, you get the following option:</p>
<p><a href="http://tombeeby.files.wordpress.com/2010/05/1.png"><img style="display:inline;border-width:0;" title="1" src="http://tombeeby.files.wordpress.com/2010/05/1_thumb.png?w=452&#038;h=404" border="0" alt="1" width="452" height="404" /></a></p>
<p>Alternatively, you can go into the properties of a Silverlight application and link the server project there:</p>
<p><a href="http://tombeeby.files.wordpress.com/2010/05/2.png"><img style="display:inline;border-width:0;" title="2" src="http://tombeeby.files.wordpress.com/2010/05/2_thumb.png?w=604&#038;h=326" border="0" alt="2" width="604" height="326" /></a></p>
<p>But strangely enough, these options don’t exist when you are dealing with a Silverlight class library.</p>
<p>The work around is this: create you ASP.NET web application and then create your Silverlight class library. The two aren’t linked yet. Exit visual studio and open the .csproj file of the class library project. You want to add the following:<br />
<pre class="brush: plain;">
&lt;PropertyGroup&gt;
	....
	&lt;LinkedServerProject&gt;..\SilverlightApplication1.Web\SilverlightApplication1.Web.csproj&lt;/LinkedServerProject&gt;
	...
&lt;/PropertyGroup&gt;
</pre><br />
Just make sure the path points to your web application project.</p>
<p>Now when you re-open visual studio and build your web application project (assuming it has some domain service classes in it) you’ll see the generated code in your Silverlight class library.</p>
<p>I should probably note that this will all probably change by the time the July CTP comes out (Brad Abrams implied as much in a twitter response to my question).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=8&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2009/06/30/building-a-net-ria-service-project-as-a-silverlight-class-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/1_thumb.png" medium="image">
			<media:title type="html">1</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/2_thumb.png" medium="image">
			<media:title type="html">2</media:title>
		</media:content>
	</item>
		<item>
		<title>Loading panel control for asynchronous requests</title>
		<link>http://tombeeby.com/2008/11/29/loading-panel-control-for-asynchronous-requests/</link>
		<comments>http://tombeeby.com/2008/11/29/loading-panel-control-for-asynchronous-requests/#comments</comments>
		<pubDate>Sat, 29 Nov 2008 13:44:56 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://tombeeby.wordpress.com/?p=57</guid>
		<description><![CDATA[Wow. just realising that finding the time to write a blog is hard! I&#8217;ve had a busy couple of weeks, and with a big deadline looming in February I think time is only going to become more scarce. It&#8217;s a good thing I really enjoy coding in Silverlight &#8211; unlike some other technologies I&#8217;ve been [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=57&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Wow. just realising that finding the time to write a blog is hard! I&#8217;ve had a busy couple of weeks, and with a big deadline looming in February I think time is only going to become more scarce. It&#8217;s a good thing I really enjoy coding in Silverlight &#8211; unlike some other technologies I&#8217;ve been using lately &#8211; and being on the crest of this wave of Silverlight enthusiasm going around at the moment.</p>
<p>Last night I witnessed the first ever meeting of the <a title="Silverlight Designer and Developer Network" href="http://www.sddn.org.au/" target="_blank">Silverlight Designer and Developer Network</a> &#8211; a new Silverlight user group here in Melbourne. Turnout was huge for a first time and the quality of the presented material was great. In particular, I have to say I was blown away by <a title="Jonas Follesø" href="http://jonas.follesoe.no/" target="_blank">Jonas Follesø&#8217;s</a> presentation (a Norwegian Microsoft guy). Not only did he turn out *lots* of code by hand by he actually covered some really cool topics (which I didn&#8217;t expect at this sort of event). He covered the Silverlight Toolkit (nothing new here), Live Mesh &amp; Silverlight outside the browser (wow! this one got the gears of my brain turning) as well as the as-yet nameless Silverlight Business FX Framework which I&#8217;m thinking will be part of Silverlight 3 (we could take weeks/months off our project if this was available now!). So I walked away pretty happy and very positive about putting myself in the Silverlight camp for the foreseeable future.</p>
<p>Better get to some code&#8230;.</p>
<p>A very quick post today. In the course of today I realised needed to unify our approach to managing the UI during asynchronous loads. Basically, the scenario is where you have a control that displays some piece of data that needs to be fetched, and the fetching may take several seconds (or more). Obviously you need to block any user interaction with the control before it is fully loaded, and to follow the convention, you should probably also throw a translucent layer over the control and display a snazzy loading graphic. And of course, a major consideration for me was to make a control I could re-use throughout my app.</p>
<p>Here&#8217;s what I&#8217;m making:</p>
<p><a href="http://tombeeby.files.wordpress.com/2010/05/image-axd-1.jpg"><img class="aligncenter size-full wp-image-58" title="image.axd (1)" src="http://tombeeby.files.wordpress.com/2010/05/image-axd-1.jpg" alt="" width="304" height="304" /></a></p>
<p>The way I decided to approach this was to make a very minor extension to a ContentControl &#8211; adding an extra piece of content to hold the &#8216;waiting&#8217; layer, and an IsLoading property to manage the visual state of the control (i.e. loading or normal). To manage the different visual states, Silverlight provides the handy Visual State Manager. Using the VSM, you can define the visual appearance of your control when it is in certain states (or combinations of states). The Loading Panel can only ever be in two states: Normal and Loading. When the control is in the loading state, the &#8216;waiting&#8217; layer has it&#8217;s visibility set to visible.</p>
<p>Here&#8217;s the XAML:</p>
<p><pre class="brush: plain;">
&lt;ResourceDictionary
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot; 
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot; 
    xmlns:vsm=&quot;clr-namespace:System.Windows;assembly=System.Windows&quot;
    xmlns:loc=&quot;clr-namespace:LoadingPanel&quot;
    &gt;
    &lt;Style TargetType=&quot;loc:LoadingPanel&quot;&gt;
        &lt;Setter Property=&quot;Template&quot;&gt;
            &lt;Setter.Value&gt;
                &lt;ControlTemplate TargetType=&quot;loc:LoadingPanel&quot;&gt;
                    &lt;Grid&gt;
                        &lt;vsm:VisualStateManager.VisualStateGroups&gt;
                            &lt;vsm:VisualStateGroup x:Name=&quot;CommonStates&quot;&gt;
                                &lt;vsm:VisualState x:Name=&quot;Loading&quot;&gt;
                                    &lt;Storyboard&gt;
                                        &lt;ObjectAnimationUsingKeyFrames 
                                            Storyboard.TargetName=&quot;frameworkelementLoadingContent&quot; 
                                            Storyboard.TargetProperty=&quot;Visibility&quot; Duration=&quot;0&quot;&gt;
                                            &lt;DiscreteObjectKeyFrame KeyTime=&quot;0&quot;&gt;
                                                &lt;DiscreteObjectKeyFrame.Value&gt;
                                                    &lt;Visibility&gt;Visible&lt;/Visibility&gt;
                                                &lt;/DiscreteObjectKeyFrame.Value&gt;
                                            &lt;/DiscreteObjectKeyFrame&gt;
                                        &lt;/ObjectAnimationUsingKeyFrames&gt;
                                    &lt;/Storyboard&gt;
                                &lt;/vsm:VisualState&gt;
                                &lt;vsm:VisualState x:Name=&quot;Normal&quot;/&gt;
                            &lt;/vsm:VisualStateGroup&gt;
                        &lt;/vsm:VisualStateManager.VisualStateGroups&gt;
                        &lt;ContentPresenter Content=&quot;{TemplateBinding Content}&quot;/&gt;
                        &lt;ContentPresenter x:Name=&quot;frameworkelementLoadingContent&quot; 
                                          Content=&quot;{TemplateBinding LoadingContent}&quot;
                                          Visibility=&quot;Collapsed&quot;/&gt;
                    &lt;/Grid&gt;
                &lt;/ControlTemplate&gt;
            &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
    &lt;/Style&gt;
&lt;/ResourceDictionary&gt;
</pre></p>
<p>There&#8217;s little that needs explaining here, since the control comprises little more than two ContentPresenters to hold the pieces of content. The VSM also enables you to se transitions between states, but since our designers haven&#8217;t asked for anything I&#8217;ve purposely left this out.</p>
<p>In our case, when the control is put into &#8216;Loading&#8217; mode, there&#8217;s a basic Storyboard with a single animation occurring after 0 seconds (the change from collapsed to visible) targeted at the &#8216;waiting&#8217; content presenter. This particular control uses only one VisualStateGroup, but with more complex controls, you can use several of these to describe different sets of visual characteristics that may or may not be valid in conjunction with other visual states.</p>
<p>The LoadingPanel.cs is a little more interesting. Here&#8217;s the code:</p>
<p><pre class="brush: plain;">
using System;
using System.Windows;
using System.Windows.Controls;
 
namespace LoadingPanel
{
    public class LoadingPanel : ContentControl
    {
        public LoadingPanel()
        {
            DefaultStyleKey = typeof(LoadingPanel);
            IsLoading = false;
        }
 
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            GoToState();
        }
 
        private void GoToState()
        {
            if (IsLoading)
            {
                VisualStateManager.GoToState(this, &quot;Loading&quot;, false);
            }
            else
            {
                VisualStateManager.GoToState(this, &quot;Normal&quot;, false);
            }
        }
 
        public static DependencyProperty IsLoadingProperty =
            DependencyProperty.Register(&quot;IsLoading&quot;, typeof(bool), typeof(LoadingPanel),
            new PropertyMetadata(new PropertyChangedCallback((d, e) =&gt;
            {
                LoadingPanel lp = d as LoadingPanel;
                lp.GoToState();
            })));
 
        public bool IsLoading
        {
            get { return (bool)GetValue(IsLoadingProperty); }
            set { SetValue(IsLoadingProperty, value); }
        }
 
        public static readonly DependencyProperty LoadingContentProperty =
            DependencyProperty.Register(&quot;LoadingContent&quot;, typeof(object), typeof(LoadingPanel), null);
 
        public object LoadingContent
        {
            get { return (object)GetValue(LoadingContentProperty); }
            set { SetValue(LoadingContentProperty, value); }
        }
    }
}
</pre></p>
<p>A few things worth pointing out:</p>
<ul>
<li>The constructor is useful for setting default values for the control&#8217;s properties</li>
<li>The GotoState() method is, by convention, a helper method that interacts with the VisualStateManager</li>
<li>I haven&#8217;t touched the Control Contract at all. This is a series of class Attributes that describe the various parts and states of the control &#8211; consumed by Blend. If you don&#8217;t plan to use the control in Blend then there&#8217;s  no need for a Control Contract, but apparently it&#8217;s good practice to leave it in anyway. <a title="Karen Corby" href="http://scorbs.com/2008/06/23/parts-states-model-with-visualstatemanager-part-3-of-4" target="_blank">Karen Corby</a> wrote a good post about this.</li>
</ul>
<p>Here&#8217;s how to use the control in your XAML:</p>
<p><pre class="brush: plain;">
&lt;UserControl 
    x:Class=&quot;LoadingPanelSL.Page&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot; 
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot; 
    xmlns:data=&quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data&quot;
    xmlns:lp=&quot;clr-namespace:LoadingPanel;assembly=LoadingPanel&quot;
    &gt;
    &lt;Grid x:Name=&quot;LayoutRoot&quot;&gt;
        
        &lt;Grid Width=&quot;400&quot; Height=&quot;400&quot;&gt;
            &lt;Grid.RowDefinitions&gt;
                &lt;RowDefinition Height=&quot;*&quot; /&gt;
                &lt;RowDefinition Height=&quot;Auto&quot; /&gt;
            &lt;/Grid.RowDefinitions&gt;
 
            &lt;lp:LoadingPanel IsLoading=&quot;{Binding IsLoading}&quot;&gt;
                &lt;lp:LoadingPanel.Content&gt;
                    &lt;data:DataGrid x:Name=&quot;datagridMyGrid&quot; ItemsSource=&quot;{Binding MyData}&quot; /&gt;
                &lt;/lp:LoadingPanel.Content&gt;
                &lt;lp:LoadingPanel.LoadingContent&gt;
                    &lt;Grid&gt;
                        &lt;Rectangle Fill=&quot;LightSlateGray&quot; Opacity=&quot;0.3&quot; /&gt;
                        &lt;TextBlock Text=&quot;Loading...&quot; 
                                   HorizontalAlignment=&quot;Center&quot; 
                                   VerticalAlignment=&quot;Center&quot; 
                                   Opacity=&quot;0.7&quot; FontSize=&quot;16&quot; /&gt;
                    &lt;/Grid&gt;
                &lt;/lp:LoadingPanel.LoadingContent&gt;
            &lt;/lp:LoadingPanel&gt;
            
            &lt;Button Content=&quot;Load Data&quot; x:Name=&quot;buttonLoadData&quot; Grid.Row=&quot;1&quot; /&gt;
        &lt;/Grid&gt;
        
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre></p>
<p>Note the two attached properties: Content (inherited from ContentControl) and LoadingContent which is a dependency property I added. You should put the data control in the Content tag and the &#8216;waiting&#8217; screen in the LoadingContent tag.</p>
<p>The thing that makes this technique very simple to use is being able to databind the IsLoading property. It becomes very simple to flick the IsLoading property from true to false in your presenter and know that the UI side of things is taken care of.</p>
<p>And finally, the code-behind:</p>
<p><pre class="brush: plain;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using System.ComponentModel;
 
namespace LoadingPanelSL
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            this.DataContext = new MyDataContext(this);
        }
    }
 
    public class MyDataContext : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private readonly UserControl view;
 
        public MyDataContext(UserControl view)
        {
            this.view = view;
 
            MyDataService service = new MyDataService();
            service.DataLoaded += (object s, MyDataEventArgs e) =&gt;
                {
                    IsLoading = false;
                    MyData = e.Data;
                };
 
            Button b = view.FindName(&quot;buttonLoadData&quot;) as Button;
            b.Click += (s, e) =&gt;
                {
                    IsLoading = true;
                    service.GetData();
                };
        }
 
        private IEnumerable&lt;string&gt; myData;
        public IEnumerable&lt;string&gt; MyData
        {
            get { return myData; }
            set { myData = value; NotifyChange(&quot;MyData&quot;); }
        }
 
        private bool isLoading = false;
        public bool IsLoading
        {
            get { return isLoading; }
            set { isLoading = value; NotifyChange(&quot;IsLoading&quot;); }
        }
 
        private void NotifyChange(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
 
    public class MyDataService
    {
        public event EventHandler&lt;MyDataEventArgs&gt; DataLoaded;
        private string[] str = (&quot;Microsoft Silverlight extends your existing &quot; +
            &quot;development skills empowering you to build new types of applications &quot; +
            &quot;for the Web regardless of target platform or browser Rapidly create &quot; +
            &quot;compelling rich Web applications using all the familiar features &quot; +
            &quot;languages and tools of the .NET framework&quot;).Split();
 
        public void GetData()
        {
            Random rand = new Random();
            Storyboard sb = new Storyboard();
            sb.Duration = new Duration(TimeSpan.FromSeconds(3));
            sb.Completed += new EventHandler((s, e) =&gt;
                {
                    OnDataLoaded(new MyDataEventArgs(from st in str orderby rand.Next() select st));
                });
            sb.Begin();
        }
 
        private void OnDataLoaded(MyDataEventArgs e)
        {
            if (DataLoaded != null) DataLoaded(this, e);
        }
    }
 
    public class MyDataEventArgs : EventArgs
    {
        public IEnumerable&lt;string&gt; Data { get; set; }
        public MyDataEventArgs(IEnumerable&lt;string&gt; data)
        {
            Data = data;
        }
    }
}
</pre></p>
<p>There&#8217;s a bit of junk code here to generate &#8216;random&#8217; data and simulate an asynchronous request. Nevertheless, the code flow is somewhat similar to the way you find your self working with WCF services in a real LOB app.</p>
<p>If I had time there&#8217;s any number of improvements I&#8217;d make to this, but what sort of software developer has time?  This is exactly the sort of quick and dirty solution that makes Silverlight so fun to work with.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/57/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=57&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2008/11/29/loading-panel-control-for-asynchronous-requests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/image-axd-1.jpg" medium="image">
			<media:title type="html">image.axd (1)</media:title>
		</media:content>
	</item>
		<item>
		<title>Automatic hierarchies using Linq and IValueConverter</title>
		<link>http://tombeeby.com/2008/11/09/automatic-hierarchies-using-linq-and-ivalueconverter/</link>
		<comments>http://tombeeby.com/2008/11/09/automatic-hierarchies-using-linq-and-ivalueconverter/#comments</comments>
		<pubDate>Sun, 09 Nov 2008 13:25:17 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://tombeeby.wordpress.com/?p=51</guid>
		<description><![CDATA[The big news in the last week or so has been the release of the Silverlight Toolkit, packed with some nice controls. At my work we were particularly hanging out for the TreeView and Expander controls, but the Charting stuff looks really nice as well, so I&#8217;m sure I&#8217;ll find myself using most of the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=51&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The big news in the last week or so has been the release of the Silverlight Toolkit, packed with some nice controls. At my work we were particularly hanging out for the TreeView and Expander controls, but the Charting stuff looks really nice as well, so I&#8217;m sure I&#8217;ll find myself using most of the toolkit before long.</p>
<p>One of the first things I needed to do with the new control was rig up a TreeView for some data. Sounds pretty easy, and it is &#8211; if you data happen to be in the right structure for the data binding. Reading the docos I discovered that in order to display hierarchical data to the nth level, I need objects that contain collections of their child objects. Damn! For a moment I thought this would mean either changes to the business objects (unlikely) or some sort of conversion layer to covert my business objects into hierarchical objects.</p>
<p>Before we get any further, this is what I am making:<br />
<a href="http://tombeeby.files.wordpress.com/2010/05/image-axd.jpg"><img class="aligncenter size-full wp-image-52" title="image.axd" src="http://tombeeby.files.wordpress.com/2010/05/image-axd.jpg" alt="" width="304" height="356" /></a></p>
<p>To explain what I mean, this is how my business objects were structured:</p>
<p><pre class="brush: plain;">
public class Person
{
    public Person() { PersonID = 0; }
    public int PersonID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string JobTitle { get; set; }
    public Person Manager { get; set; }
}
</pre></p>
<p>So, in my objects, I carry an instance of the parent, not a collection of the children. This is fairly standard stuff, so I figured there must be a neat way to make a collection of objects like this bind to a tree view.</p>
<h3>Convert flat collection to hierarchy using LINQ</h3>
<p>In my reading I came across a blog post by a guy name Stefan Cruysberghs (<a title="LINQ AsHierarchy" href="http://www.scip.be/index.php?Page=ArticlesNET23" target="_blank">LINQ AsHierarchy</a>) which demonstrates how to use an extension method to dynamically convert flat objects into hierarchical ones. What a great idea! I highly recommend you read his post.</p>
<p>I needed to make a minor customization to the source provided by Stefan: I threw in an extra method that allows you to specify the parent ids that root nodes should have, but other than that, everything is the same. Here is my altered code:</p>
<p><pre class="brush: plain;">
using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

/// &lt;summary&gt;
/// Hierarchy node class which contains a nested collection of hierarchy nodes
/// &lt;/summary&gt;
/// &lt;typeparam name=&quot;T&quot;&gt;Entity&lt;/typeparam&gt;
public class HierarchyNode&lt;T&gt; where T : class
{
    public T Entity { get; set; }
    public IEnumerable&lt;HierarchyNode&lt;T&gt;&gt; ChildNodes { get; set; }
    public int Depth { get; set; }
    public T Parent { get; set; }
}

// Stefan Cruysberghs, July 2008, http://www.scip.be
/// &lt;summary&gt;
/// AsHierarchy extension methods for LINQ to Objects IEnumerable
/// &lt;/summary&gt;
public static class LinqToObjectsExtensionMethods
{
    private static IEnumerable&lt;HierarchyNode&lt;TEntity&gt;&gt;
      CreateHierarchy&lt;TEntity, TProperty&gt;(
        IEnumerable&lt;TEntity&gt; allItems,
        TEntity parentItem,
        Func&lt;TEntity, TProperty&gt; idProperty,
        Func&lt;TEntity, TProperty&gt; parentIdProperty,
        object rootItemId,
        object rootParentId,
        int maxDepth,
        int depth) where TEntity : class
    {
        IEnumerable&lt;TEntity&gt; childs;

        if (rootItemId != null)
        {
            childs = allItems.Where(i =&gt; idProperty(i).Equals(rootItemId));
        }
        else if (rootParentId != null)
        {
            childs = allItems.Where(i =&gt; parentIdProperty(i).Equals(rootParentId));
        }
        else
        {
            if (parentItem == null)
            {
                childs = allItems.Where(i =&gt; parentIdProperty(i).Equals(default(TEntity)));
            }
            else
            {
                childs = allItems.Where(i =&gt; parentIdProperty(i).Equals(idProperty(parentItem)));
            }
        }

        if (childs.Count() &gt; 0)
        {
            depth++;

            if ((depth &lt;= maxDepth) || (maxDepth == 0))
            {
                foreach (var item in childs)
                    yield return
                      new HierarchyNode&lt;TEntity&gt;()
                      {
                          Entity = item,
                          ChildNodes =
                            CreateHierarchy(allItems.AsEnumerable(), item, idProperty, parentIdProperty, null, null, maxDepth, depth),
                          Depth = depth,
                          Parent = parentItem
                      };
            }
        }
    }

    /// &lt;summary&gt;
    /// LINQ to Objects (IEnumerable) AsHierachy() extension method
    /// &lt;/summary&gt;
    /// &lt;typeparam name=&quot;TEntity&quot;&gt;Entity class&lt;/typeparam&gt;
    /// &lt;typeparam name=&quot;TProperty&quot;&gt;Property of entity class&lt;/typeparam&gt;
    /// &lt;param name=&quot;allItems&quot;&gt;Flat collection of entities&lt;/param&gt;
    /// &lt;param name=&quot;idProperty&quot;&gt;Func delegete to Id/Key of entity&lt;/param&gt;
    /// &lt;param name=&quot;parentIdProperty&quot;&gt;Func delegete to parent Id/Key&lt;/param&gt;
    /// &lt;returns&gt;Hierarchical structure of entities&lt;/returns&gt;
    public static IEnumerable&lt;HierarchyNode&lt;TEntity&gt;&gt; AsHierarchy&lt;TEntity, TProperty&gt;(
      this IEnumerable&lt;TEntity&gt; allItems,
      Func&lt;TEntity, TProperty&gt; idProperty,
      Func&lt;TEntity, TProperty&gt; parentIdProperty) where TEntity : class
    {
        return CreateHierarchy(allItems, default(TEntity), idProperty, parentIdProperty, null, null, 0, 0);
    }

    /// &lt;summary&gt;
    /// LINQ to Objects (IEnumerable) AsHierachy() extension method
    /// &lt;/summary&gt;
    /// &lt;typeparam name=&quot;TEntity&quot;&gt;Entity class&lt;/typeparam&gt;
    /// &lt;typeparam name=&quot;TProperty&quot;&gt;Property of entity class&lt;/typeparam&gt;
    /// &lt;param name=&quot;allItems&quot;&gt;Flat collection of entities&lt;/param&gt;
    /// &lt;param name=&quot;idProperty&quot;&gt;Func delegete to Id/Key of entity&lt;/param&gt;
    /// &lt;param name=&quot;parentIdProperty&quot;&gt;Func delegete to parent Id/Key&lt;/param&gt;
    /// &lt;param name=&quot;rootItemId&quot;&gt;Value of root item Id/Key&lt;/param&gt;
    /// &lt;returns&gt;Hierarchical structure of entities&lt;/returns&gt;
    public static IEnumerable&lt;HierarchyNode&lt;TEntity&gt;&gt; AsHierarchy&lt;TEntity, TProperty&gt;(
      this IEnumerable&lt;TEntity&gt; allItems,
      Func&lt;TEntity, TProperty&gt; idProperty,
      Func&lt;TEntity, TProperty&gt; parentIdProperty,
      object rootItemId) where TEntity : class
    {
        return CreateHierarchy(allItems, default(TEntity), idProperty, parentIdProperty, rootItemId, null, 0, 0);
    }

    /// &lt;summary&gt;
    /// LINQ to Objects (IEnumerable) AsHierachy() extension method
    /// &lt;/summary&gt;
    /// &lt;typeparam name=&quot;TEntity&quot;&gt;Entity class&lt;/typeparam&gt;
    /// &lt;typeparam name=&quot;TProperty&quot;&gt;Property of entity class&lt;/typeparam&gt;
    /// &lt;param name=&quot;allItems&quot;&gt;Flat collection of entities&lt;/param&gt;
    /// &lt;param name=&quot;idProperty&quot;&gt;Func delegete to Id/Key of entity&lt;/param&gt;
    /// &lt;param name=&quot;parentIdProperty&quot;&gt;Func delegete to parent Id/Key&lt;/param&gt;
    /// &lt;param name=&quot;rootItemId&quot;&gt;Value of root item Id/Key&lt;/param&gt;
    /// &lt;returns&gt;Hierarchical structure of entities&lt;/returns&gt;
    public static IEnumerable&lt;HierarchyNode&lt;TEntity&gt;&gt; AsHierarchy&lt;TEntity, TProperty&gt;(
      this IEnumerable&lt;TEntity&gt; allItems,
      Func&lt;TEntity, TProperty&gt; idProperty,
      Func&lt;TEntity, TProperty&gt; parentIdProperty,
      object rootItemId,
      object rootParentId) where TEntity : class
    {
        return CreateHierarchy(allItems, default(TEntity), idProperty, parentIdProperty, rootItemId, rootParentId, 0, 0);
    }

    /// &lt;summary&gt;
    /// LINQ to Objects (IEnumerable) AsHierachy() extension method
    /// &lt;/summary&gt;
    /// &lt;typeparam name=&quot;TEntity&quot;&gt;Entity class&lt;/typeparam&gt;
    /// &lt;typeparam name=&quot;TProperty&quot;&gt;Property of entity class&lt;/typeparam&gt;
    /// &lt;param name=&quot;allItems&quot;&gt;Flat collection of entities&lt;/param&gt;
    /// &lt;param name=&quot;idProperty&quot;&gt;Func delegete to Id/Key of entity&lt;/param&gt;
    /// &lt;param name=&quot;parentIdProperty&quot;&gt;Func delegete to parent Id/Key&lt;/param&gt;
    /// &lt;param name=&quot;rootItemId&quot;&gt;Value of root item Id/Key&lt;/param&gt;
    /// &lt;param name=&quot;maxDepth&quot;&gt;Maximum depth of tree&lt;/param&gt;
    /// &lt;returns&gt;Hierarchical structure of entities&lt;/returns&gt;
    public static IEnumerable&lt;HierarchyNode&lt;TEntity&gt;&gt; AsHierarchy&lt;TEntity, TProperty&gt;(
      this IEnumerable&lt;TEntity&gt; allItems,
      Func&lt;TEntity, TProperty&gt; idProperty,
      Func&lt;TEntity, TProperty&gt; parentIdProperty,
      object rootItemId,
      object rootParentId,
      int maxDepth) where TEntity : class
    {
        return CreateHierarchy(allItems, default(TEntity), idProperty, parentIdProperty, rootItemId, rootParentId, maxDepth, 0);
    }
}
</pre></p>
<p>Using this technique, I quickly converted my flat collection in a hierarchical one and bound it to my treeview. Great!</p>
<h3>Implementing the conversion via an IValueConverter</h3>
<p>The solution still seemed a bit messy, so I hooked it up to an IValueConverter to make the conversion automatic and seamless. The less code the better, right? The IValueConverter interface is incredibly useful (I&#8217;ve been using it all week to display different ItemTemplate content in an ItemsControl depending what the data is). Basically, it grabs data during data binding and lets you examine / alter / replace data while it moves from the data source to the destination. In my case, I want to bind the ItemsSource of a TreeView to a flat collection of objects, but I wanted the TreeView to receive a hierarchical collection of objects. Here&#8217;s my converter:</p>
<p><pre class="brush: plain;">
public class HierarchyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ObservableCollection&lt;Person&gt; p = (ObservableCollection&lt;Person&gt;)value;
        var tree = p.AsHierarchy(e =&gt; e.PersonID, e =&gt; e.Manager.PersonID, null, 0);
        return tree;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
</pre></p>
<h3>Wrap Up</h3>
<p>Using this technique, I took  a flat collection of business objects and dynamically converted it to a hierarchical collection of node objects at run-time. Once again this is an instance where I expected something to be painful and involve writing a lot of boring code, but Silverlight managed to give me a really nice, elegant solution that I can re-use throughout my app.</p>
<p>I have done  some experimentation, though, and if you want to get two-way data binding to work for you, then you&#8217;ll have to drop the IValueConverter part. This is becuase the Convert() method is called when the initial binding takes place to the TreeView&#8217;s ItemsSource, but at no time will the ConvertBack() method be called &#8211; even if you specify fields in your Hierarchical ItemTemplate to have two-way binding. I still use the AsHierarchy extension method for a quick conversion when I am using two-way data binding however.</p>
<p>Here&#8217;s the Page.xaml:</p>
<p><pre class="brush: plain;">
&lt;UserControl
    x:Class=&quot;LinqTree.Page&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:controls=&quot;clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls&quot;
    xmlns:local=&quot;clr-namespace:LinqTree&quot;
    &gt;
    &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot; Width=&quot;400&quot; Height=&quot;470&quot;&gt;
        &lt;Grid.Resources&gt;
            &lt;local:HierarchyConverter x:Key=&quot;HierarchyConverter&quot; /&gt;
            &lt;Style x:Key=&quot;NameStyle&quot; TargetType=&quot;TextBlock&quot;&gt;
                &lt;Setter Property=&quot;FontSize&quot; Value=&quot;14&quot; /&gt;
            &lt;/Style&gt;
            &lt;Style x:Key=&quot;JobTitleStyle&quot; TargetType=&quot;TextBlock&quot;&gt;
                &lt;Setter Property=&quot;FontSize&quot; Value=&quot;12&quot; /&gt;
                &lt;Setter Property=&quot;Foreground&quot; Value=&quot;LightGray&quot; /&gt;
                &lt;Setter Property=&quot;FontStyle&quot; Value=&quot;Italic&quot; /&gt;
            &lt;/Style&gt;
            &lt;Style x:Key=&quot;MainBorder&quot; TargetType=&quot;Border&quot;&gt;
                &lt;Setter Property=&quot;Background&quot; Value=&quot;WhiteSmoke&quot; /&gt;
                &lt;Setter Property=&quot;BorderThickness&quot; Value=&quot;1&quot; /&gt;
                &lt;Setter Property=&quot;CornerRadius&quot; Value=&quot;8&quot; /&gt;
                &lt;Setter Property=&quot;BorderBrush&quot; Value=&quot;LightGray&quot; /&gt;
                &lt;Setter Property=&quot;Padding&quot; Value=&quot;12&quot; /&gt;
            &lt;/Style&gt;
        &lt;/Grid.Resources&gt;
        &lt;Border Style=&quot;{StaticResource MainBorder}&quot;&gt;
            &lt;controls:TreeView
            x:Name=&quot;treeview&quot;
            ItemsSource=&quot;{Binding Converter={StaticResource HierarchyConverter}}&quot;&gt;
                &lt;controls:TreeView.ItemTemplate&gt;
                    &lt;controls:HierarchicalDataTemplate ItemsSource=&quot;{Binding ChildNodes}&quot;&gt;
                        &lt;StackPanel Orientation=&quot;Vertical&quot;&gt;
                            &lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
                                &lt;TextBlock Style=&quot;{StaticResource NameStyle}&quot; Text=&quot;{Binding Entity.FirstName}&quot; /&gt;
                                &lt;TextBlock Text=&quot; &quot; /&gt;
                                &lt;TextBlock Style=&quot;{StaticResource NameStyle}&quot; Text=&quot;{Binding Entity.LastName}&quot; /&gt;
                            &lt;/StackPanel&gt;
                            &lt;StackPanel Orientation=&quot;Horizontal&quot;&gt;
                                &lt;TextBlock Style=&quot;{StaticResource JobTitleStyle}&quot; Text=&quot;{Binding Entity.JobTitle}&quot; /&gt;
                            &lt;/StackPanel&gt;
                        &lt;/StackPanel&gt;
                    &lt;/controls:HierarchicalDataTemplate&gt;
                &lt;/controls:TreeView.ItemTemplate&gt;
            &lt;/controls:TreeView&gt;
        &lt;/Border&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre></p>
<p>And here&#8217;s  the code behind (Page.xaml.cs):</p>
<p><pre class="brush: plain;">
using System;
using System.Collections.ObjectModel;
using System.Windows.Controls;

namespace LinqTree
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            ObservableCollection&lt;Person&gt; Persons = PersonCollection.PersonList();
            treeview.DataContext = Persons;
        }
    }
}
</pre></p>
<p>A nice clean solution to a common problem.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/51/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=51&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2008/11/09/automatic-hierarchies-using-linq-and-ivalueconverter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/image-axd.jpg" medium="image">
			<media:title type="html">image.axd</media:title>
		</media:content>
	</item>
		<item>
		<title>Customizing a ListBox</title>
		<link>http://tombeeby.com/2008/11/04/customizing-a-listbox/</link>
		<comments>http://tombeeby.com/2008/11/04/customizing-a-listbox/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 13:02:38 +0000</pubDate>
		<dc:creator>tombeeby</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://tombeeby.wordpress.com/?p=45</guid>
		<description><![CDATA[I am quite new to Silverlight (like just about everyone I guess) and I spend a good proportion of each day reading various blogs and finding how to make stuff happen in new and better ways. A well written blog post on a pertinent topic can save me hours or even days of frustration &#8211; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=45&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I am quite new to Silverlight (like just about everyone I guess) and I spend a good proportion of each day reading various blogs and finding how to make stuff happen in new and better ways. A well written blog post on a pertinent topic can save me hours or even days of frustration &#8211; even if the topic is pretty basic stuff. Sometimes it helps to see the same old demos done slightly differently just to get a feel for how others are approaching the sorts of problems we all deal with on a daily basis. So, having spurned the vast majority of bloggers as self-important know-it-alls and vowing never to engage in the practice, I&#8217;ve decided to start a blog. Whether I continue to keep a blog depends largely on 1) how much of my time it consumes 2) how often I come across little tid-bits worthy of sharing 3) how many people read the posts 4) whether I decide to throw in my unhealthy software career and become a farmer or a fisherman (an idea I entertain each morning at 7am when my alarm goes off).</p>
<p>Now, to get to the code&#8230;<br />
A fairly common scenario I encounter is needing to display a UI for objects with one-to-many relationships with other objects, for example a person who has one or more addresses (shipping, billing, etc). The other day I needed to whip up a really quick and dirty view in Silverlight to do this, and it occurred to me that it might be a good place to use the rich control templating features rather than making a whole new control by extending, say, ItemsControl. A key consideration is, of course, to make a reusable component that can be dropped anywhere in my app. The component also needs to support data binding, and fit in with the patterns &amp; practises of the rest of the project (we are using Prism).</p>
<p>Here&#8217;s a screenshot of what I am creating:</p>
<p><a href="http://tombeeby.files.wordpress.com/2010/05/01-01.jpg"><img class="aligncenter size-full wp-image-46" title="01-01" src="http://tombeeby.files.wordpress.com/2010/05/01-01.jpg" alt="" width="402" height="472" /></a></p>
<h3>Overview</h3>
<p>The widget depicted in the screenshot above comprises some basic form components and a templated ListBox. Each address is a ListBoxItem: the ListBox is templated in such a way as to make Selected ListBoxItems visible and Unselected ListBoxItems hidden.</p>
<p>The ItemsSource of the ListBox and the ItemsSource of the Addresses ComboBox are data bound to the same collection of Addresses. The SelectedIndex of the ListBox and the SelectedIndex of the Address(es) ComboBox are data bound to an integer Property in the DataContext of the UserControl: when the selection in the ComboBox changes, the corresponding ListBoxItem is made visible in the ListBox below.</p>
<p>Since re-use is a big goal, I want to create new styles and templates for ListBox and ListBoxItem, and store them somewhere accessible like my App.xaml. This way, I can use a ListBox anywhere in my app and use these  styles &#8211; the ItemTemplate of the ListBoxItem can be customized on each use.</p>
<h3>Customizing the ListBox</h3>
<p>In my experience, when customizing an existing control, it is best to start by looking at that control&#8217;s default styles and templates. The source of all Silverlight&#8217;s controls can be obtained from Codeplex, but I also find the documentation on MSDN to be pretty good. I found a particularly helpful article here: ListBox Styles and Templates that gave me a great start.<br />
The two controls I&#8217;ll need to customize are ListBox and ListBoxItem. Here are the default styles and templates for ListBox in XAML:</p>
<p><pre class="brush: plain;">
&lt;Style TargetType=&quot;ListBox&quot;&gt;
  &lt;Setter Property=&quot;Padding&quot; Value=&quot;1&quot;/&gt;
  &lt;Setter Property=&quot;Background&quot; Value=&quot;#FFFFFFFF&quot; /&gt;
  &lt;Setter Property=&quot;Foreground&quot; Value=&quot;#FF333333&quot; /&gt;
  &lt;Setter Property=&quot;HorizontalContentAlignment&quot; Value=&quot;Left&quot; /&gt;
  &lt;Setter Property=&quot;VerticalContentAlignment&quot; Value=&quot;Top&quot; /&gt;
  &lt;Setter Property=&quot;IsTabStop&quot; Value=&quot;False&quot; /&gt;
  &lt;Setter Property=&quot;BorderThickness&quot; Value=&quot;1&quot; /&gt;
  &lt;Setter Property=&quot;TabNavigation&quot; Value=&quot;Once&quot; /&gt;
  &lt;Setter Property=&quot;BorderBrush&quot;&gt;
    &lt;Setter.Value&gt;
      &lt;LinearGradientBrush EndPoint=&quot;0.5,1&quot; StartPoint=&quot;0.5,0&quot;&gt;
        &lt;GradientStop Color=&quot;#FFA3AEB9&quot; Offset=&quot;0&quot;/&gt;
        &lt;GradientStop Color=&quot;#FF8399A9&quot; Offset=&quot;0.375&quot;/&gt;
        &lt;GradientStop Color=&quot;#FF718597&quot; Offset=&quot;0.375&quot;/&gt;
        &lt;GradientStop Color=&quot;#FF617584&quot; Offset=&quot;1&quot;/&gt;
      &lt;/LinearGradientBrush&gt;
    &lt;/Setter.Value&gt;
  &lt;/Setter&gt;
  &lt;Setter Property=&quot;Template&quot;&gt;
    &lt;Setter.Value&gt;
      &lt;ControlTemplate TargetType=&quot;ListBox&quot;&gt;
        &lt;Border CornerRadius=&quot;2&quot;
                    BorderBrush=&quot;{TemplateBinding BorderBrush}&quot;
                  BorderThickness=&quot;{TemplateBinding BorderThickness}&quot;&gt;
          &lt;ScrollViewer x:Name=&quot;ScrollViewer&quot; Padding=&quot;{TemplateBinding Padding}&quot;
                        Background=&quot;{TemplateBinding Background}&quot;
                        BorderBrush=&quot;Transparent&quot; BorderThickness=&quot;0&quot;&gt;
            &lt;ItemsPresenter /&gt;
          &lt;/ScrollViewer&gt;
        &lt;/Border&gt;
      &lt;/ControlTemplate&gt;
    &lt;/Setter.Value&gt;
  &lt;/Setter&gt;
&lt;/Style&gt;
</pre></p>
<p>Looking at ListBox, the major area of interest is the ControlTemplate; the rest is just very basic style stuff. The ControlTemplate lays out the various bits and pieces that go together to make a ListBox &#8211; and most notably it includes an ItemsPresenter which marks the place where the ListBoxItems will be positioned. For my purposes, I&#8221;ll need to strip out some of the style info and remove the ScrollViewer (which isn&#8217;t needed in this case).</p>
<p>And here are the default styles and templates for ListBoxItem in XAML:</p>
<p><pre class="brush: plain;">
&lt;Style TargetType=&quot;ListBoxItem&quot;&gt;
  &lt;Setter Property=&quot;Padding&quot; Value=&quot;3&quot; /&gt;
  &lt;Setter Property=&quot;HorizontalContentAlignment&quot; Value=&quot;Left&quot; /&gt;
  &lt;Setter Property=&quot;VerticalContentAlignment&quot; Value=&quot;Top&quot; /&gt;
  &lt;Setter Property=&quot;Background&quot; Value=&quot;Transparent&quot; /&gt;
  &lt;Setter Property=&quot;BorderThickness&quot; Value=&quot;1&quot;/&gt;
  &lt;Setter Property=&quot;TabNavigation&quot; Value=&quot;Local&quot; /&gt;
  &lt;Setter Property=&quot;Template&quot;&gt;
    &lt;Setter.Value&gt;
      &lt;ControlTemplate TargetType=&quot;ListBoxItem&quot;&gt;
        &lt;Grid Background=&quot;{TemplateBinding Background}&quot;&gt;
          &lt;vsm:VisualStateManager.VisualStateGroups&gt;
            &lt;vsm:VisualStateGroup x:Name=&quot;CommonStates&quot;&gt;
              &lt;vsm:VisualState x:Name=&quot;Normal&quot; /&gt;
              &lt;vsm:VisualState x:Name=&quot;MouseOver&quot;&gt;
                &lt;Storyboard&gt;
                  &lt;DoubleAnimation Storyboard.TargetName=&quot;fillColor&quot; Storyboard.TargetProperty=&quot;Opacity&quot; Duration=&quot;0&quot; To=&quot;.35&quot;/&gt;
                &lt;/Storyboard&gt;
              &lt;/vsm:VisualState&gt;
            &lt;/vsm:VisualStateGroup&gt;
            &lt;vsm:VisualStateGroup x:Name=&quot;SelectionStates&quot;&gt;
              &lt;vsm:VisualState x:Name=&quot;Unselected&quot; /&gt;
              &lt;vsm:VisualState x:Name=&quot;Selected&quot;&gt;
                &lt;Storyboard&gt;
                  &lt;DoubleAnimation Storyboard.TargetName=&quot;fillColor2&quot; Storyboard.TargetProperty=&quot;Opacity&quot; Duration=&quot;0&quot; To=&quot;.75&quot;/&gt;
                &lt;/Storyboard&gt;
              &lt;/vsm:VisualState&gt;
            &lt;/vsm:VisualStateGroup&gt;
            &lt;vsm:VisualStateGroup x:Name=&quot;FocusStates&quot;&gt;
              &lt;vsm:VisualState x:Name=&quot;Focused&quot;&gt;
                &lt;Storyboard&gt;
                  &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName=&quot;FocusVisualElement&quot; Storyboard.TargetProperty=&quot;Visibility&quot; Duration=&quot;0&quot;&gt;
                    &lt;DiscreteObjectKeyFrame KeyTime=&quot;0&quot;&gt;
                      &lt;DiscreteObjectKeyFrame.Value&gt;
                        &lt;Visibility&gt;Visible&lt;/Visibility&gt;
                      &lt;/DiscreteObjectKeyFrame.Value&gt;
                    &lt;/DiscreteObjectKeyFrame&gt;
                  &lt;/ObjectAnimationUsingKeyFrames&gt;
                &lt;/Storyboard&gt;
              &lt;/vsm:VisualState&gt;
              &lt;vsm:VisualState x:Name=&quot;Unfocused&quot;/&gt;
            &lt;/vsm:VisualStateGroup&gt;
          &lt;/vsm:VisualStateManager.VisualStateGroups&gt;
          &lt;Rectangle x:Name=&quot;fillColor&quot; Opacity=&quot;0&quot; Fill=&quot;#FFBADDE9&quot; IsHitTestVisible=&quot;False&quot; RadiusX=&quot;1&quot; RadiusY=&quot;1&quot;/&gt;
          &lt;Rectangle x:Name=&quot;fillColor2&quot; Opacity=&quot;0&quot; Fill=&quot;#FFBADDE9&quot; IsHitTestVisible=&quot;False&quot; RadiusX=&quot;1&quot; RadiusY=&quot;1&quot;/&gt;
          &lt;ContentPresenter
            x:Name=&quot;contentPresenter&quot;
            Content=&quot;{TemplateBinding Content}&quot;
            ContentTemplate=&quot;{TemplateBinding ContentTemplate}&quot;
            HorizontalAlignment=&quot;Left&quot;
            Margin=&quot;{TemplateBinding Padding}&quot;/&gt;
          &lt;Rectangle x:Name=&quot;FocusVisualElement&quot; Stroke=&quot;#FF45D6FA&quot; StrokeThickness=&quot;1&quot; Visibility=&quot;Collapsed&quot; RadiusX=&quot;1&quot; RadiusY=&quot;1&quot; /&gt;
        &lt;/Grid&gt;
      &lt;/ControlTemplate&gt;
    &lt;/Setter.Value&gt;
  &lt;/Setter&gt;
&lt;/Style&gt;
</pre></p>
<p>Things get a lot more interesting looking at the ListBoxItem styles and templates. The Template makes use of the VisualStateManager, which defines a different look-and-feel for each of the various states (or combination of states) the ListBoxItem might be in. The VisualStateManager can also describe transitions between states, but this functionality is not used by ListBoxItem by default.</p>
<p>States are divided into VisualStateGroups. At any moment, the control may be in no more than one state from each VisualStateGroup. The internal logic of the control instructs the VisualStateManager when a state needs to be activated (e.g. MouseOver state is activated when a use moves their mouse over the ListBoxItem).</p>
<p>The states used by ListBoxItem are:</p>
<ul>
<li>Common States
<ul>
<li>Normal</li>
<li>MouseOver</li>
</ul>
</li>
<li>Selection States
<ul>
<li>Unselected</li>
<li>Selected</li>
</ul>
</li>
<li>Focus States
<ul>
<li>Focused</li>
<li>Unfocused</li>
</ul>
</li>
</ul>
<p>For my purposes, I want to simplify this a bit. I am only interested in two states: Selected (i.e. visible) and Unselected (i.e. invisible). I do not want any changes to occur on Normal, MouseOver, Focused or Unfocused, so I will remove the extra information in these VisualStates and remove the three Rectangles which these states manipulate. In the Selected VisualState, I am going use an ObjectAnimationUsingKeyFrames to change the Visibility property to Visible. Likewise, in the Unselected VisualState, I am going to use an ObjectAnimationUsingKeyFrames to to change the Visibility property to collapsed.</p>
<p>Here&#8217;s the resultant styles and templates I came up with for ListBox and ListBoxItem:</p>
<p><pre class="brush: plain;">
&lt;Style x:Key=&quot;ListBoxStyle&quot; TargetType=&quot;ListBox&quot;&gt;
    &lt;Setter Property=&quot;HorizontalContentAlignment&quot; Value=&quot;Left&quot; /&gt;
    &lt;Setter Property=&quot;VerticalContentAlignment&quot; Value=&quot;Top&quot; /&gt;
    &lt;Setter Property=&quot;IsTabStop&quot; Value=&quot;False&quot; /&gt;
    &lt;Setter Property=&quot;TabNavigation&quot; Value=&quot;Once&quot; /&gt;
    &lt;Setter Property=&quot;Template&quot;&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType=&quot;ListBox&quot;&gt;
                &lt;ItemsPresenter /&gt;
            &lt;/ControlTemplate&gt;
        &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
&lt;/Style&gt;
&lt;Style x:Key=&quot;ListBoxItemStyle&quot; TargetType=&quot;ListBoxItem&quot;&gt;
    &lt;Setter Property=&quot;HorizontalContentAlignment&quot; Value=&quot;Left&quot; /&gt;
    &lt;Setter Property=&quot;VerticalContentAlignment&quot; Value=&quot;Top&quot; /&gt;
    &lt;Setter Property=&quot;TabNavigation&quot; Value=&quot;Local&quot; /&gt;
    &lt;Setter Property=&quot;Template&quot;&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType=&quot;ListBoxItem&quot;&gt;
                &lt;Grid Background=&quot;{TemplateBinding Background}&quot;&gt;
                    &lt;vsm:VisualStateManager.VisualStateGroups&gt;
                        &lt;vsm:VisualStateGroup x:Name=&quot;CommonStates&quot;&gt;
                            &lt;vsm:VisualState x:Name=&quot;Normal&quot; /&gt;
                            &lt;vsm:VisualState x:Name=&quot;MouseOver&quot; /&gt;
                        &lt;/vsm:VisualStateGroup&gt;
                        &lt;vsm:VisualStateGroup x:Name=&quot;SelectionStates&quot;&gt;
                            &lt;vsm:VisualState x:Name=&quot;Unselected&quot;&gt;
                                &lt;Storyboard&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName=&quot;contentPresenter&quot; Storyboard.TargetProperty=&quot;Visibility&quot; Duration=&quot;0&quot;&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime=&quot;0&quot;&gt;
                                            &lt;DiscreteObjectKeyFrame.Value&gt;
                                                &lt;Visibility&gt;Collapsed&lt;/Visibility&gt;
                                            &lt;/DiscreteObjectKeyFrame.Value&gt;
                                        &lt;/DiscreteObjectKeyFrame&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                &lt;/Storyboard&gt;
                            &lt;/vsm:VisualState&gt;
                            &lt;vsm:VisualState x:Name=&quot;Selected&quot;&gt;
                                &lt;Storyboard&gt;
                                    &lt;ObjectAnimationUsingKeyFrames Storyboard.TargetName=&quot;contentPresenter&quot; Storyboard.TargetProperty=&quot;Visibility&quot; Duration=&quot;0&quot;&gt;
                                        &lt;DiscreteObjectKeyFrame KeyTime=&quot;0&quot;&gt;
                                            &lt;DiscreteObjectKeyFrame.Value&gt;
                                                &lt;Visibility&gt;Visible&lt;/Visibility&gt;
                                            &lt;/DiscreteObjectKeyFrame.Value&gt;
                                        &lt;/DiscreteObjectKeyFrame&gt;
                                    &lt;/ObjectAnimationUsingKeyFrames&gt;
                                &lt;/Storyboard&gt;
                            &lt;/vsm:VisualState&gt;
                        &lt;/vsm:VisualStateGroup&gt;
                        &lt;vsm:VisualStateGroup x:Name=&quot;FocusStates&quot;&gt;
                            &lt;vsm:VisualState x:Name=&quot;Focused&quot;/&gt;
                            &lt;vsm:VisualState x:Name=&quot;Unfocused&quot;/&gt;
                        &lt;/vsm:VisualStateGroup&gt;
                    &lt;/vsm:VisualStateManager.VisualStateGroups&gt;
                    &lt;ContentPresenter
                        x:Name=&quot;contentPresenter&quot;
                        Content=&quot;{TemplateBinding Content}&quot;
                        ContentTemplate=&quot;{TemplateBinding ContentTemplate}&quot;/&gt;
                &lt;/Grid&gt;
            &lt;/ControlTemplate&gt;
        &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
&lt;/Style&gt;
</pre></p>
<p>And Finally, the data context:</p>
<p><pre class="brush: plain;">
using System;
using System.ComponentModel;
using System.Windows.Controls;
 
namespace ListBoxTest
{
    public class MyDataContext : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        public MyDataContext(UserControl view)
        {
            View = view;
            PersonList = new PersonCollection().LoadDefault();
            if (PersonList.Count &gt; 0)
            {
                PersonComboBoxSelectedIdx = 0;
            }
        }
 
        private UserControl view;
        public UserControl View
        {
            get { return view; }
            set { view = value; }
        }
 
        private PersonCollection personList;
        public PersonCollection PersonList
        {
            get { return personList; }
            set { personList = value; NotifyChange(&quot;PersonList&quot;); }
        }
 
        private int personComboBoxSelectedIdx;
        public int PersonComboBoxSelectedIdx
        {
            get { return personComboBoxSelectedIdx; }
            set 
            { 
                personComboBoxSelectedIdx = value; 
                NotifyChange(&quot;PersonComboBoxSelectedIdx&quot;);
                if (value.Equals(-1)) return;
 
                SelectedPerson = PersonList[value];
 
                AddressesComboBoxSelectedIdx = -1;
                ComboBox cb = (ComboBox)View.FindName(&quot;comboboxAddresses&quot;);
                cb.UpdateLayout();
                AddressesComboBoxSelectedIdx = 0;
            }
        }
 
        private int addressesComboBoxSelectedIdx;
        public int AddressesComboBoxSelectedIdx
        {
            get { return addressesComboBoxSelectedIdx; }
            set { addressesComboBoxSelectedIdx = value; NotifyChange(&quot;AddressesComboBoxSelectedIdx&quot;); }
        }
 
        private Person selectedPerson;
        public Person SelectedPerson
        {
            get { return selectedPerson; }
            set { selectedPerson = value; NotifyChange(&quot;SelectedPerson&quot;); }
        }
 
        private void NotifyChange(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tombeeby.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tombeeby.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tombeeby.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tombeeby.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tombeeby.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tombeeby.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tombeeby.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tombeeby.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tombeeby.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tombeeby.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tombeeby.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tombeeby.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tombeeby.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tombeeby.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tombeeby.com&amp;blog=13470690&amp;post=45&amp;subd=tombeeby&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tombeeby.com/2008/11/04/customizing-a-listbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c76ed4c7bd83d15a007c9378917b2279?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=X" medium="image">
			<media:title type="html">tombeeby</media:title>
		</media:content>

		<media:content url="http://tombeeby.files.wordpress.com/2010/05/01-01.jpg" medium="image">
			<media:title type="html">01-01</media:title>
		</media:content>
	</item>
	</channel>
</rss>
