<?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>Peter McGrattan's Weblog</title>
	<atom:link href="http://petermcg.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://petermcg.wordpress.com</link>
	<description>Silverlight, WCF, ASP.NET, AJAX, Graphics, RIA</description>
	<lastBuildDate>Sun, 14 Aug 2011 09:05:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='petermcg.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Peter McGrattan's Weblog</title>
		<link>http://petermcg.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://petermcg.wordpress.com/osd.xml" title="Peter McGrattan&#039;s Weblog" />
	<atom:link rel='hub' href='http://petermcg.wordpress.com/?pushpress=hub'/>
		<item>
		<title>LINQ to Visual Tree (Beta)</title>
		<link>http://petermcg.wordpress.com/2009/03/04/linq-to-visual-tree-beta/</link>
		<comments>http://petermcg.wordpress.com/2009/03/04/linq-to-visual-tree-beta/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 12:49:36 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[LINQ to Visual Tree]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2009/03/04/linq-to-visual-tree-beta/</guid>
		<description><![CDATA[(Code Download) Introduction This post presents an early prototype of &#8216;LINQ to Visual Tree&#8217; for Silverlight 2 and WPF applications.&#160; The ultimate goal is to provide applications with the ability to quickly and easily query the Silverlight 2 or WPF Visual Tree via LINQ to Objects. The prototype provides this functionality by enabling enumeration of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=240&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>(<a href="http://cid-920505bfc4faba01.skydrive.live.com/embedrowdetail.aspx/Public/LinqToVisualTree.zip" target="_blank">Code Download</a>) </p>
<h4><strong>Introduction </strong></h4>
<p>This post presents an early prototype of &#8216;LINQ to Visual Tree&#8217; for Silverlight 2 and WPF applications.&#160; The ultimate goal is to provide applications with the ability to quickly and easily query the Silverlight 2 or WPF Visual Tree via LINQ to Objects. </p>
<p>The prototype provides this functionality by enabling enumeration of an application&#8217;s in-memory Visual Tree through the IEnumerable&lt;T&gt; interface.&#160; This is distinct to implementing a custom query provider: the prototype does not implement IQueryable&lt;T&gt; or execute and translate expression trees. </p>
<p>This post demonstrates the basics so far and makes the prototype available for download, it&#8217;s aim is to get feedback and ideas on how the simple API can be improved. </p>
<h4><strong>Trees in Silverlight and WPF </strong></h4>
<p>The one fundamental tree of objects that make up a Silverlight 2 or WPF application is the object tree.&#160; <a href="http://msdn.microsoft.com/en-us/library/ms753391.aspx" target="_blank">WPF provides</a> two conceptual views of the object tree called the logical tree and the visual tree that if combined would expose the full object tree.&#160; The two conceptual trees are exposed via the LogicalTreeHelper and VisualTreeHelper static classes respectively.&#160; The logical tree is a map of elements in the object tree&#8217;s element hierarchy (defined in Xaml or in code) that make up an applications user interface, including inferred elements not explicitly typed by the programmer.&#160; The visual tree is a map of elements in the object tree&#8217;s element hierarchy that derive from Visual or Visual3D, each element is exploded into it&#8217;s constituent visual ingredient elements. </p>
<p>Silverlight does not expose the full object tree, there is more than likely a logical tree behind the scenes but there is currently no LogicalTreeHelper static class to expose it.&#160; Silverlight does however expose a visual tree through VisualTreeHelper but the Visual and Visual3D types do not exist in the API.&#160; The criteria for an object&#8217;s inclusion in the Silverlight visual tree <a href="http://msdn.microsoft.com/en-us/library/cc189034(VS.95).aspx" target="_blank">according to MSDN</a> is that the object has a &quot;rendering implication&quot;. </p>
<h4><strong>LINQ to Visual Tree </strong></h4>
<p>So every Silverlight and WPF application has a Visual Tree exposed through VisualTreeHelper.&#160; &#8216;LINQ to Visual Tree&#8217; extends this model by enabling enumeration of the results returned from VisualTreeHelper for an object and it&#8217;s descendants.&#160; The prototype is exactly two days old &#8211; I&#8217;m still experimenting at this stage, it currently consists of the following two extension methods:</p>
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:blue;">using</span> System;</pre>
<pre style="margin:0;"><span style="color:blue;">using</span> System.Collections.Generic;</pre>
<pre style="margin:0;"><span style="color:blue;">using</span> System.Linq;</pre>
<pre style="margin:0;"><span style="color:blue;">using</span> System.Windows;</pre>
<pre style="margin:0;"><span style="color:blue;">using</span> System.Windows.Media;</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;"><span style="color:blue;">namespace</span> LinqToVisualTree.Common</pre>
<pre style="margin:0;">{</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:blue;">class</span> <span style="color:#2b91af;">VisualEnumerable</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; {</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Gets the Visual Tree filtered by Type for a DependencyObject with that DependencyObject as the root.</span></pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:#2b91af;">IEnumerable</span>&lt;T&gt; GetVisualOfType&lt;T&gt;(<span style="color:blue;">this</span> <span style="color:#2b91af;">DependencyObject</span> element)</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">return</span> GetVisualTree(element).Where(t =&gt; t.GetType() == <span style="color:blue;">typeof</span>(T)).Cast&lt;T&gt;();</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> Gets the Visual Tree for a DependencyObject with that DependencyObject as the root.</span></pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">public</span> <span style="color:blue;">static</span> <span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">DependencyObject</span>&gt; GetVisualTree(<span style="color:blue;">this</span> <span style="color:#2b91af;">DependencyObject</span> element)</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">int</span> childrenCount = <span style="color:#2b91af;">VisualTreeHelper</span>.GetChildrenCount(element);</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">for</span> (<span style="color:blue;">int</span> i = 0; i &lt; childrenCount; i++)</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">var</span> visualChild = <span style="color:#2b91af;">VisualTreeHelper</span>.GetChild(element, i);</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">yield</span> <span style="color:blue;">return</span> visualChild;</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">foreach</span> (<span style="color:blue;">var</span> visualChildren <span style="color:blue;">in</span> GetVisualTree(visualChild))</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">yield</span> <span style="color:blue;">return</span> visualChildren;</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin:0;">&#160;&#160;&#160; }</pre>
<pre style="margin:0;">}</pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<p>Although there are currently only two extension methods, they provide an abundance of scope for querying the Visual Tree in Silverlight or WPF.&#160; Let&#8217;s take a look at some usage scenarios from the code download to see how &#8216;LINQ to Visual Tree&#8217; can be used in practice to query the Visual Tree of a Silverlight 2 application consisting of the following simple Xaml:</p>
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:blue;">&lt;</span><span style="color:#a31515;">UserControl</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Class</span><span style="color:blue;">=&quot;LinqToVisualTree.Sil.Tasks.Page&quot;</span></pre>
<pre style="margin:0;">&#160;&#160; <span style="color:red;"> xmlns</span><span style="color:blue;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span> </pre>
<pre style="margin:0;">&#160;&#160; <span style="color:red;"> xmlns</span><span style="color:blue;">:</span><span style="color:red;">x</span><span style="color:blue;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></pre>
<pre style="margin:0;">&#160;&#160; <span style="color:red;"> Loaded</span><span style="color:blue;">=&quot;Page_Loaded&quot;&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">UserControl.Resources</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">SolidColorBrush</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Key</span><span style="color:blue;">=&quot;ForegroundBrush&quot;</span><span style="color:red;"> Color</span><span style="color:blue;">=&quot;#FFFF0000&quot;/&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160; </span><span style="color:blue;">&lt;/</span><span style="color:#a31515;">UserControl.Resources</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">Grid</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;GridOne&quot;</span><span style="color:red;"> Background</span><span style="color:blue;">=&quot;White&quot;&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">Grid.RowDefinitions</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">RowDefinition</span><span style="color:red;"> Height</span><span style="color:blue;">=&quot;Auto&quot; /&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">RowDefinition</span><span style="color:red;"> Height</span><span style="color:blue;">=&quot;Auto&quot; /&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;/</span><span style="color:#a31515;">Grid.RowDefinitions</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;TextBoxOne&quot;</span><span style="color:red;"> Text</span><span style="color:blue;">=&quot;One&quot;</span><span style="color:red;"> Foreground</span><span style="color:blue;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:red;"> ForegroundBrush</span><span style="color:blue;">}&quot;</span><span style="color:red;"> Grid.Row</span><span style="color:blue;">=&quot;0&quot; /&gt;</span></pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">StackPanel</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;StackPanelOne&quot;</span><span style="color:red;"> Grid.Row</span><span style="color:blue;">=&quot;1&quot;&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;TextBoxTwo&quot;</span><span style="color:red;"> Text</span><span style="color:blue;">=&quot;Two&quot; /&gt;</span></pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">Grid</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;GridTwo&quot;&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">Grid.RowDefinitions</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">RowDefinition</span><span style="color:red;"> Height</span><span style="color:blue;">=&quot;Auto&quot; /&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">RowDefinition</span><span style="color:red;"> Height</span><span style="color:blue;">=&quot;Auto&quot; /&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;/</span><span style="color:#a31515;">Grid.RowDefinitions</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;TextBoxThree&quot;</span><span style="color:red;"> Text</span><span style="color:blue;">=&quot;Three&quot;</span><span style="color:red;"> Grid.Row</span><span style="color:blue;">=&quot;0&quot; /&gt;</span></pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">StackPanel</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;StackPanelTwo&quot;</span><span style="color:red;"> Grid.Row</span><span style="color:blue;">=&quot;1&quot;&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;</span><span style="color:#a31515;">TextBox</span><span style="color:red;"> x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;TextBoxFour&quot;</span><span style="color:red;"> Text</span><span style="color:blue;">=&quot;Four&quot;</span><span style="color:red;"> Foreground</span><span style="color:blue;">=&quot;{</span><span style="color:#a31515;">StaticResource</span><span style="color:red;"> ForegroundBrush</span><span style="color:blue;">}&quot; /&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;/</span><span style="color:#a31515;">Grid</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color:blue;">&lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;"><span style="color:#a31515;">&#160;&#160;&#160; </span><span style="color:blue;">&lt;/</span><span style="color:#a31515;">Grid</span><span style="color:blue;">&gt;</span></pre>
<pre style="margin:0;"><span style="color:blue;">&lt;/</span><span style="color:#a31515;">UserControl</span><span style="color:blue;">&gt;</span></pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<p>Xaml similar to the above is also used for the test WPF application in the code download, for testing it&#8217;s really the hierarchy of the elements in the Xaml that is important &#8211; this can be visualized as follows:</p>
<p><img style="display:inline;border-width:0;" title="Example Xaml Hierarchy" border="0" alt="Example Xaml Hierarchy" src="http://petermcg.files.wordpress.com/2009/03/examplexamlhierarchy.png?w=356&#038;h=223" width="356" height="223" /> </p>
<p>The code download defines seven tasks that demonstrate how to use the &#8216;LINQ to Visual Tree&#8217; API, starting off with basic queries and progressing to slightly more involved ones.&#160; Each task shows the code to produce the required result using both Extension Method syntax and LINQ syntax.&#160; Each task is represented by a method called from the Page_Loaded event handler defined in the above Xaml:</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> Task 1: Get the Visual Tree of this UserControl</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:blue;">private</span> <span style="color:blue;">void</span> Task1()</pre>
<pre style="margin:0;">{</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Extension Method syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">var</span> pageTree1 = <span style="color:blue;">this</span>.GetVisualTree();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Linq syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">var</span> pageTree2 = <span style="color:blue;">from</span> v <span style="color:blue;">in</span> <span style="color:blue;">this</span>.GetVisualTree()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">select</span> v;</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">Debug</span>.Assert(pageTree1.SequenceEqual(pageTree2));</pre>
<pre style="margin:0;">}</pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />
<table border="0" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td align="center"><strong>Silverlight Result</strong></td>
<td align="center"><strong>WPF Result</strong></td>
</tr>
<tr>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/silverlighttask01result3.png" target="_blank"><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="Silverlight Task 01 Result" border="0" alt="Silverlight Task 01 Result" src="http://petermcg.files.wordpress.com/2009/03/silverlighttask01result-thumb3.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/wpftask01result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Wpf Task 01 Result" border="0" alt="Wpf Task 01 Result" src="http://petermcg.files.wordpress.com/2009/03/wpftask01result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> Task 2: Get all the TextBox controls in this UserControl's Visual Tree</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:blue;">private</span> <span style="color:blue;">void</span> Task2()</pre>
<pre style="margin:0;">{</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Extension Method syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">var</span> pageTextBoxes1 = <span style="color:blue;">this</span>.GetVisualOfType&lt;<span style="color:#2b91af;">TextBox</span>&gt;();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Linq syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">var</span> pageTextBoxes2 = <span style="color:blue;">from</span> v <span style="color:blue;">in</span> <span style="color:blue;">this</span>.GetVisualOfType&lt;<span style="color:#2b91af;">TextBox</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">select</span> v;</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">Debug</span>.Assert(pageTextBoxes1.SequenceEqual(pageTextBoxes2));</pre>
<pre style="margin:0;">}</pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />
<table border="0" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td align="center"><strong>Silverlight Result</strong></td>
<td align="center"><strong>WPF Result</strong></td>
</tr>
<tr>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/silverlighttask02result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Silverlight Task 02 Result" border="0" alt="Silverlight Task 02 Result" src="http://petermcg.files.wordpress.com/2009/03/silverlighttask02result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/wpftask02result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Wpf Task 02 Result" border="0" alt="Wpf Task 02 Result" src="http://petermcg.files.wordpress.com/2009/03/wpftask02result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> Task 3: Get the Visual Tree of GridTwo</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:blue;">private</span> <span style="color:blue;">void</span> Task3()</pre>
<pre style="margin:0;">{</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Extension Method syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">var</span> gridTwoTree1 = GridTwo.GetVisualTree();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Linq syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">var</span> gridTwoTree2 = <span style="color:blue;">from</span> v <span style="color:blue;">in</span> GridTwo.GetVisualTree()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">select</span> v;</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">Debug</span>.Assert(gridTwoTree1.SequenceEqual(gridTwoTree2));</pre>
<pre style="margin:0;">}</pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />
<table border="0" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td align="center"><strong>Silverlight Result</strong></td>
<td align="center"><strong>WPF Result</strong></td>
</tr>
<tr>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/silverlighttask03result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Silverlight Task 03 Result" border="0" alt="Silverlight Task 03 Result" src="http://petermcg.files.wordpress.com/2009/03/silverlighttask03result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/wpftask03result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Wpf Task 03 Result" border="0" alt="Wpf Task 03 Result" src="http://petermcg.files.wordpress.com/2009/03/wpftask03result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> Task 4: Get all the TextBox controls in GridTwo's Visual Tree </span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:blue;">private</span> <span style="color:blue;">void</span> Task4()</pre>
<pre style="margin:0;">{</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Extension Method syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">TextBox</span>&gt; gridTwoTextBoxes1 = GridTwo.GetVisualOfType&lt;<span style="color:#2b91af;">TextBox</span>&gt;().ToList();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Linq syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">TextBox</span>&gt; gridTwoTextBoxes2 = (<span style="color:blue;">from</span> v <span style="color:blue;">in</span> GridTwo.GetVisualOfType&lt;<span style="color:#2b91af;">TextBox</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">select</span> v).ToList();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">Debug</span>.Assert(gridTwoTextBoxes1.SequenceEqual(gridTwoTextBoxes2));</pre>
<pre style="margin:0;">}</pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />
<table border="0" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td align="center"><strong>Silverlight Result</strong></td>
<td align="center"><strong>WPF Result</strong></td>
</tr>
<tr>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/silverlighttask04result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Silverlight Task 04 Result" border="0" alt="Silverlight Task 04 Result" src="http://petermcg.files.wordpress.com/2009/03/silverlighttask04result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/wpftask04result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Wpf Task 04 Result" border="0" alt="Wpf Task 04 Result" src="http://petermcg.files.wordpress.com/2009/03/wpftask04result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> Task 5: Get all TextBox controls with a red foreground in this UserControl's Visual Tree</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:blue;">private</span> <span style="color:blue;">void</span> Task5()</pre>
<pre style="margin:0;">{</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Extension Method syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">TextBox</span>&gt; redTextBoxes1 = <span style="color:blue;">this</span>.GetVisualOfType&lt;<span style="color:#2b91af;">TextBox</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .Where(t =&gt; t.Foreground == <span style="color:blue;">this</span>.Resources[<span style="color:#a31515;">&quot;ForegroundBrush&quot;</span>])</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .ToList();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Linq syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">TextBox</span>&gt; redTextBoxes2 = (<span style="color:blue;">from</span> t <span style="color:blue;">in</span> <span style="color:blue;">this</span>.GetVisualOfType&lt;<span style="color:#2b91af;">TextBox</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">where</span> t.Foreground == <span style="color:blue;">this</span>.Resources[<span style="color:#a31515;">&quot;ForegroundBrush&quot;</span>]</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">select</span> t).ToList();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">Debug</span>.Assert(redTextBoxes1.SequenceEqual(redTextBoxes2));</pre>
<pre style="margin:0;">}</pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />
<table border="0" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td align="center"><strong>Silverlight Result</strong></td>
<td align="center"><strong>WPF Result</strong></td>
</tr>
<tr>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/silverlighttask05result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Silverlight Task 05 Result" border="0" alt="Silverlight Task 05 Result" src="http://petermcg.files.wordpress.com/2009/03/silverlighttask05result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/wpftask05result3.png" target="_blank"><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="Wpf Task 05 Result" border="0" alt="Wpf Task 05 Result" src="http://petermcg.files.wordpress.com/2009/03/wpftask05result-thumb3.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> Task 6: Get all Grid controls in a StackPanel in this UserControl's Visual Tree</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:blue;">private</span> <span style="color:blue;">void</span> Task6()</pre>
<pre style="margin:0;">{</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Extension Method syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">Grid</span>&gt; gridsInSp1 = (<span style="color:blue;">this</span>.GetVisualOfType&lt;<span style="color:#2b91af;">StackPanel</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .SelectMany(s =&gt; s.GetVisualOfType&lt;<span style="color:#2b91af;">Grid</span>&gt;())</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ).ToList();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Linq syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">Grid</span>&gt; gridsInSp2 = (<span style="color:blue;">from</span> s <span style="color:blue;">in</span> <span style="color:blue;">this</span>.GetVisualOfType&lt;<span style="color:#2b91af;">StackPanel</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">from</span> g <span style="color:blue;">in</span> s.GetVisualOfType&lt;<span style="color:#2b91af;">Grid</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">select</span> g).ToList();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">Debug</span>.Assert(gridsInSp1.SequenceEqual(gridsInSp2));</pre>
<pre style="margin:0;">}</pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />
<table border="0" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td align="center"><strong>Silverlight Result</strong></td>
<td align="center"><strong>WPF Result</strong></td>
</tr>
<tr>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/silverlighttask06result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Silverlight Task 06 Result" border="0" alt="Silverlight Task 06 Result" src="http://petermcg.files.wordpress.com/2009/03/silverlighttask06result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/wpftask06result2.png" target="_blank"><img style="display:inline;border-width:0;" title="Wpf Task 06 Result" border="0" alt="Wpf Task 06 Result" src="http://petermcg.files.wordpress.com/2009/03/wpftask06result-thumb2.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<div style="font-family:courier new;background:white;color:black;font-size:10pt;">
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> Task 7: Get all TextBox controls in a Grid in a StackPanel in this UserControl's Visual Tree</span></pre>
<pre style="margin:0;"><span style="color:gray;">///</span><span style="color:green;"> </span><span style="color:gray;">&lt;/summary&gt;</span></pre>
<pre style="margin:0;"><span style="color:blue;">private</span> <span style="color:blue;">void</span> Task7()</pre>
<pre style="margin:0;">{</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Extension Method syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">TextBox</span>&gt; textBoxesInGridInSp1 = (<span style="color:blue;">this</span>.GetVisualOfType&lt;<span style="color:#2b91af;">StackPanel</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .SelectMany(s =&gt; s.GetVisualOfType&lt;<span style="color:#2b91af;">Grid</span>&gt;())</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .SelectMany(g =&gt; g.GetVisualOfType&lt;<span style="color:#2b91af;">TextBox</span>&gt;())</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ).ToList();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:green;">// Linq syntax</span></pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">List</span>&lt;<span style="color:#2b91af;">TextBox</span>&gt; textBoxesInGridInSp2 = (<span style="color:blue;">from</span> s <span style="color:blue;">in</span> <span style="color:blue;">this</span>.GetVisualOfType&lt;<span style="color:#2b91af;">StackPanel</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">from</span> g <span style="color:blue;">in</span> s.GetVisualOfType&lt;<span style="color:#2b91af;">Grid</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">from</span> t <span style="color:blue;">in</span> g.GetVisualOfType&lt;<span style="color:#2b91af;">TextBox</span>&gt;()</pre>
<pre style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">select</span> t).ToList();</pre>
<pre style="margin:0;">&#160;</pre>
<pre style="margin:0;">&#160;&#160;&#160; <span style="color:#2b91af;">Debug</span>.Assert(textBoxesInGridInSp1.SequenceEqual(textBoxesInGridInSp2));</pre>
<pre style="margin:0;">}</pre>
</div>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br />
<table border="0" cellspacing="0" cellpadding="6">
<tbody>
<tr>
<td align="center"><strong>Silverlight Result</strong></td>
<td align="center"><strong>WPF Result</strong></td>
</tr>
<tr>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/silverlighttask07result3.png" target="_blank"><img style="display:inline;border-width:0;" title="Silverlight Task 07 Result" border="0" alt="Silverlight Task 07 Result" src="http://petermcg.files.wordpress.com/2009/03/silverlighttask07result-thumb3.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
<td valign="top" width="200"><a href="http://petermcg.files.wordpress.com/2009/03/wpftask07result3.png" target="_blank"><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="Wpf Task 07 Result" border="0" alt="Wpf Task 07 Result" src="http://petermcg.files.wordpress.com/2009/03/wpftask07result-thumb3.png?w=220&#038;h=131" width="220" height="131" /></a> </td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
<p>Feel free to download the code and run the tasks to see how the API is used from both Silverlight and WPF.&#160; As I say I&#8217;m still experimenting with this so I&#8217;d love to hear your suggestions and get feedback and ideas on how the simple API can be improved.</p>
<br />Posted in LINQ to Visual Tree, Silverlight, WPF Tagged: LINQ to Visual Tree <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/240/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/240/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/240/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=240&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2009/03/04/linq-to-visual-tree-beta/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/examplexamlhierarchy.png" medium="image">
			<media:title type="html">Example Xaml Hierarchy</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/silverlighttask01result-thumb3.png" medium="image">
			<media:title type="html">Silverlight Task 01 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/wpftask01result-thumb2.png" medium="image">
			<media:title type="html">Wpf Task 01 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/silverlighttask02result-thumb2.png" medium="image">
			<media:title type="html">Silverlight Task 02 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/wpftask02result-thumb2.png" medium="image">
			<media:title type="html">Wpf Task 02 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/silverlighttask03result-thumb2.png" medium="image">
			<media:title type="html">Silverlight Task 03 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/wpftask03result-thumb2.png" medium="image">
			<media:title type="html">Wpf Task 03 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/silverlighttask04result-thumb2.png" medium="image">
			<media:title type="html">Silverlight Task 04 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/wpftask04result-thumb2.png" medium="image">
			<media:title type="html">Wpf Task 04 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/silverlighttask05result-thumb2.png" medium="image">
			<media:title type="html">Silverlight Task 05 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/wpftask05result-thumb3.png" medium="image">
			<media:title type="html">Wpf Task 05 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/silverlighttask06result-thumb2.png" medium="image">
			<media:title type="html">Silverlight Task 06 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/wpftask06result-thumb2.png" medium="image">
			<media:title type="html">Wpf Task 06 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/silverlighttask07result-thumb3.png" medium="image">
			<media:title type="html">Silverlight Task 07 Result</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/03/wpftask07result-thumb3.png" medium="image">
			<media:title type="html">Wpf Task 07 Result</media:title>
		</media:content>
	</item>
		<item>
		<title>Customizing the Silverlight 2 ItemsControl with Templates</title>
		<link>http://petermcg.wordpress.com/2009/02/15/customizing-the-silverlight-2-itemscontrol-with-templates/</link>
		<comments>http://petermcg.wordpress.com/2009/02/15/customizing-the-silverlight-2-itemscontrol-with-templates/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 13:25:39 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[ItemsControl]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[XAML]]></category>
		<category><![CDATA[ControlTemplate]]></category>
		<category><![CDATA[DataTemplate]]></category>
		<category><![CDATA[ItemsPanel]]></category>
		<category><![CDATA[ItemTemplate]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2009/02/15/customizing-the-silverlight-2-itemscontrol-with-templates/</guid>
		<description><![CDATA[(Code download) The ItemsControl in Silverlight 2 is the base type for a number of list based UI controls: It’s at a place in it’s class hierarchy that means it provides just enough to get you going with list output. Controls further down the inheritance hierarchy from ItemsControl tend to specialise it’s functionality by providing [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=192&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>(<a href="http://cid-920505bfc4faba01.skydrive.live.com/embedrowdetail.aspx/Public/ItemsControlImages.zip" target="_blank">Code download</a>)</strong></p>
<p>The ItemsControl in Silverlight 2 is the base type for a number of list based UI controls:</p>
<p><img style="border-bottom:0;border-left:0;display:inline;margin-left:0;border-top:0;margin-right:0;border-right:0;" title="ItemsControl Derived Types" src="http://petermcg.files.wordpress.com/2009/02/itemscontrolderivedtypes1.png?w=418&#038;h=219" border="0" alt="ItemsControl Derived Types" width="418" height="219" /></p>
<p>It’s at a place in it’s class hierarchy that means it provides just enough to get you going with list output.  Controls further down the inheritance hierarchy from ItemsControl tend to specialise it’s functionality by providing the ability to select or edit items in the list in slightly distinct ways.  The items in an ItemsControl can be defined in Xaml or generated dynamically from the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemssource(VS.95).aspx" target="_blank">ItemsSource</a> property in code.</p>
<p>Every aspect of the <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol(VS.95).aspx" target="_blank">ItemsControl</a>’s appearance from the exterior of the control, the panel that surrounds it’s items and the items themselves can be customized based on a pre-defined pattern or ‘template’ that you specify.  Three properties on the ItemsControl allow you to specify three different types of template to describe three different aspects of the appearance of the final list:</p>
<table border="1" cellspacing="0" cellpadding="4" width="550">
<tbody>
<tr>
<td>
<p align="center"><strong>Property Name</strong></p>
</td>
<td>
<p align="center"><strong>Type</strong></p>
</td>
<td>
<p align="center"><strong>Default Content</strong></p>
</td>
</tr>
<tr>
<td>Template</td>
<td>System.Windows.Controls.ControlTemplate</td>
<td>ItemsPresenter containing StackPanel</td>
</tr>
<tr>
<td>ItemsPanel</td>
<td>System.Windows.Controls.ItemsPanelTemplate</td>
<td>StackPanel containing ContentPresenter per item</td>
</tr>
<tr>
<td>ItemTemplate</td>
<td>System.Windows.DataTemplate</td>
<td>ContentPresenter containing Grid</td>
</tr>
</tbody>
</table>
<p>&nbsp;<br />
These defaults can be visualised in the following control hierarchy:</p>
<p><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="Default ItemsControl Template Output" src="http://petermcg.files.wordpress.com/2009/02/defaultitemscontroltemplateoutput1.png?w=250&#038;h=277" border="0" alt="Default ItemsControl Template Output" width="250" height="277" /></p>
<p>The ‘Template’ property is inherited from Control and appropriately allows you to specify a ControlTemplate to define the appearance of everything about the ItemsControl outside it’s <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemspresenter(VS.95).aspx" target="_blank">ItemsPresenter</a>.  The other two properties ‘ItemsPanel’ and ‘ItemTemplate’ are defined by the ItemsControl class itself and are concerned with the appearance of items inside the ItemsControl.  More specifically the ‘ItemsPanel’ property controls the appearance of the panel that surrounds all the item’s ContentPresenters, the ‘ItemTemplate’ property customizes the appearance of the contents of each <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(VS.95).aspx" target="_blank">ContentPresenter</a>.</p>
<h5>Customizing the Default Templates</h5>
<p>The following example shows how to customize the value of each of these three properties to produce a different control hierarchy.  The sample application attached to this post makes use of the ItemsControl to position images not vertically in a StackPanel but at specific coordinates within a Canvas.  The Xaml from the sample application is reproduced below along with the subsequent control hierarchy:</p>
<pre class="code"><span style="color:blue;">&lt;</span><span style="color:#a31515;">UserControl </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Class</span><span style="color:blue;">="ItemsControlImages.Page"
    </span><span style="color:red;">xmlns</span><span style="color:blue;">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    </span><span style="color:red;">xmlns</span><span style="color:blue;">:</span><span style="color:red;">x</span><span style="color:blue;">="http://schemas.microsoft.com/winfx/2006/xaml"
    </span><span style="color:red;">xmlns</span><span style="color:blue;">:</span><span style="color:red;">app</span><span style="color:blue;">="clr-namespace:ItemsControlImages"&gt;

    &lt;</span><span style="color:#a31515;">UserControl.Resources</span><span style="color:blue;">&gt;
        &lt;</span><span style="color:#a31515;">ControlTemplate </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Key</span><span style="color:blue;">="ControlTemplateKey"&gt;
            &lt;</span><span style="color:#a31515;">Border </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">="ControlTemplate_ValueOf_Template"&gt;
                &lt;</span><span style="color:#a31515;">ItemsPresenter </span><span style="color:blue;">/&gt;
            &lt;/</span><span style="color:#a31515;">Border</span><span style="color:blue;">&gt;
        &lt;/</span><span style="color:#a31515;">ControlTemplate</span><span style="color:blue;">&gt;

        &lt;</span><span style="color:#a31515;">ItemsPanelTemplate </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Key</span><span style="color:blue;">="ItemsPanelKey"&gt;
            &lt;</span><span style="color:#a31515;">Grid </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">="ItemsPanelTemplate_ValueOf_ItemsPanel" /&gt;
        &lt;/</span><span style="color:#a31515;">ItemsPanelTemplate</span><span style="color:blue;">&gt;

        &lt;</span><span style="color:#a31515;">DataTemplate </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Key</span><span style="color:blue;">="ItemTemplateKey"&gt;
            &lt;</span><span style="color:#a31515;">Canvas </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">="DataTemplate_ValueOf_ItemTemplate" &gt;
                &lt;</span><span style="color:#a31515;">Image </span><span style="color:red;">Canvas.Top</span><span style="color:blue;">="{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Location</span><span style="color:blue;">.</span><span style="color:red;">Y</span><span style="color:blue;">}"
                       </span><span style="color:red;">Canvas.Left</span><span style="color:blue;">="{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Location</span><span style="color:blue;">.</span><span style="color:red;">X</span><span style="color:blue;">}"
                       </span><span style="color:red;">Source</span><span style="color:blue;">="{</span><span style="color:#a31515;">Binding </span><span style="color:red;">FlagImage</span><span style="color:blue;">}" /&gt;

                &lt;</span><span style="color:#a31515;">StackPanel </span><span style="color:red;">Canvas.Top</span><span style="color:blue;">="{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Location</span><span style="color:blue;">.</span><span style="color:red;">Y</span><span style="color:blue;">}"
                            </span><span style="color:red;">Canvas.Left</span><span style="color:blue;">="{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Location</span><span style="color:blue;">.</span><span style="color:red;">X</span><span style="color:blue;">}"&gt;
                    &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">="{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Title</span><span style="color:blue;">}" /&gt;
                    &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">="{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Location</span><span style="color:blue;">}" /&gt;

                    &lt;</span><span style="color:#a31515;">StackPanel.RenderTransform</span><span style="color:blue;">&gt;
                        &lt;</span><span style="color:#a31515;">TranslateTransform </span><span style="color:red;">Y</span><span style="color:blue;">="-32.0" /&gt;
                    &lt;/</span><span style="color:#a31515;">StackPanel.RenderTransform</span><span style="color:blue;">&gt;
                &lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;
            &lt;/</span><span style="color:#a31515;">Canvas</span><span style="color:blue;">&gt;
        &lt;/</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">UserControl.Resources</span><span style="color:blue;">&gt;

    &lt;</span><span style="color:#a31515;">Canvas </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">="LayoutRoot"&gt;
        &lt;</span><span style="color:#a31515;">Canvas.Background</span><span style="color:blue;">&gt;
            &lt;</span><span style="color:#a31515;">LinearGradientBrush </span><span style="color:red;">EndPoint</span><span style="color:blue;">="0.5,1" </span><span style="color:red;">StartPoint</span><span style="color:blue;">="0.5,0"&gt;
                &lt;</span><span style="color:#a31515;">GradientStop </span><span style="color:red;">Color</span><span style="color:blue;">="#FFB2C6D5"/&gt;
                &lt;</span><span style="color:#a31515;">GradientStop </span><span style="color:red;">Color</span><span style="color:blue;">="#FF1483D9" </span><span style="color:red;">Offset</span><span style="color:blue;">="1"/&gt;
            &lt;/</span><span style="color:#a31515;">LinearGradientBrush</span><span style="color:blue;">&gt;
        &lt;/</span><span style="color:#a31515;">Canvas.Background</span><span style="color:blue;">&gt;

        &lt;</span><span style="color:#a31515;">ItemsControl </span><span style="color:red;">Template</span><span style="color:blue;">="{</span><span style="color:#a31515;">StaticResource </span><span style="color:red;">ControlTemplateKey</span><span style="color:blue;">}"
                      </span><span style="color:red;">ItemsPanel</span><span style="color:blue;">="{</span><span style="color:#a31515;">StaticResource </span><span style="color:red;">ItemsPanelKey</span><span style="color:blue;">}"
                      </span><span style="color:red;">ItemTemplate</span><span style="color:blue;">="{</span><span style="color:#a31515;">StaticResource </span><span style="color:red;">ItemTemplateKey</span><span style="color:blue;">}"&gt;

            &lt;</span><span style="color:#a31515;">app</span><span style="color:blue;">:</span><span style="color:#a31515;">Country </span><span style="color:red;">Title</span><span style="color:blue;">="Argentina" </span><span style="color:red;">Location</span><span style="color:blue;">="56,218" </span><span style="color:red;">FlagImage</span><span style="color:blue;">="Images/ARG.png" /&gt;
            &lt;</span><span style="color:#a31515;">app</span><span style="color:blue;">:</span><span style="color:#a31515;">Country </span><span style="color:red;">Title</span><span style="color:blue;">="China" </span><span style="color:red;">Location</span><span style="color:blue;">="368,66" </span><span style="color:red;">FlagImage</span><span style="color:blue;">="Images/CHN.png" /&gt;
            &lt;</span><span style="color:#a31515;">app</span><span style="color:blue;">:</span><span style="color:#a31515;">Country </span><span style="color:red;">Title</span><span style="color:blue;">="Ireland" </span><span style="color:red;">Location</span><span style="color:blue;">="192,90" </span><span style="color:red;">FlagImage</span><span style="color:blue;">="Images/IRE.png" /&gt;
            &lt;</span><span style="color:#a31515;">app</span><span style="color:blue;">:</span><span style="color:#a31515;">Country </span><span style="color:red;">Title</span><span style="color:blue;">="New Zealand" </span><span style="color:red;">Location</span><span style="color:blue;">="404,225" </span><span style="color:red;">FlagImage</span><span style="color:blue;">="Images/NZ.png" /&gt;
            &lt;</span><span style="color:#a31515;">app</span><span style="color:blue;">:</span><span style="color:#a31515;">Country </span><span style="color:red;">Title</span><span style="color:blue;">="United States" </span><span style="color:red;">Location</span><span style="color:blue;">="40,80" </span><span style="color:red;">FlagImage</span><span style="color:blue;">="Images/USA.png" /&gt;

        &lt;/</span><span style="color:#a31515;">ItemsControl</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">Canvas</span><span style="color:blue;">&gt;
&lt;/</span><span style="color:#a31515;">UserControl</span><span style="color:blue;">&gt;</span></pre>
<p>This Xaml produces the following control hierarchy:</p>
<p><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="Customized ItemsControl Template Output" src="http://petermcg.files.wordpress.com/2009/02/customizeditemscontroltemplateoutput1.png?w=450&#038;h=483" border="0" alt="Customized ItemsControl Template Output" width="450" height="483" /></p>
<p>The contents of the three custom templates are defined in the Resources section of the UserControl and bound to the relevant properties of the instance of ItemsControl.  Firstly the ControlTemplate specified in the Template property has been used to surround the ItemsPresenter with a blank Border.  Secondly the ItemsPanelTemplate specified in the ItemsPanel property means the ItemsPresenter now has a Grid as it’s content rather than a StackPanel.  Finally the DataTemplate specified in the ItemTemplate property has completely replaced the default Grid with a Canvas containing an Image and a StackPanel.  The contents of the DataTemplate are interspersed with Binding expressions to extract data from each item in the ItemsControl, in this case instances of the simple Country class shown below:</p>
<pre class="code"><span style="color:blue;">using </span>System.ComponentModel;
<span style="color:blue;">using </span>System.Windows;

<span style="color:blue;">namespace </span>ItemsControlImages
{
    <span style="color:blue;">public class </span><span style="color:#2b91af;">Country </span>: <span style="color:#2b91af;">INotifyPropertyChanged
    </span>{
        <span style="color:blue;">private string </span>title;
        <span style="color:blue;">private string </span>flagImage;
        <span style="color:blue;">private </span><span style="color:#2b91af;">Point </span>location;

        <span style="color:blue;">public string </span>Title
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return this</span>.title;
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">if </span>((<span style="color:blue;">object</span>.ReferenceEquals(<span style="color:blue;">this</span>.title, <span style="color:blue;">value</span>) != <span style="color:blue;">true</span>))
                {
                    <span style="color:blue;">this</span>.title = <span style="color:blue;">value</span>;
                    <span style="color:blue;">this</span>.RaisePropertyChanged(<span style="color:#a31515;">"Title"</span>);
                }
            }
        }

        <span style="color:blue;">public string </span>FlagImage
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return this</span>.flagImage;
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">if </span>((<span style="color:blue;">object</span>.ReferenceEquals(<span style="color:blue;">this</span>.flagImage, <span style="color:blue;">value</span>) != <span style="color:blue;">true</span>))
                {
                    <span style="color:blue;">this</span>.flagImage = <span style="color:blue;">value</span>;
                    <span style="color:blue;">this</span>.RaisePropertyChanged(<span style="color:#a31515;">"FlagImage"</span>);
                }
            }
        }

        <span style="color:blue;">public </span><span style="color:#2b91af;">Point </span>Location
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return this</span>.location;
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">if </span>((<span style="color:blue;">this</span>.location.Equals(<span style="color:blue;">value</span>) != <span style="color:blue;">true</span>))
                {
                    <span style="color:blue;">this</span>.location = <span style="color:blue;">value</span>;
                    <span style="color:blue;">this</span>.RaisePropertyChanged(<span style="color:#a31515;">"Location"</span>);
                }
            }
        }

        <span style="color:blue;">#region </span>INotifyPropertyChanged Members

        <span style="color:blue;">public event </span><span style="color:#2b91af;">PropertyChangedEventHandler </span>PropertyChanged;

        <span style="color:blue;">protected void </span>RaisePropertyChanged(<span style="color:blue;">string </span>propertyName)
        {
            <span style="color:#2b91af;">PropertyChangedEventHandler </span>propertyChanged = <span style="color:blue;">this</span>.PropertyChanged;

            <span style="color:blue;">if </span>(propertyChanged != <span style="color:blue;">null</span>)
            {
                propertyChanged(<span style="color:blue;">this</span>, <span style="color:blue;">new </span><span style="color:#2b91af;">PropertyChangedEventArgs</span>(propertyName));
            }
        }

        <span style="color:blue;">#endregion
    </span>}
}</pre>
<p>This all conspires to produce the following UI:</p>
<p><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="Positioned ItemsControl Images" src="http://petermcg.files.wordpress.com/2009/02/positioneditemscontrolimages1.png?w=572&#038;h=434" border="0" alt="Positioned ItemsControl Images" width="572" height="434" /></p>
<p>Note even though the Images are in an ItemsControl they are positioned at the coordinates shown by setting the value of the Left and Top attached properties of their parent Canvas to the value of the X and Y coordinates from the custom Location property via the Bindings specified in the DataTemplate assigned to the ItemsControl’s ItemTemplate property.</p>
<p>The images used in the sample application are from <a href="http://commons.wikimedia.org/wiki/National_insignia" target="_blank">this article</a> on WikiMedia and the control hierarchy images were produced from screenshots of the excellent <a href="http://firstfloorsoftware.com/silverlightspy/download-silverlight-spy/" target="_blank">Silverlight Spy 2</a> which I highly recommend.</p>
<br />Posted in ItemsControl, Silverlight, XAML Tagged: ControlTemplate, DataTemplate, ItemsControl, ItemsPanel, ItemTemplate, Silverlight <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/192/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/192/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/192/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=192&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2009/02/15/customizing-the-silverlight-2-itemscontrol-with-templates/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/02/itemscontrolderivedtypes1.png" medium="image">
			<media:title type="html">ItemsControl Derived Types</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/02/defaultitemscontroltemplateoutput1.png" medium="image">
			<media:title type="html">Default ItemsControl Template Output</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/02/customizeditemscontroltemplateoutput1.png" medium="image">
			<media:title type="html">Customized ItemsControl Template Output</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/02/positioneditemscontrolimages1.png" medium="image">
			<media:title type="html">Positioned ItemsControl Images</media:title>
		</media:content>
	</item>
		<item>
		<title>Filtering Silverlight DataGrid Rows with ApplyMutateFilter&lt;T&gt;</title>
		<link>http://petermcg.wordpress.com/2009/01/29/filtering-silverlight-datagrid-rows/</link>
		<comments>http://petermcg.wordpress.com/2009/01/29/filtering-silverlight-datagrid-rows/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 11:42:35 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[DataGrid]]></category>
		<category><![CDATA[Extension Method]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[DataGrid Row Visibility]]></category>
		<category><![CDATA[ObservableCollection]]></category>
		<category><![CDATA[Silverlight 2]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2009/01/29/filtering-silverlight-datagrid-rows/</guid>
		<description><![CDATA[(Code download) This post presents a solution to a question on Stack Overflow which I found interesting, this is a question I&#8217;ve seen crop up a few times now in one form or another: &#34;I have an ObservableCollection feeding a DataGrid that is updating nicely.&#160; The point: I want to filter (collapse) the rows without [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=183&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[</p>
<p><strong>(<a target="_blank" href="http://cid-920505bfc4faba01.skydrive.live.com/embedrowdetail.aspx/Public/DataGridRowFiltering.zip">Code download</a>)</strong></p>
<p>This post presents a solution to <a target="_blank" href="http://stackoverflow.com/questions/485437/silverlight-datagridrows-in-a-datagrid-how-do-i-hide-them-selectively">a question on Stack Overflow</a> which I found interesting, this is a question I&#8217;ve seen crop up a few times now in one form or another:</p>
<p><em>&quot;I have an ObservableCollection feeding a DataGrid that is updating nicely.&#160; The point: I want to filter (collapse) the rows without removing them from the collection.&#160; Is there a way to do this?&quot;</em></p>
<p>You can remove rows from a DataGrid by removing items from the ObservableCollection&lt;T&gt; that the grid&#8217;s ItemsSource property is bound to, but the question asks is there a way to avoid this.&#160; The way I see it a solution to this question will firstly offer a way to filter the rows displayed in a DataGrid without affecting the Count of the original ObservableCollection&lt;T&gt; and secondly provide a way to easily discern which rows are currently filtered and which are displayed after the filter has been applied.&#160; The intent is also to provide a solution general enough to be reused with any type T in an ObservableCollection&lt;T&gt;.</p>
<p>The solution structure of the simple demo solution available for download above looks as follows:</p>
<p><img style="display:inline;border-width:0;" title="Solution Structure" border="0" alt="Solution Structure" src="http://petermcg.files.wordpress.com/2009/01/solutionstructure.png?w=328&#038;h=431" width="328" height="431" /> </p>
<p>The demo application running looks as follows:</p>
<p><img style="display:inline;border-width:0;" title="App Running Pre-Filter" border="0" alt="App Running Pre-Filter" src="http://petermcg.files.wordpress.com/2009/01/apprunningprefilter.png?w=832&#038;h=675" width="832" height="675" /> </p>
<p>This UI is produced from the contents of Page.xaml:</p>
<pre class="code"><span style="color:blue;">&lt;</span><span style="color:#a31515;">UserControl </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Class</span><span style="color:blue;">=&quot;DataGridRowFiltering.Page&quot;
             </span><span style="color:red;">xmlns</span><span style="color:blue;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             </span><span style="color:red;">xmlns</span><span style="color:blue;">:</span><span style="color:red;">x</span><span style="color:blue;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             </span><span style="color:red;">xmlns</span><span style="color:blue;">:</span><span style="color:red;">data</span><span style="color:blue;">=&quot;clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data&quot;
             </span><span style="color:red;">xmlns</span><span style="color:blue;">:</span><span style="color:red;">input</span><span style="color:blue;">=&quot;clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls.Input&quot;&gt;

    &lt;</span><span style="color:#a31515;">StackPanel </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;5,5,5,5&quot; </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;LayoutRoot&quot; </span><span style="color:red;">Background</span><span style="color:blue;">=&quot;White&quot;&gt;

        &lt;</span><span style="color:#a31515;">StackPanel </span><span style="color:red;">Orientation</span><span style="color:blue;">=&quot;Horizontal&quot; </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;0,15,0,15&quot;&gt;
            &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">=&quot;Age Filter&quot; </span><span style="color:red;">FontSize</span><span style="color:blue;">=&quot;16&quot; </span><span style="color:red;">VerticalAlignment</span><span style="color:blue;">=&quot;Center&quot; </span><span style="color:red;">TextAlignment</span><span style="color:blue;">=&quot;Center&quot; </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;0,0,10,0&quot; /&gt;

            &lt;</span><span style="color:#a31515;">input</span><span style="color:blue;">:</span><span style="color:#a31515;">NumericUpDown </span><span style="color:red;">Width</span><span style="color:blue;">=&quot;40&quot; </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;FilterValue&quot; </span><span style="color:red;">DecimalPlaces</span><span style="color:blue;">=&quot;0&quot; </span><span style="color:red;">Minimum</span><span style="color:blue;">=&quot;20.0&quot; </span><span style="color:red;">Maximum</span><span style="color:blue;">=&quot;25.0&quot; </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;0,0,10,0&quot; /&gt;

            &lt;</span><span style="color:#a31515;">Button </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;FilterButton&quot; </span><span style="color:red;">Content</span><span style="color:blue;">=&quot;Apply Filter&quot; </span><span style="color:red;">Click</span><span style="color:blue;">=&quot;FilterButton_Click&quot; /&gt;
        &lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;

        &lt;</span><span style="color:#a31515;">StackPanel </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;0,15,0,15&quot;&gt;
            &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">=&quot;Filtered People&quot; </span><span style="color:red;">FontSize</span><span style="color:blue;">=&quot;16&quot; /&gt;
            &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGrid </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;FilteredPeople&quot;  </span><span style="color:red;">AutoGenerateColumns</span><span style="color:blue;">=&quot;True&quot; </span><span style="color:red;">IsReadOnly</span><span style="color:blue;">=&quot;True&quot; /&gt;
        &lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;

        &lt;</span><span style="color:#a31515;">StackPanel </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;0,15,0,15&quot;&gt;
            &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">=&quot;All People&quot; </span><span style="color:red;">FontSize</span><span style="color:blue;">=&quot;16&quot; /&gt;
            &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGrid </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;AllPeople&quot;  </span><span style="color:red;">AutoGenerateColumns</span><span style="color:blue;">=&quot;True&quot; </span><span style="color:red;">IsReadOnly</span><span style="color:blue;">=&quot;True&quot; /&gt;
        &lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;

    &lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;
&lt;/</span><span style="color:#a31515;">UserControl</span><span style="color:blue;">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>The Xaml contains two DataGrids, a NumericUpDown control from the <a target="_blank" href="http://www.codeplex.com/Silverlight">Silverlight Toolkit</a> and a standard Button control.&#160; When the &#8216;Apply Filter&#8217; button is clicked the people (or rows) shown in the FilteredPeople grid are filtered, the row count in the AllPeople grid remains unchanged.&#160; The filter excludes people whose Age property does not equal the current value of the NumericUpDown control.</p>
<p>The events for the UI are in Page.xaml.cs:</p>
<pre class="code"><span style="color:blue;">using </span>System;
<span style="color:blue;">using </span>System.Collections.ObjectModel;
<span style="color:blue;">using </span>System.Linq;
<span style="color:blue;">using </span>System.Windows;
<span style="color:blue;">using </span>System.Windows.Controls;

<span style="color:blue;">namespace </span>DataGridRowFiltering
{
    <span style="color:blue;">public partial class </span><span style="color:#2b91af;">Page </span>: <span style="color:#2b91af;">UserControl
    </span>{
        <span style="color:#2b91af;">ObservableCollection</span>&lt;<span style="color:#2b91af;">Person</span>&gt; people = <span style="color:blue;">new </span><span style="color:#2b91af;">ObservableCollection</span>&lt;<span style="color:#2b91af;">Person</span>&gt;()
        {
            <span style="color:blue;">new </span><span style="color:#2b91af;">Person</span>(<span style="color:#a31515;">&quot;Peter&quot;</span>, 20),
            <span style="color:blue;">new </span><span style="color:#2b91af;">Person</span>(<span style="color:#a31515;">&quot;Bill&quot;</span>, 21),
            <span style="color:blue;">new </span><span style="color:#2b91af;">Person</span>(<span style="color:#a31515;">&quot;Joe&quot;</span>, 21),
            <span style="color:blue;">new </span><span style="color:#2b91af;">Person</span>(<span style="color:#a31515;">&quot;David&quot;</span>, 23),
            <span style="color:blue;">new </span><span style="color:#2b91af;">Person</span>(<span style="color:#a31515;">&quot;Steve&quot;</span>, 24),
            <span style="color:blue;">new </span><span style="color:#2b91af;">Person</span>(<span style="color:#a31515;">&quot;Jeff&quot;</span>, 25),
        };

        <span style="color:blue;">public </span>Page()
        {
            InitializeComponent();

            Loaded += Page_Loaded;
        }

        <span style="color:blue;">private void </span>Page_Loaded(<span style="color:blue;">object </span>sender, <span style="color:#2b91af;">RoutedEventArgs </span>e)
        {
            FilteredPeople.ItemsSource = people;
            AllPeople.ItemsSource = people;
        }

        <span style="color:blue;">private void </span>FilterButton_Click(<span style="color:blue;">object </span>sender, <span style="color:#2b91af;">RoutedEventArgs </span>e)
        {
            <span style="color:blue;">int </span>selectedAge = <span style="color:#2b91af;">Convert</span>.ToInt32(FilterValue.Value);

            FilteredPeople.ItemsSource = people.ApplyMutateFilter(p =&gt; p.Age == selectedAge,
                                                                  p =&gt; p.IsVisible = <span style="color:blue;">true</span>,
                                                                  p =&gt; p.IsVisible = <span style="color:blue;">false</span>);
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>The Page class has an ObservableCollection&lt;Person&gt; called &#8216;people&#8217; containing 6 instances of the Person class.&#160; The Person class is a simple class that implements the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(VS.95).aspx">INotifyPropertyChanged interface</a> and has properties called FirstName, Age and IsVisible.</p>
<p>When an instance of the Page UserControl is loaded the ItemsSource property of both DataGrids is bound to the people collection resulting in the screenshot shown earlier.</p>
<p>When the &#8216;Apply Filter&#8217; button is clicked we store the current value of the NumericUpDown control in the selectedAge variable and set the ItemsSource of the FilteredPeople grid to the result of calling the ApplyMutateFilter&lt;T&gt; extension method:</p>
<pre class="code"><span style="color:blue;">using </span>System;
<span style="color:blue;">using </span>System.Collections.Generic;
<span style="color:blue;">using </span>System.Linq;

<span style="color:blue;">namespace </span>DataGridRowFiltering
{
    <span style="color:blue;">public static class </span><span style="color:#2b91af;">Extensions
    </span>{
        <span style="color:gray;">/// &lt;summary&gt;
        /// </span><span style="color:green;">Applies an action to each item in the sequence, which action depends on the evaluation of the predicate.
        </span><span style="color:gray;">/// &lt;/summary&gt;
        /// &lt;typeparam name=&quot;TSource&quot;&gt;</span><span style="color:green;">The type of the elements of source.</span><span style="color:gray;">&lt;/typeparam&gt;
        /// &lt;param name=&quot;source&quot;&gt;</span><span style="color:green;">A sequence to filter.</span><span style="color:gray;">&lt;/param&gt;
        /// &lt;param name=&quot;predicate&quot;&gt;</span><span style="color:green;">A function to test each element for a condition.</span><span style="color:gray;">&lt;/param&gt;
        /// &lt;param name=&quot;posAction&quot;&gt;</span><span style="color:green;">An action used to mutate elements that match the predicate's condition.</span><span style="color:gray;">&lt;/param&gt;
        /// &lt;param name=&quot;negAction&quot;&gt;</span><span style="color:green;">An action used to mutate elements that do not match the predicate's condition.</span><span style="color:gray;">&lt;/param&gt;
        /// &lt;returns&gt;</span><span style="color:green;">The elements in the sequence that matched the predicate's condition and were transformed by posAction.</span><span style="color:gray;">&lt;/returns&gt;
        </span><span style="color:blue;">public static </span><span style="color:#2b91af;">IEnumerable</span>&lt;TSource&gt; ApplyMutateFilter&lt;TSource&gt;(<span style="color:blue;">this </span><span style="color:#2b91af;">IEnumerable</span>&lt;TSource&gt; source,
                                                                      <span style="color:#2b91af;">Func</span>&lt;TSource, <span style="color:blue;">bool</span>&gt; predicate,
                                                                      <span style="color:#2b91af;">Action</span>&lt;TSource&gt; posAction,
                                                                      <span style="color:#2b91af;">Action</span>&lt;TSource&gt; negAction)
        {
            <span style="color:blue;">if </span>(source != <span style="color:blue;">null</span>)
            {
                <span style="color:blue;">foreach </span>(TSource item <span style="color:blue;">in </span>source)
                {
                    <span style="color:blue;">if </span>(predicate(item))
                    {
                        posAction(item);
                    }
                    <span style="color:blue;">else
                    </span>{
                        negAction(item);
                    }
                }
            }

            <span style="color:blue;">return </span>source.Where(predicate);
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>This method takes one predicate and two actions.&#160; A &#8216;predicate&#8217; in this case just means a function that takes a parameter of type TSource and returns true or false.&#160; Similarly an &#8216;action&#8217; is just a function that takes a parameter of type TSource and returns void.</p>
<p>In the call to ApplyMutateFilter&lt;T&gt; in the event handler for the button&#8217;s Click event above, the predicate function is designed to return the result of the comparison between a Person object&#8217;s Age property and the value of selectedAge.&#160; The two action functions are designed to set the value of the IsVisible property on a Person object to either true or false.</p>
<p>The ApplyMutateFilter&lt;T&gt; extension method body applies one of these actions to every item in the sequence, which action depends on the evaluation of the predicate.&#160; If the predicate returns true the positive action is executed otherwise the negative action is executed resulting in the value of the IsVisible property changing.</p>
<p>Finally only the elements in the sequence that matched the predicate are returned with the call to the Where&lt;T&gt; extension method, thus the filter is applied.<br />
  <br />It&#8217;s important to remember that setting the IsVisible property does not make the row disappear from the DataGrid; it&#8217;s the call to Where&lt;T&gt; that filters the sequence.&#160; The IsVisible property is merely a convenient way of later finding which elements have been affected by the current filter in code, for example if you wanted to know what rows are currently being shown in the DataGrid after a filter has been applied.</p>
<p>Here is a screen shot after clicking the &#8216;Apply Filter&#8217; button with a selected age of 21:</p>
<p><img style="display:inline;border-width:0;" title="App Running Post-Filter" border="0" alt="App Running Post-Filter" src="http://petermcg.files.wordpress.com/2009/01/apprunningpostfilter.png?w=832&#038;h=675" width="832" height="675" /> </p>
<p>The FilteredPeople DataGrid now only displays people aged 21.&#160; The grid is now bound to the filtered sequence returned from the call to ApplyMutateFilter&lt;T&gt; with a predicate comparing each Person object&#8217;s Age property to the selectedAge of 21.</p>
<p>The screenshot shows the rows have been filtered in the first DataGrid without affecting the Count of the original ObservableCollection&lt;T&gt; which the second DataGrid&#8217;s is still bound to, thus satisfying the first task we set out to achieve.</p>
<p>Finally it&#8217;s clear to see the second requirement has been fulfilled from the state of the IsVisible properties. The value of this property makes it easy to discern which rows in the original ObservableCollection&lt;T&gt; are currently filtered and which are displayed after the filter has been applied.</p>
<p>Altering the predicate is all that&#8217;s required to apply a filter to a different property/column or a combination of several properties/columns.</p>
<br />Posted in DataGrid, Extension Method, Silverlight Tagged: DataGrid, DataGrid Row Visibility, ObservableCollection, Silverlight 2 <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/183/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=183&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2009/01/29/filtering-silverlight-datagrid-rows/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/01/solutionstructure.png" medium="image">
			<media:title type="html">Solution Structure</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/01/apprunningprefilter.png" medium="image">
			<media:title type="html">App Running Pre-Filter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2009/01/apprunningpostfilter.png" medium="image">
			<media:title type="html">App Running Post-Filter</media:title>
		</media:content>
	</item>
		<item>
		<title>Silverlight 2 WCF Polling Duplex Support &#8211; Part 4: Adding a WPF Client</title>
		<link>http://petermcg.wordpress.com/2008/11/19/silverlight-polling-duplex-part-4-wpf-client/</link>
		<comments>http://petermcg.wordpress.com/2008/11/19/silverlight-polling-duplex-part-4-wpf-client/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 04:26:24 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[PollingDuplex]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[ColorAnimationUsingKeyFrames]]></category>
		<category><![CDATA[DataContractSerializer]]></category>
		<category><![CDATA[DuplexReceiver]]></category>
		<category><![CDATA[Polling Duplex]]></category>
		<category><![CDATA[Storyboard]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2008/11/19/silverlight-polling-duplex-part-4-wpf-client/</guid>
		<description><![CDATA[(Code download) Introduction This post attempts to highlight some of the intricacies involved in connecting a WPF Client to the existing Silverlight 2 Polling Duplex demo previously published on this blog.&#160; To recap, the demo consists of a WCF service designed to push Stock data to previously connected Silverlight 2 clients over Http.&#160; In a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=179&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong><span style="color:#ff0000;"></span></strong><strong>(<a target="_blank" href="http://cid-920505bfc4faba01.skydrive.live.com/embedrowdetail.aspx/Public/PollingDuplexWpfDemo.zip">Code download</a>)</strong></p>
<h5>Introduction</h5>
<p>This post attempts to highlight some of the intricacies involved in connecting a WPF Client to <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture/">the existing Silverlight 2 Polling Duplex demo</a> previously published on this blog.&#160; To recap, the demo consists of a WCF service designed to push Stock data to previously connected Silverlight 2 clients over Http.&#160; In a similar scenario to a chat application, the Silverlight 2 clients can also send &#8216;Note&#8217; messages back to the server and have them propagated to other connected clients.</p>
<p>The aim of this post is to make the demo capable of also supporting connections from WPF clients.&#160; Success is defined by enabling WPF clients to connect to the same WCF service, receive the same Stock updates at the same time as the Silverlight 2 clients and having Notes synchronized across all connected clients regardless of their underlying technology.&#160; Below is a link to a screenshot of the final version of this demo running, shown is the Console Application hosting the WCF service with two Silverlight clients and one WPF client connected:</p>
<p><a target="_blank" href="http://petermcg.files.wordpress.com/2008/11/serverandallclientsrunning.png"><img style="display:inline;border-width:0;" title="Server and All Clients Running" border="0" alt="Server and All Clients Running" src="http://petermcg.files.wordpress.com/2008/11/serverandallclientsrunning-thumb.png?w=621&#038;h=480" width="621" height="480" /></a></p>
<h5>PollingDuplexHttpBinding and WPF clients</h5>
<p>Up until this point the demo application has solely supported pushing data to Silverlight 2 clients, defining a <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.pollingduplexhttpbinding(VS.95).aspx">PollingDuplexHttpBinding</a> endpoint on the server side and creating a channel factory as part of the Silverlight 2 client as shown below:</p>
<pre class="code"><span style="color:green;">// Create a channel factory capable of producing a channel of type IDuplexSessionChannel
</span><span style="color:#2b91af;">IChannelFactory</span>&lt;<span style="color:#2b91af;">IDuplexSessionChannel</span>&gt; factory = <span style="color:blue;">new </span><span style="color:#2b91af;">PollingDuplexHttpBinding</span>().BuildChannelFactory&lt;<span style="color:#2b91af;">IDuplexSessionChannel</span>&gt;();</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>However, attempting to use PollingDuplexHttpBinding for this purpose in a WPF application (as in the code above) currently results in a NotSupportedException exception being raised with a full explanation and even some architectural advice:</p>
<p><img style="display:inline;border-width:0;" title="Polling Duplex NotSupportedException" border="0" alt="Polling Duplex NotSupportedException" src="http://petermcg.files.wordpress.com/2008/11/pollingduplexnotsupportedexception.png?w=484&#038;h=344" width="484" height="344" /></p>
<p>PollingDuplexHttpBinding cannot currently be used in non-Silverlight clients without running into this exception.&#160; In order to extend the demo to support pushing Stock data to a WPF client through Http the guidance from the above exception is to consider <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.wsdualhttpbinding.aspx">WSDualHttpBinding</a>.&#160; This binding predates Silverlight and is the closest alternative for achieving equivalent results to PollingDuplexHttpBinding in a non-Silverlight client application.&#160; A look at the BindingElement objects each binding encapsulates reveals WSDualHttpBinding is actually a much more mature binding than PollingDuplexHttpBinding:</p>
<table border="1" cellspacing="0" cellpadding="2" width="400">
<thead>
<tr>
<th valign="top" width="200">WSDualHttpBinding</th>
<th valign="top" width="200">PollingDuplexHttpBinding</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="200">TransactionFlowBindingElement</td>
<td valign="top" width="200">PollingDuplexBindingElement</td>
</tr>
<tr>
<td valign="top" width="200">ReliableSessionBindingElement</td>
<td valign="top" width="200">TextMessageEncodingBindingElement</td>
</tr>
<tr>
<td valign="top" width="200">SymmetricSecurityBindingElement</td>
<td valign="top" width="200">HttpTransportBindingElement</td>
</tr>
<tr>
<td valign="top" width="200">CompositeDuplexBindingElement</td>
<td valign="top" width="200">&#160;</td>
</tr>
<tr>
<td valign="top" width="200">OneWayBindingElement</td>
<td valign="top" width="200">&#160;</td>
</tr>
<tr>
<td valign="top" width="200">TextMessageEncodingBindingElement</td>
<td valign="top" width="200">&#160;</td>
</tr>
<tr>
<td valign="top" width="200">HttpTransportBindingElement</td>
<td valign="top" width="200">&#160;</td>
</tr>
</tbody>
</table>
<h5>The WSDualHttpBinding Endpoint</h5>
<p>The outcome of acting on the aforementioned advice in the demo application is the addition of a new endpoint to the WCF service exposed from the StockServer Console Application.&#160; This could easily be specified entirely in a configuration file (<a target="_blank" href="http://petermcg.wordpress.com/2008/10/23/configuring-silverlight-2-polling-duplex-config/">see this post</a> for how to configure the Silverlight policy and duplex endpoints) but in the download is achieved in code as shown below:</p>
<pre class="code"><span style="color:blue;">using </span>System;
<span style="color:blue;">using </span>System.ServiceModel;
<span style="color:blue;">using </span>System.ServiceModel.Description;

<span style="color:blue;">namespace </span>StockServer
{
    <span style="color:blue;">public class </span><span style="color:#2b91af;">StockServiceHost </span>: <span style="color:#2b91af;">ServiceHost
    </span>{
        <span style="color:blue;">public </span>StockServiceHost(<span style="color:blue;">object </span>singletonInstance, <span style="color:blue;">params </span><span style="color:#2b91af;">Uri</span>[] baseAddresses)
            : <span style="color:blue;">base</span>(singletonInstance, baseAddresses)
        {
        }

        <span style="color:blue;">public </span>StockServiceHost(<span style="color:#2b91af;">Type </span>serviceType, <span style="color:blue;">params </span><span style="color:#2b91af;">Uri</span>[] baseAddresses)
            : <span style="color:blue;">base</span>(serviceType, baseAddresses)
        {
        }

        <span style="color:blue;">protected override void </span>InitializeRuntime()
        {
            <span style="color:blue;">this</span>.AddServiceEndpoint(
                <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">IPolicyProvider</span>),
                <span style="color:blue;">new </span><span style="color:#2b91af;">WebHttpBinding</span>(),
                <span style="color:blue;">new </span><span style="color:#2b91af;">Uri</span>(<span style="color:#a31515;">&quot;http://localhost:10201/&quot;</span>)).Behaviors.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">WebHttpBehavior</span>());

            <span style="color:blue;">this</span>.AddServiceEndpoint(
                <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">IStockService</span>),
                <span style="color:blue;">new </span><span style="color:#2b91af;">PollingDuplexHttpBinding</span>(),
                <span style="color:blue;">new </span><span style="color:#2b91af;">Uri</span>(<span style="color:#a31515;">&quot;http://localhost:10201/SilverlightStockService&quot;</span>));

            <span style="color:blue;">this</span>.AddServiceEndpoint(
                <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">IStockService</span>),
                <span style="color:blue;">new </span><span style="color:#2b91af;">WSDualHttpBinding</span>(<span style="color:#2b91af;">WSDualHttpSecurityMode</span>.None),
                <span style="color:blue;">new </span><span style="color:#2b91af;">Uri</span>(<span style="color:#a31515;">&quot;http://localhost:10201/WpfStockService&quot;</span>));

            <span style="color:blue;">base</span>.InitializeRuntime();
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Although the WSDualHttpBinding endpoint is registered using a different URI, the endpoint is simply just another entry point into the same WCF service called by the existing Silverlight 2 clients using PollingDuplexHttpBinding.&#160; Before you can push data from a WCF duplex service to a client, the client must initiate the session by calling the service.&#160; The Register method serves this purpose in the demo application and the only change to the code in the WCF service itself (although there are no method signature changes) is in this method as shown below:</p>
<pre class="code"><span style="color:blue;">public void </span>Register(<span style="color:#2b91af;">Message </span>message)
{
    client = <span style="color:blue;">new </span><span style="color:#2b91af;">StockClient</span>(<span style="color:#2b91af;">OperationContext</span>.Current.GetCallbackChannel&lt;<span style="color:#2b91af;">IStockClient</span>&gt;(),
                                  <span style="color:#a31515;">&quot;StockClient/IStockService/Receive&quot;</span>,
                                  message.Version);
    client.Faulted += OnClientFaulted;

    InitialReply();

    <span style="color:#2b91af;">StockGenerator</span>.Instance.DeltaReceived += OnDeltaReceived;
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>The change is minor but essential: extracting the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.messageversion.aspx">MessageVersion</a> from the initial message sent by the client and passing it to the constructor of the StockClient object along with a reference to the channel back to that client.&#160; The variety of MessageVersion used by each of the bindings in the demo application is as follows:</p>
<table border="1" cellspacing="0" cellpadding="2" width="400">
<thead>
<tr>
<th valign="top" width="200">Binding</th>
<th valign="top" width="200">MessageVersion</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="200">
<pre class="code"><span style="color:#2b91af;">WSDualHttpBinding</span></pre>
</td>
<td valign="top" width="200">
<pre class="code"><span style="color:#2b91af;">MessageVersion</span>.Soap12WSAddressing10</pre>
</td>
</tr>
<tr>
<td valign="top" width="200">
<pre class="code"><span style="color:#2b91af;">PollingDuplexHttpBinding</span></pre>
</td>
<td valign="top" width="200">
<pre class="code"><span style="color:#2b91af;">MessageVersion</span>.Soap11</pre>
</td>
</tr>
</tbody>
</table>
<p></p>
<p>Messages sent between WSDualHttpBinding endpoints use the SOAP 1.2 protocol; between PollingDuplexHttpBinding endpoints the SOAP 1.1 protocol is employed.&#160; There is a clue in the name of MessageVersion. Soap12WSAddressing10 that WSDualHttpBinding also requires addressing headers to support reliable messaging sessions via <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.reliablesessionbindingelement.aspx">ReliableSessionBindingElement</a>.&#160; In the case of these two bindings, attempting to use a mismatch of MessageVersion and binding, for example MessageVersion.Soap11 for messages sent to a WSDualHttpBinding endpoint, results in an InvalidOperationException as shown below:</p>
<p><img style="display:inline;border-width:0;" title="MessageVersion InvalidOperationException" border="0" alt="MessageVersion InvalidOperationException" src="http://petermcg.files.wordpress.com/2008/11/messageversioninvalidoperationexception.png?w=484&#038;h=363" width="484" height="363" /></p>
<p>Storing the message version along with the channel reference in an instance of the StockClient class (see code download) ensures the reply messages are pushed back to the client in the format the relevant binding expects.&#160; The rest of the WCF service remains the same: a new instance of StockService is created per session regardless of the endpoint used.&#160; Each session registers it&#8217;s interest in the DeltaReceived event of the singleton StockGenerator class.&#160; This event is raised approx every 250 milliseconds and each session&#8217;s handler (OnDeltaReceived) sends the same generated delta to its respective client via the stored channel reference using the appropriate message protocol.</p>
<h5>The WPF Client Application</h5>
<p>In a good advertisement for how nearly all of what you write in Silverlight 2 can be used without modification in WPF, the code in the WPF client application is extremely similar to that contained in the Silverlight 2 client project.&#160; The markup in StockWindow.xaml and code in StockWindow.xaml.cs is virtually identical to Page.xaml and Page.xaml.cs in the Silverlight 2 project. </p>
<p>One difference between the WPF and Silverlight client code is the WPF DataGrid which is from the <a target="_blank" href="http://www.codeplex.com/wpf/Release/ProjectReleases.aspx?ReleaseId=15598">October 2008 Release of the WPF Toolkit</a> available from codeplex.&#160; Another difference already highlighted is that PollingDuplexHttpBinding cannot be used in a non-Silverlight client application.&#160; In its place we use WSDualHttpBinding on the WPF client side also and due to this binding&#8217;s maturity the code in StockTicker.cs is less verbose as shown below:</p>
<pre class="code"><span style="color:blue;">using </span>System;
<span style="color:blue;">using </span>System.Linq;
<span style="color:blue;">using </span>System.Runtime.Serialization;
<span style="color:blue;">using </span>System.ServiceModel;
<span style="color:blue;">using </span>System.ServiceModel.Channels;
<span style="color:blue;">using </span>System.Windows.Threading;
<span style="color:blue;">using </span>Common;

<span style="color:blue;">namespace </span>WpfStockClient
{
    <span style="color:blue;">public sealed class </span><span style="color:#2b91af;">StockTicker </span>: <span style="color:#2b91af;">IStockClient
    </span>{
        <span style="color:green;">// Reference to layout instance that created the StockTicker
        </span><span style="color:blue;">private readonly </span><span style="color:#2b91af;">Dispatcher </span>owner = <span style="color:blue;">null</span>;

        <span style="color:green;">// Serializes instances of the Stock type before they are sent on the wire
        </span><span style="color:blue;">private readonly </span><span style="color:#2b91af;">DataContractSerializer </span>stockSerializer = <span style="color:blue;">new </span><span style="color:#2b91af;">DataContractSerializer</span>(<span style="color:blue;">typeof</span>(<span style="color:#2b91af;">Stock</span>));

        <span style="color:green;">// Proxy for communication to WCF service
        </span><span style="color:blue;">private </span><span style="color:#2b91af;">IStockService </span>proxy;

        <span style="color:green;">// List of stocks designed to be bound to a UI control
        </span><span style="color:blue;">private readonly </span><span style="color:#2b91af;">StockList </span>stockList = <span style="color:blue;">new </span><span style="color:#2b91af;">StockList</span>();

        <span style="color:blue;">public </span><span style="color:#2b91af;">StockList </span>StockList
        {
            <span style="color:blue;">get </span>{ <span style="color:blue;">return </span>stockList; }
        }

        <span style="color:blue;">public </span>StockTicker(<span style="color:#2b91af;">Dispatcher </span>owner)
        {
            <span style="color:blue;">if </span>(owner == <span style="color:blue;">null</span>)
            {
                <span style="color:blue;">throw new </span><span style="color:#2b91af;">ArgumentNullException</span>(<span style="color:#a31515;">&quot;owner&quot;</span>);
            }

            <span style="color:blue;">this</span>.owner = owner;
        }

        <span style="color:blue;">public void </span>SubscribeDeltas()
        {
            <span style="color:#2b91af;">EndpointAddress </span>endPoint = <span style="color:blue;">new </span><span style="color:#2b91af;">EndpointAddress</span>(<span style="color:#a31515;">&quot;http://localhost:10201/WpfStockService&quot;</span>);

            proxy = <span style="color:blue;">new </span><span style="color:#2b91af;">DuplexChannelFactory</span>&lt;<span style="color:#2b91af;">IStockService</span>&gt;(<span style="color:blue;">this</span>,
                                                            <span style="color:blue;">new </span><span style="color:#2b91af;">WSDualHttpBinding</span>(<span style="color:#2b91af;">WSDualHttpSecurityMode</span>.None),
                                                            endPoint).CreateChannel();

            proxy.Register(<span style="color:#2b91af;">Message</span>.CreateMessage(<span style="color:#2b91af;">MessageVersion</span>.Soap12WSAddressing10, <span style="color:#a31515;">&quot;StockClient/IStockService/Register&quot;</span>));
        }

        <span style="color:blue;">public void </span>Receive(<span style="color:#2b91af;">Message </span>message)
        {
            <span style="color:#2b91af;">Stock </span>stock = message.GetBody&lt;<span style="color:#2b91af;">Stock</span>&gt;();

            <span style="color:green;">// Queue a call to UpdateStockList on the Dispatcher of the thread that created this instance
            </span><span style="color:#2b91af;">Action</span>&lt;<span style="color:#2b91af;">Stock</span>&gt; action = UpdateStockList;
            owner.BeginInvoke(action, stock);
        }

        <span style="color:blue;">public void </span>Sync(<span style="color:#2b91af;">Stock </span>stock)
        {
            <span style="color:green;">// Create a message with the appropriate SOAPAction and asynchronously send it via the proxy with the serialized Stock as the body of the envelope
            </span><span style="color:#2b91af;">Message </span>message = <span style="color:#2b91af;">Message</span>.CreateMessage(<span style="color:#2b91af;">MessageVersion</span>.Soap12WSAddressing10, <span style="color:#a31515;">&quot;StockClient/IStockService/Sync&quot;</span>, stock, stockSerializer);
            proxy.Sync(message);
        }

        <span style="color:blue;">private void </span>UpdateStockList(<span style="color:#2b91af;">Stock </span>delta)
        {
            <span style="color:green;">// NOTE : CheckAccess is there but intellisense doesn't see it because of the [EditorBrowsable(EditorBrowsableState.Never)] attribute
            </span><span style="color:blue;">if </span>(!owner.CheckAccess())
            {
                <span style="color:blue;">throw new </span><span style="color:#2b91af;">InvalidOperationException</span>(<span style="color:#a31515;">&quot;The calling thread cannot access this method because a different thread owns it.&quot;</span>);
            }

            <span style="color:green;">// Check if this Stock is already in the collection
            </span><span style="color:#2b91af;">Stock </span>existing = stockList.FirstOrDefault(s =&gt; s.Symbol == delta.Symbol);

            <span style="color:blue;">if </span>(existing == <span style="color:blue;">default</span>(<span style="color:#2b91af;">Stock</span>))
            {
                <span style="color:green;">// This delta is a new Stock
                </span>stockList.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">StockHighlight</span>(delta));
            }
            <span style="color:blue;">else
            </span>{
                <span style="color:green;">// This delta is an existing Stock
                </span>existing.Ask = delta.Ask;
                existing.Bid = delta.Bid;

                <span style="color:blue;">if </span>(!<span style="color:#2b91af;">String</span>.IsNullOrEmpty(delta.Notes))
                {
                    existing.Notes = delta.Notes;
                }
            }
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>There are many similarities between the above code and the Silverlight 2 version; the changes are all centred on the body of the SubscribeDeltas method.&#160; This is where the client instance of the WSDualHttpBinding class is instantiated and used to establish a <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.compositeduplexbindingelement.aspx">composite duplex channel</a> (two one-way channels) with the new endpoint at the address exposed in the WCF service.&#160; The first parameter passed to the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms576164.aspx">DuplexChannelFactory</a>&lt;IStockService&gt;&#160; constructor specifies &#8216;this&#8217; as the instance of the IStockService interface to receive the pushed messages from the WCF service in the Receive method.&#160; After the channel is created the initial message is sent using the correct MessageVersion as described earlier.</p>
<h5>Linked Common Files</h5>
<p>Those class files that are identical across both client projects are added to the Common Solution folder and are <a target="_blank" href="http://pagebrooks.com/archive/2008/10/11/sharing-code-between-.net-and-silverlight-platforms.aspx">referenced using links</a> from the respective projects where they are used:</p>
<p><img style="display:inline;border-width:0;" title="Common Files Linked" border="0" alt="Common Files Linked" src="http://petermcg.files.wordpress.com/2008/11/commonfileslinked.png?w=307&#038;h=625" width="307" height="625" /></p>
<p>The highlighted classes are written in one place and as such are assured of being the same structure throughout the solution (and where relevant on both sides of the wire as a consequence).&#160; As the files are linked, the code they contain will be compiled into IL that targets the respective version of the CLR implied by the type of project the classes are linked from.&#160; For the WPF project the linked classes will be compiled into an assembly that targets the desktop CLR, for the Silverlight project the linked classes will be compiled into an assembly that targets the more compact <a target="_blank" href="http://msdn.microsoft.com/en-us/magazine/cc721609.aspx">CoreCLR</a>.&#160; Linking common files in this manner is one solution to the problem normally solved by using a class library when a common CLR is targeted by all projects.</p>
<h5>Animating the Stock Price changes</h5>
<p>Illustrating changes to Stock price instances displayed in the DataGrid by creating the illusion that the DataGrid cell background is changing color takes less code in WPF than in Silverlight.&#160; The code for this animation for both WPF and Silverlight 2 is contained in the StockHighlight class.&#160; The entire contents of the StockHighlight.cs file is shown below, the code between the #if and #endif directives is compiled only if the SILVERLIGHT symbol is defined as it is in the Build tab of project properties on all default Silverlight 2 projects:</p>
<pre class="code"><span style="color:blue;">using </span>System;
<span style="color:blue;">using </span>System.Runtime.Serialization;
<span style="color:blue;">using </span>System.Windows;
<span style="color:blue;">using </span>System.Windows.Media;
<span style="color:blue;">using </span>System.Windows.Media.Animation;

<span style="color:blue;">namespace </span>Common
{
    [<span style="color:#2b91af;">DataContract</span>(Name = <span style="color:#a31515;">&quot;Stock&quot;</span>, Namespace = <span style="color:#a31515;">&quot;urn:petermcg.wordpress.com&quot;</span>)]
    <span style="color:blue;">public class </span><span style="color:#2b91af;">StockHighlight </span>: <span style="color:#2b91af;">Stock
    </span>{
        <span style="color:blue;">public </span><span style="color:#2b91af;">SolidColorBrush </span>AskHighlight { <span style="color:blue;">get</span>; <span style="color:blue;">private set</span>; }
        <span style="color:blue;">public </span><span style="color:#2b91af;">SolidColorBrush </span>BidHighlight { <span style="color:blue;">get</span>; <span style="color:blue;">private set</span>; }

<span style="color:blue;">#if </span>SILVERLIGHT
        <span style="color:blue;">private </span><span style="color:#2b91af;">Storyboard </span>askPosStory = <span style="color:blue;">new </span><span style="color:#2b91af;">Storyboard</span>();
        <span style="color:blue;">private </span><span style="color:#2b91af;">Storyboard </span>askNegStory = <span style="color:blue;">new </span><span style="color:#2b91af;">Storyboard</span>();
        <span style="color:blue;">private </span><span style="color:#2b91af;">Storyboard </span>bidPosStory = <span style="color:blue;">new </span><span style="color:#2b91af;">Storyboard</span>();
        <span style="color:blue;">private </span><span style="color:#2b91af;">Storyboard </span>bidNegStory = <span style="color:blue;">new </span><span style="color:#2b91af;">Storyboard</span>();
<span style="color:blue;">#endif

        private static readonly </span><span style="color:#2b91af;">Duration </span>DefaultDuration = <span style="color:blue;">new </span><span style="color:#2b91af;">Duration</span>(<span style="color:#2b91af;">TimeSpan</span>.FromSeconds(2.0));
        <span style="color:blue;">private static readonly </span><span style="color:#2b91af;">Color </span>DefaultColor = <span style="color:#2b91af;">Colors</span>.Transparent;

        <span style="color:blue;">public </span>StockHighlight(<span style="color:#2b91af;">Stock </span>stock)
        {
            <span style="color:blue;">base</span>.Ask = stock.Ask;
            <span style="color:blue;">base</span>.Bid = stock.Bid;
            <span style="color:blue;">base</span>.Notes = stock.Notes;
            <span style="color:blue;">base</span>.Symbol = stock.Symbol;

            InitializeAnimation();
        }

        <span style="color:blue;">private void </span>InitializeAnimation()
        {
            <span style="color:green;">// Default highlight color to Transparent
            </span><span style="color:blue;">this</span>.AskHighlight = <span style="color:blue;">new </span><span style="color:#2b91af;">SolidColorBrush</span>(DefaultColor);
            <span style="color:blue;">this</span>.BidHighlight = <span style="color:blue;">new </span><span style="color:#2b91af;">SolidColorBrush</span>(DefaultColor);

<span style="color:blue;">#if </span>SILVERLIGHT
            InitializeAnimation(AskHighlight, askPosStory, askNegStory);
            InitializeAnimation(BidHighlight, bidPosStory, bidNegStory);
<span style="color:blue;">#endif
        </span>}

<span style="color:blue;">#if </span>SILVERLIGHT
        <span style="color:blue;">private static void </span>InitializeAnimation(<span style="color:#2b91af;">SolidColorBrush </span>brush, <span style="color:#2b91af;">Storyboard </span>pos, <span style="color:#2b91af;">Storyboard </span>neg)
        {
            <span style="color:green;">// Set up a unique Positive and Negative ColorAnimationUsingKeyFrames for  price
            </span><span style="color:#2b91af;">ColorAnimationUsingKeyFrames </span>posAnim = <span style="color:blue;">new </span><span style="color:#2b91af;">ColorAnimationUsingKeyFrames</span>();
            posAnim.KeyFrames.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">LinearColorKeyFrame</span>() { KeyTime = <span style="color:#2b91af;">TimeSpan</span>.FromSeconds(0.0), Value = <span style="color:#2b91af;">Colors</span>.Green });
            posAnim.KeyFrames.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">LinearColorKeyFrame</span>() { KeyTime = DefaultDuration.TimeSpan, Value = DefaultColor });
            posAnim.Duration = DefaultDuration;

            <span style="color:#2b91af;">ColorAnimationUsingKeyFrames </span>negAnim = <span style="color:blue;">new </span><span style="color:#2b91af;">ColorAnimationUsingKeyFrames</span>();
            negAnim.KeyFrames.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">LinearColorKeyFrame</span>() { KeyTime = <span style="color:#2b91af;">TimeSpan</span>.FromSeconds(0.0), Value = <span style="color:#2b91af;">Colors</span>.Red });
            negAnim.KeyFrames.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">LinearColorKeyFrame</span>() { KeyTime = DefaultDuration.TimeSpan, Value = DefaultColor });
            negAnim.Duration = DefaultDuration;

            <span style="color:green;">// Add animations to storyboard
            </span>pos.Children.Add(posAnim);
            neg.Children.Add(negAnim);

            <span style="color:green;">// Target the  color animations to the  brush
            </span><span style="color:#2b91af;">Storyboard</span>.SetTarget(posAnim, brush);
            <span style="color:#2b91af;">Storyboard</span>.SetTarget(negAnim, brush);

            <span style="color:green;">// Target the property of the  brush to animate
            </span><span style="color:#2b91af;">Storyboard</span>.SetTargetProperty(posAnim, <span style="color:blue;">new </span><span style="color:#2b91af;">PropertyPath</span>(<span style="color:#2b91af;">SolidColorBrush</span>.ColorProperty));
            <span style="color:#2b91af;">Storyboard</span>.SetTargetProperty(negAnim, <span style="color:blue;">new </span><span style="color:#2b91af;">PropertyPath</span>(<span style="color:#2b91af;">SolidColorBrush</span>.ColorProperty));
        }

        <span style="color:blue;">private void </span>BeginHighlight(<span style="color:#2b91af;">Storyboard </span>storyBoard)
        {
            storyBoard.Begin();
        }
<span style="color:blue;">#else
        </span><span style="color:gray;">private void BeginHighlight(SolidColorBrush brush, Color startColor)
        {
            ColorAnimationUsingKeyFrames anim = new ColorAnimationUsingKeyFrames();
            anim.KeyFrames.Add(new LinearColorKeyFrame() { KeyTime = TimeSpan.FromSeconds(0.0), Value = startColor });
            anim.KeyFrames.Add(new LinearColorKeyFrame() { KeyTime = DefaultDuration.TimeSpan, Value = DefaultColor });
            anim.Duration = DefaultDuration;

            brush.BeginAnimation(SolidColorBrush.ColorProperty, anim);
        }
</span><span style="color:blue;">#endif
        public override double </span>Ask
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return base</span>.Ask;
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">if </span>((<span style="color:blue;">base</span>.Ask.Equals(<span style="color:blue;">value</span>) != <span style="color:blue;">true</span>))
                {
<span style="color:blue;">#if </span>SILVERLIGHT
                    BeginHighlight((<span style="color:blue;">value </span>&gt; <span style="color:blue;">this</span>.Ask) ? askPosStory : askNegStory);
<span style="color:blue;">#else
                    </span><span style="color:gray;">BeginHighlight(AskHighlight, (value &gt; this.Ask) ? Colors.Green : Colors.Red);
</span><span style="color:blue;">#endif

                    base</span>.Ask = <span style="color:blue;">value</span>;

                    <span style="color:blue;">this</span>.RaisePropertyChanged(<span style="color:#a31515;">&quot;Ask&quot;</span>);
                }
            }
        }

        <span style="color:blue;">public override double </span>Bid
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return base</span>.Bid;
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">if </span>((<span style="color:blue;">base</span>.Bid.Equals(<span style="color:blue;">value</span>) != <span style="color:blue;">true</span>))
                {
<span style="color:blue;">#if </span>SILVERLIGHT
                    BeginHighlight((<span style="color:blue;">value </span>&gt; <span style="color:blue;">this</span>.Bid) ? bidPosStory : bidNegStory);
<span style="color:blue;">#else
                    </span><span style="color:gray;">BeginHighlight(BidHighlight, (value &gt; this.Bid) ? Colors.Green : Colors.Red);
</span><span style="color:blue;">#endif

                    base</span>.Bid = <span style="color:blue;">value</span>;

                    <span style="color:blue;">this</span>.RaisePropertyChanged(<span style="color:#a31515;">&quot;Bid&quot;</span>);
                }
            }
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>The targets of the animation are the two public SolidColorBrush properties, AskHighlight and BidHighlight.&#160; The Color dependency property of these brushes is animated using color key frame animation from green for a positive change or red for a negative change.&#160; The animation for both WPF and Silverlight begins with a call to the BeginHighlight method when the corresponding Ask or Bid price property changes.&#160; The SILVERLIGHT debug symbol makes it clear to see the extra Storyboard objects and extra initialization required in the InitializeAnimation method to achieve the desired effect in Silverlight 2.&#160; You can see the references to these AskHighlight and BidHighlight properties in the WPF XAML below, also notice the xmlns:data for the DataGrid from the WPF Toolkit:</p>
<pre class="code"><span style="color:blue;">&lt;</span><span style="color:#a31515;">Window </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Class</span><span style="color:blue;">=&quot;WpfStockClient.StockWindow&quot;
    </span><span style="color:red;">xmlns</span><span style="color:blue;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    </span><span style="color:red;">xmlns</span><span style="color:blue;">:</span><span style="color:red;">x</span><span style="color:blue;">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    </span><span style="color:red;">xmlns</span><span style="color:blue;">:</span><span style="color:red;">data</span><span style="color:blue;">=&quot;http://schemas.microsoft.com/wpf/2008/toolkit&quot;
    </span><span style="color:red;">Title</span><span style="color:blue;">=&quot;Stock Window&quot; </span><span style="color:red;">Width</span><span style="color:blue;">=&quot;640&quot; </span><span style="color:red;">Height</span><span style="color:blue;">=&quot;520&quot;&gt;

    &lt;</span><span style="color:#a31515;">Grid </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;LayoutRoot&quot; </span><span style="color:red;">Background</span><span style="color:blue;">=&quot;White&quot;  </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;5,5,5,5&quot;&gt;
        &lt;</span><span style="color:#a31515;">Grid.RowDefinitions</span><span style="color:blue;">&gt;
            &lt;</span><span style="color:#a31515;">RowDefinition </span><span style="color:red;">MaxHeight</span><span style="color:blue;">=&quot;30&quot; /&gt;
            &lt;</span><span style="color:#a31515;">RowDefinition </span><span style="color:red;">Height</span><span style="color:blue;">=&quot;*&quot; /&gt;
        &lt;/</span><span style="color:#a31515;">Grid.RowDefinitions</span><span style="color:blue;">&gt;

        &lt;</span><span style="color:#a31515;">Grid.ColumnDefinitions</span><span style="color:blue;">&gt;
            &lt;</span><span style="color:#a31515;">ColumnDefinition </span><span style="color:red;">Width</span><span style="color:blue;">=&quot;.80*&quot; /&gt;
            &lt;</span><span style="color:#a31515;">ColumnDefinition </span><span style="color:red;">Width</span><span style="color:blue;">=&quot;.20*&quot; /&gt;
        &lt;/</span><span style="color:#a31515;">Grid.ColumnDefinitions</span><span style="color:blue;">&gt;

        &lt;</span><span style="color:#a31515;">TextBox </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;Notes&quot; </span><span style="color:red;">Grid.Row</span><span style="color:blue;">=&quot;0&quot; </span><span style="color:red;">Grid.Column</span><span style="color:blue;">=&quot;0&quot; </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;0,0,5,0&quot; /&gt;
        &lt;</span><span style="color:#a31515;">Button </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;AddNotes&quot; </span><span style="color:red;">Click</span><span style="color:blue;">=&quot;AddNotes_Click&quot; </span><span style="color:red;">Content</span><span style="color:blue;">=&quot;Add Notes&quot; </span><span style="color:red;">Grid.Row</span><span style="color:blue;">=&quot;0&quot; </span><span style="color:red;">Grid.Column</span><span style="color:blue;">=&quot;1&quot; </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;5,0,0,0&quot; /&gt;

        &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGrid </span><span style="color:red;">x</span><span style="color:blue;">:</span><span style="color:red;">Name</span><span style="color:blue;">=&quot;StocksGrid&quot;
                       </span><span style="color:red;">AutoGenerateColumns</span><span style="color:blue;">=&quot;False&quot;
                       </span><span style="color:red;">Grid.Row</span><span style="color:blue;">=&quot;1&quot;
                       </span><span style="color:red;">Grid.ColumnSpan</span><span style="color:blue;">=&quot;2&quot;
                       </span><span style="color:red;">GridLinesVisibility</span><span style="color:blue;">=&quot;Horizontal&quot;
                       </span><span style="color:red;">HeadersVisibility</span><span style="color:blue;">=&quot;Column&quot;
                       </span><span style="color:red;">RowBackground</span><span style="color:blue;">=&quot;AliceBlue&quot;
                       </span><span style="color:red;">CanUserResizeColumns</span><span style="color:blue;">=&quot;False&quot;
                       </span><span style="color:red;">SelectionChanged</span><span style="color:blue;">=&quot;StocksGrid_SelectionChanged&quot;
                       </span><span style="color:red;">SelectionMode</span><span style="color:blue;">=&quot;Single&quot;
                       </span><span style="color:red;">Margin</span><span style="color:blue;">=&quot;0,5,0,0&quot;&gt;
            &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGrid.Columns</span><span style="color:blue;">&gt;
                &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn </span><span style="color:red;">Header</span><span style="color:blue;">=&quot;Symbol&quot;&gt;
                    &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn.CellTemplate</span><span style="color:blue;">&gt;
                        &lt;</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
                            &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">=&quot;{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Symbol</span><span style="color:blue;">}&quot; /&gt;
                        &lt;/</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
                    &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn.CellTemplate</span><span style="color:blue;">&gt;
                &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn</span><span style="color:blue;">&gt;
                &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn </span><span style="color:red;">Header</span><span style="color:blue;">=&quot;Bid&quot;&gt;
                    &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn.CellTemplate</span><span style="color:blue;">&gt;
                        &lt;</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
                            &lt;</span><span style="color:#a31515;">StackPanel </span><span style="color:red;">Background</span><span style="color:blue;">=&quot;{</span><span style="color:#a31515;">Binding </span><span style="color:red;">BidHighlight</span><span style="color:blue;">}&quot;&gt;
                                &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">=&quot;{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Bid</span><span style="color:blue;">}&quot; /&gt;
                            &lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;
                        &lt;/</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
                    &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn.CellTemplate</span><span style="color:blue;">&gt;
                &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn</span><span style="color:blue;">&gt;
                &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn </span><span style="color:red;">Header</span><span style="color:blue;">=&quot;Ask&quot;&gt;
                    &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn.CellTemplate</span><span style="color:blue;">&gt;
                        &lt;</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
                            &lt;</span><span style="color:#a31515;">StackPanel </span><span style="color:red;">Background</span><span style="color:blue;">=&quot;{</span><span style="color:#a31515;">Binding </span><span style="color:red;">AskHighlight</span><span style="color:blue;">}&quot;&gt;
                                &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">=&quot;{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Ask</span><span style="color:blue;">}&quot; /&gt;
                            &lt;/</span><span style="color:#a31515;">StackPanel</span><span style="color:blue;">&gt;
                        &lt;/</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
                    &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn.CellTemplate</span><span style="color:blue;">&gt;
                &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn</span><span style="color:blue;">&gt;
                &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn </span><span style="color:red;">MinWidth</span><span style="color:blue;">=&quot;150&quot; </span><span style="color:red;">Header</span><span style="color:blue;">=&quot;Notes&quot;&gt;
                    &lt;</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn.CellTemplate</span><span style="color:blue;">&gt;
                        &lt;</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
                            &lt;</span><span style="color:#a31515;">TextBlock </span><span style="color:red;">Text</span><span style="color:blue;">=&quot;{</span><span style="color:#a31515;">Binding </span><span style="color:red;">Notes</span><span style="color:blue;">}&quot; /&gt;
                        &lt;/</span><span style="color:#a31515;">DataTemplate</span><span style="color:blue;">&gt;
                    &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn.CellTemplate</span><span style="color:blue;">&gt;
                &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGridTemplateColumn</span><span style="color:blue;">&gt;
            &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGrid.Columns</span><span style="color:blue;">&gt;
        &lt;/</span><span style="color:#a31515;">data</span><span style="color:blue;">:</span><span style="color:#a31515;">DataGrid</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">Grid</span><span style="color:blue;">&gt;
&lt;/</span><span style="color:#a31515;">Window</span><span style="color:blue;">&gt;</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>For more detail and to see the application running the entire solution can be downloaded using the link at the start of this post.</p>
<br />Posted in PollingDuplex, Silverlight, WCF, WPF Tagged: Animation, ColorAnimationUsingKeyFrames, DataContractSerializer, DuplexReceiver, Polling Duplex, Silverlight, Storyboard, WCF, WPF <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/179/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/179/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/179/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/179/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/179/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/179/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/179/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/179/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=179&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2008/11/19/silverlight-polling-duplex-part-4-wpf-client/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/11/serverandallclientsrunning-thumb.png" medium="image">
			<media:title type="html">Server and All Clients Running</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/11/pollingduplexnotsupportedexception.png" medium="image">
			<media:title type="html">Polling Duplex NotSupportedException</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/11/messageversioninvalidoperationexception.png" medium="image">
			<media:title type="html">MessageVersion InvalidOperationException</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/11/commonfileslinked.png" medium="image">
			<media:title type="html">Common Files Linked</media:title>
		</media:content>
	</item>
		<item>
		<title>Configuring Silverlight 2 Polling Duplex Endpoints in .config file only</title>
		<link>http://petermcg.wordpress.com/2008/10/23/configuring-silverlight-2-polling-duplex-config/</link>
		<comments>http://petermcg.wordpress.com/2008/10/23/configuring-silverlight-2-polling-duplex-config/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 11:55:36 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[PollingDuplex]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[App.config]]></category>
		<category><![CDATA[Silverlight 2]]></category>
		<category><![CDATA[System.ServiceModel.PollingDuplex]]></category>
		<category><![CDATA[Web.config]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2008/10/23/configuring-silverlight-2-polling-duplex-config/</guid>
		<description><![CDATA[(Sample Application Code) &#124; (PollingDuplexConfig.cs only) I got an interesting question recently asking if it was possible to specify a Silverlight 2 Polling Duplex endpoint entirely within an application’s configuration file instead of defining the endpoint in code as show below in the excerpt taken from my Polling Duplex Stock List demo: using System; using [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=172&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>(<a target="_blank" href="http://cid-920505bfc4faba01.skydrive.live.com/embedrowdetail.aspx/Public/PollingDuplexConfigDemoRTW.zip">Sample Application Code</a>) | (<a target="_blank" href="http://cid-920505bfc4faba01.skydrive.live.com/embedrowdetail.aspx/Public/PollingDuplexConfig.cs">PollingDuplexConfig.cs only</a>)</p>
<p>I got an <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server/#comment-226">interesting question</a> recently asking if it was possible to specify a <a target="_blank" href="http://www.silverlight.net/GetStarted/">Silverlight 2</a> <a target="_blank" href="http://blogs.msdn.com/silverlightws/archive/2008/10/20/new-web-services-features-in-sl2-rtw.aspx">Polling Duplex</a> endpoint entirely within an application’s configuration file instead of defining the endpoint in code as show below in the excerpt taken from my <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture/">Polling Duplex Stock List demo</a>:</p>
<pre class="code"><span style="color:blue;">using </span>System;
<span style="color:blue;">using </span>System.ServiceModel;
<span style="color:blue;">using </span>System.ServiceModel.Description;

<span style="color:blue;">namespace </span>StockServer
{
    <span style="color:blue;">public class </span><span style="color:#2b91af;">StockServiceHost </span>: <span style="color:#2b91af;">ServiceHost
    </span>{
        <span style="color:blue;">public </span>StockServiceHost(<span style="color:blue;">object </span>singletonInstance, <span style="color:blue;">params </span><span style="color:#2b91af;">Uri</span>[] baseAddresses)
            : <span style="color:blue;">base</span>(singletonInstance, baseAddresses)
        {
        }

        <span style="color:blue;">public </span>StockServiceHost(<span style="color:#2b91af;">Type </span>serviceType, <span style="color:blue;">params </span><span style="color:#2b91af;">Uri</span>[] baseAddresses)
            : <span style="color:blue;">base</span>(serviceType, baseAddresses)
        {
        }

        <span style="color:blue;">protected override void </span>InitializeRuntime()
        {
            <span style="color:green;">// Policy Requirements Endpoint
            </span><span style="color:blue;">this</span>.AddServiceEndpoint(
                <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">IPolicyProvider</span>),
                <span style="color:blue;">new </span><span style="color:#2b91af;">WebHttpBinding</span>(),
                <span style="color:blue;">new </span><span style="color:#2b91af;">Uri</span>(<span style="color:#a31515;">&quot;http://localhost:10201/&quot;</span>)).Behaviors.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">WebHttpBehavior</span>());

            <span style="color:green;">// Polling Duplex Endpoint
            </span><span style="color:blue;">this</span>.AddServiceEndpoint(
                <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">IStockService</span>),
                <span style="color:blue;">new </span><span style="color:#2b91af;">PollingDuplexHttpBinding</span>(),
                <span style="color:blue;">new </span><span style="color:#2b91af;">Uri</span>(<span style="color:#a31515;">&quot;http://localhost:10201/StockService&quot;</span>));

            <span style="color:blue;">base</span>.InitializeRuntime();
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Surprisingly this is not supported by default in the <a target="_blank" href="http://www.hanselman.com/blog/Silverlight2IsOut.aspx">release version of Silverlight 2</a> due to the absence of the required configuration-related classes needed to expose the Polling Duplex binding and binding element to the WCF configuration system.&#160; However, thanks to the great extensibility model of WCF it is possible to enable this scenario and bridge the gap by registering a custom binding extension.</p>
<p>The aim is to render the StockServiceHost class (defined in code above) redundant and instead replace it’s functionality entirely in a configuration file, in this case App.config.&#160; As you can see in the InitializeRuntime method the StockServiceHost class actually registers two endpoints: in addition to the PollingDuplexHttpBinding endpoint there is the WebHttpBinding endpoint to account for the <a target="_blank" href="http://silverlight.net/learn/learnvideo.aspx?video=47174">Silverlight 2 cross-domain policy requirements</a>.&#160; It would defeat the aim to succeed in defining one of these endpoints in the configuration file without the other, so the measure of success is to be able to define both in App.config.&#160; How this aim can be achieved is shown below:</p>
<pre class="code"><span style="color:blue;">&lt;?</span><span style="color:#a31515;">xml </span><span style="color:red;">version</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">1.0</span>&quot; <span style="color:red;">encoding</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">utf-8</span>&quot; <span style="color:blue;">?&gt;
&lt;</span><span style="color:#a31515;">configuration</span><span style="color:blue;">&gt;
  &lt;</span><span style="color:#a31515;">system.serviceModel</span><span style="color:blue;">&gt;
    &lt;</span><span style="color:#a31515;">diagnostics </span><span style="color:red;">performanceCounters</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">All</span>&quot; <span style="color:blue;">/&gt;

    &lt;</span><span style="color:#a31515;">behaviors</span><span style="color:blue;">&gt;
      &lt;</span><span style="color:#a31515;">endpointBehaviors</span><span style="color:blue;">&gt;
        &lt;</span><span style="color:#a31515;">behavior </span><span style="color:red;">name</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">webHttpBehavior</span>&quot;<span style="color:blue;">&gt;
          &lt;</span><span style="color:#a31515;">webHttp </span><span style="color:blue;">/&gt;
        &lt;/</span><span style="color:#a31515;">behavior</span><span style="color:blue;">&gt;
      &lt;/</span><span style="color:#a31515;">endpointBehaviors</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">behaviors</span><span style="color:blue;">&gt;

    &lt;</span><span style="color:#a31515;">bindings</span><span style="color:blue;">&gt;
      &lt;</span><span style="color:#a31515;">pollingDuplexHttpBinding</span><span style="color:blue;">&gt;
        &lt;</span><span style="color:#a31515;">binding </span><span style="color:red;">name</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">pollingDuplexHttpBindingConfiguration</span>&quot;
                 <span style="color:red;">inactivityTimeout</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">00:09:59</span>&quot;
                 <span style="color:red;">serverPollTimeout</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">00:14:59</span>&quot; <span style="color:blue;">/&gt;
      &lt;/</span><span style="color:#a31515;">pollingDuplexHttpBinding</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">bindings</span><span style="color:blue;">&gt;

    &lt;</span><span style="color:#a31515;">extensions</span><span style="color:blue;">&gt;
      &lt;</span><span style="color:#a31515;">bindingExtensions</span><span style="color:blue;">&gt;
        &lt;</span><span style="color:#a31515;">add </span><span style="color:red;">name</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">pollingDuplexHttpBinding</span>&quot;
             <span style="color:red;">type</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">StockServer.PollingDuplexHttpBindingCollectionElement, StockServer</span>&quot; <span style="color:blue;">/&gt;
      &lt;/</span><span style="color:#a31515;">bindingExtensions</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">extensions</span><span style="color:blue;">&gt;

    &lt;</span><span style="color:#a31515;">services</span><span style="color:blue;">&gt;
      &lt;</span><span style="color:#a31515;">service </span><span style="color:red;">name</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">StockServer.StockService</span>&quot;<span style="color:blue;">&gt;

        &lt;!-- </span><span style="color:green;">Policy Requirements Endpoint </span><span style="color:blue;">--&gt;
        &lt;</span><span style="color:#a31515;">endpoint </span><span style="color:red;">address</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">http://localhost:10201/</span>&quot;
                  <span style="color:red;">binding</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">webHttpBinding</span>&quot;
                  <span style="color:red;">behaviorConfiguration</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">webHttpBehavior</span>&quot;
                  <span style="color:red;">contract</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">StockServer.IPolicyProvider</span>&quot; <span style="color:blue;">/&gt;

        &lt;!-- </span><span style="color:green;">Polling Duplex Endpoint </span><span style="color:blue;">--&gt;
        &lt;</span><span style="color:#a31515;">endpoint </span><span style="color:red;">address</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">http://localhost:10201/StockService</span>&quot;
                  <span style="color:red;">binding</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">pollingDuplexHttpBinding</span>&quot;
                  <span style="color:red;">bindingConfiguration</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">pollingDuplexHttpBindingConfiguration</span>&quot;
                  <span style="color:red;">contract</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">StockServer.IStockService</span>&quot; <span style="color:blue;">/&gt;

      &lt;/</span><span style="color:#a31515;">service</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">services</span><span style="color:blue;">&gt;
  &lt;/</span><span style="color:#a31515;">system.serviceModel</span><span style="color:blue;">&gt;
&lt;/</span><span style="color:#a31515;">configuration</span><span style="color:blue;">&gt;
</span></pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>Notice under the &lt;bindingExtensions&gt; element that the pollingDuplexHttpBinding item relies on the following two configuration-related classes (demonstrated in use as part of the sample application or available separately for download above) in the PollingDuplexConfig.cs file:</p>
<pre class="code"><span style="color:blue;">using </span>System;
<span style="color:blue;">using </span>System.Configuration;
<span style="color:blue;">using </span>System.Globalization;
<span style="color:blue;">using </span>System.ServiceModel;
<span style="color:blue;">using </span>System.ServiceModel.Channels;
<span style="color:blue;">using </span>System.ServiceModel.Configuration;

<span style="color:blue;">namespace </span>StockServer
{
    <span style="color:blue;">public class </span><span style="color:#2b91af;">PollingDuplexHttpBindingCollectionElement </span>:
        <span style="color:#2b91af;">StandardBindingCollectionElement</span>&lt;<span style="color:#2b91af;">PollingDuplexHttpBinding</span>, <span style="color:#2b91af;">PollingDuplexHttpBindingElement</span>&gt;
    {
    }

    <span style="color:blue;">public class </span><span style="color:#2b91af;">PollingDuplexHttpBindingElement </span>: <span style="color:#2b91af;">StandardBindingElement
    </span>{
        <span style="color:blue;">private const string </span>InactivityTimeoutPropertyName = <span style="color:#a31515;">&quot;inactivityTimeout&quot;</span>;
        <span style="color:blue;">private const string </span>DefaultInactivityTimeout = <span style="color:#a31515;">&quot;00:10:00&quot;</span>;

        <span style="color:blue;">private const string </span>ServerPollTimeoutPropertyName = <span style="color:#a31515;">&quot;serverPollTimeout&quot;</span>;
        <span style="color:blue;">private const string </span>DefaultServerPollTimeout = <span style="color:#a31515;">&quot;00:15:00&quot;</span>;

        <span style="color:blue;">public </span>PollingDuplexHttpBindingElement(<span style="color:blue;">string </span>configurationName) :
            <span style="color:blue;">base</span>(configurationName)
        {
        }

        <span style="color:blue;">public </span>PollingDuplexHttpBindingElement() :
            <span style="color:blue;">this</span>(<span style="color:blue;">null</span>)
        {
        }

        <span style="color:blue;">protected override </span><span style="color:#2b91af;">Type </span>BindingElementType
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return typeof</span>(<span style="color:#2b91af;">PollingDuplexHttpBinding</span>);
            }
        }

        [<span style="color:#2b91af;">ConfigurationProperty</span>(InactivityTimeoutPropertyName, DefaultValue = DefaultInactivityTimeout)]
        <span style="color:blue;">public </span><span style="color:#2b91af;">TimeSpan </span>InactivityTimeout
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return </span>((<span style="color:#2b91af;">TimeSpan</span>)(<span style="color:blue;">base</span>[InactivityTimeoutPropertyName]));
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">base</span>[InactivityTimeoutPropertyName] = <span style="color:blue;">value</span>;
            }
        }

        [<span style="color:#2b91af;">ConfigurationProperty</span>(ServerPollTimeoutPropertyName, DefaultValue = DefaultServerPollTimeout)]
        <span style="color:blue;">public </span><span style="color:#2b91af;">TimeSpan </span>ServerPollTimeout
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return </span>((<span style="color:#2b91af;">TimeSpan</span>)(<span style="color:blue;">base</span>[ServerPollTimeoutPropertyName]));
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">base</span>[ServerPollTimeoutPropertyName] = <span style="color:blue;">value</span>;
            }
        }

        <span style="color:blue;">protected override </span><span style="color:#2b91af;">ConfigurationPropertyCollection </span>Properties
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:#2b91af;">ConfigurationPropertyCollection </span>properties = <span style="color:blue;">base</span>.Properties;
                properties.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">ConfigurationProperty</span>(InactivityTimeoutPropertyName,
                                                         <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">TimeSpan</span>), DefaultInactivityTimeout));
                properties.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">ConfigurationProperty</span>(ServerPollTimeoutPropertyName,
                                                         <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">TimeSpan</span>), DefaultServerPollTimeout));
                <span style="color:blue;">return </span>properties;
            }
        }

        <span style="color:blue;">protected override void </span>InitializeFrom(<span style="color:#2b91af;">Binding </span>binding)
        {
            <span style="color:blue;">base</span>.InitializeFrom(binding);

            <span style="color:#2b91af;">PollingDuplexHttpBinding </span>pollingDuplexHttpBinding = ((<span style="color:#2b91af;">PollingDuplexHttpBinding</span>)(binding));
            <span style="color:blue;">this</span>.InactivityTimeout = pollingDuplexHttpBinding.InactivityTimeout;
            <span style="color:blue;">this</span>.ServerPollTimeout = pollingDuplexHttpBinding.ServerPollTimeout;
        }

        <span style="color:blue;">protected override void </span>OnApplyConfiguration(<span style="color:#2b91af;">Binding </span>binding)
        {
            <span style="color:blue;">if </span>((binding == <span style="color:blue;">null</span>))
            {
                <span style="color:blue;">throw new </span><span style="color:#2b91af;">ArgumentNullException</span>(<span style="color:#a31515;">&quot;binding&quot;</span>);
            }
            <span style="color:blue;">if </span>((binding.GetType() != <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">PollingDuplexHttpBinding</span>)))
            {
                <span style="color:blue;">throw new </span><span style="color:#2b91af;">ArgumentException</span>(<span style="color:blue;">string</span>.Format(<span style="color:#2b91af;">CultureInfo</span>.CurrentCulture,
                                                          <span style="color:#a31515;">&quot;Invalid type for binding. Expected type: {0}. Type passed in: {1}.&quot;</span>,
                                                          <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">PollingDuplexHttpBinding</span>).AssemblyQualifiedName,
                                                          binding.GetType().AssemblyQualifiedName));
            }

            <span style="color:#2b91af;">PollingDuplexHttpBinding </span>pollingDuplexHttpBinding = ((<span style="color:#2b91af;">PollingDuplexHttpBinding</span>)(binding));
            pollingDuplexHttpBinding.InactivityTimeout = <span style="color:blue;">this</span>.InactivityTimeout;
            pollingDuplexHttpBinding.ServerPollTimeout = <span style="color:blue;">this</span>.ServerPollTimeout;
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>To configure Polling Duplex in Silverlight 2 solely via the .config file the PollingDuplexHttpBindingCollectionElement class including the relevant namespace and assembly, need to be referenced in the type attribute of the pollingDuplexHttpBinding item under the &lt;bindingExtensions&gt; element as shown in the configuration markup above.</p>
<p>As this is a standard way to create and register a custom binding extension, once the configuration classes and markup are in place as shown and the project successfully builds, you can edit the binding in the same way as the built-in WCF bindings by opening the produced .config file (StockServer.exe.config in this case) in <a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms732009.aspx">SvcConfigEditor.exe</a> while the service is running:</p>
<p><a target="_blank" href="http://petermcg.files.wordpress.com/2008/10/bindingextension.png"><img style="display:inline;border-width:0;" title="Binding Extension" border="0" alt="Binding Extension" src="http://petermcg.files.wordpress.com/2008/10/bindingextension-thumb.png?w=240&#038;h=181" width="240" height="181" /></a> <a target="_blank" href="http://petermcg.files.wordpress.com/2008/10/bindingproperties.png"><img style="display:inline;border-width:0;" title="Binding Properties" border="0" alt="Binding Properties" src="http://petermcg.files.wordpress.com/2008/10/bindingproperties-thumb.png?w=240&#038;h=181" width="240" height="181" /></a> </p>
<p>For more detail on configuring WCF bindings in general I recommend reading <a target="_blank" href="http://msdn.microsoft.com/en-gb/magazine/cc163394.aspx">WCF Bindings In Depth</a> by <a target="_blank" href="http://www.pluralsight.com/community/blogs/aaron/default.aspx">Aaron Skonnard</a></p>
<br />Posted in PollingDuplex, Silverlight, WCF Tagged: App.config, Silverlight 2, System.ServiceModel.PollingDuplex, Web.config <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/172/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/172/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=172&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2008/10/23/configuring-silverlight-2-polling-duplex-config/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/10/bindingextension-thumb.png" medium="image">
			<media:title type="html">Binding Extension</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/10/bindingproperties-thumb.png" medium="image">
			<media:title type="html">Binding Properties</media:title>
		</media:content>
	</item>
		<item>
		<title>Silverlight 2 Samples Updated</title>
		<link>http://petermcg.wordpress.com/2008/10/21/silverlight-2-samples-updated-to-rtw/</link>
		<comments>http://petermcg.wordpress.com/2008/10/21/silverlight-2-samples-updated-to-rtw/#comments</comments>
		<pubDate>Tue, 21 Oct 2008 06:53:55 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Samples]]></category>
		<category><![CDATA[Silverlight 2]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2008/10/21/silverlight-2-samples-updated-to-rtw/</guid>
		<description><![CDATA[The samples and links to demos on this blog have been updated to be compatible with the release of Silverlight 2.&#160; These projects are typically the result of my curiosity or a desire to unearth benefit from a newly available feature in Silverlight 2.&#160; If they are useful for others so much the better, if [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=165&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The samples and links to demos on this blog have been updated to be compatible with <a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2008/10/14/silverlight-2-released.aspx">the release of Silverlight 2</a>.&#160; These projects are typically the result of my curiosity or a desire to unearth benefit from a newly available feature in Silverlight 2.&#160; If they are useful for others so much the better, if not there are certainly lots of other <a target="_blank" href="http://timheuer.com/blog/archive/2008/10/20/silverlight-community-resources-updated.aspx">Silverlight 2 samples</a> available elsewhere.</p>
<p>It has always been my intention to make these demos available without any restriction with <a target="_blank" href="http://timheuer.com/blog/archive/2008/10/14/silverlight-2-released-officially.aspx">the release of Silverlight 2</a>, feel free to make use of them however it may benefit you:</p>
<p><a target="_blank" href="http://petermcg.wordpress.com/2008/08/10/silverlight-20-pie-doughnut-chart/">Silverlight 2 Pie/Doughnut Chart Demo</a></p>
<p><a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture/">Silverlight 2 Polling Duplex Demo &#8211; Part 1 : Architecture</a></p>
<p><a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server/">Silverlight 2 Polling Duplex Demo &#8211; Part 2 : The Server</a></p>
<p><a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-3-the-client/">Silverlight 2 Polling Duplex Demo &#8211; Part 3 : The Client</a></p>
<p><a target="_blank" href="http://petermcg.wordpress.com/2008/07/16/silverlight-initialization-via-the-silverlight-server-control/">Silverlight 2 Initialization Parameters Demo</a></p>
<p><a target="_blank" href="http://petermcg.wordpress.com/2008/04/17/stock-list-demo-part-1/">Silverlight 2 Stock List Demo &#8211; Part 1 : XML file to DataGrid via LINQ to XML</a></p>
<p><a target="_blank" href="http://petermcg.wordpress.com/2008/04/24/stock-list-demo-part-2/">Silverlight 2 Stock List Demo &#8211; Part 2 : XML file to DataGrid via WCF</a></p>
<p><a target="_blank" href="http://petermcg.wordpress.com/2008/06/05/stock-list-demo-part-3/">Silverlight 2 Stock List Demo &#8211; Part 3 : Making the Grid Tick with Server Deltas via Sockets</a></p>
<p>The upgrade process was largely painless for me, the main change that sticks in my mind is accounting for the change in case of the GridLinesVisibility property on the DataGrid.&#160; The pie chart live-demos have been updated but are hosted on <a target="_blank" href="http://streaming.live.com/">Silverlight Streaming</a> which does <a target="_blank" href="http://silverlight.net/forums/t/39865.aspx">not yet fully support the released version</a> of Silverlight 2, I expect this to change in the near future.</p>
<p>Changes of interest with regard to the Polling Duplex sample include that the server System.ServiceModel.PollingDuplex.dll assembly installed as part of the Silverlight 2 SDK is no longer contained in a folder titled ‘Evaluation’ but instead in the same folder as System.Web.Silverlight.dll.&#160; This corresponds with the <a target="_blank" href="http://msdn.microsoft.com/en-us/silverlight/dd162430.aspx">summary note here</a> that <a target="_blank" href="http://blogs.msdn.com/silverlightws/archive/2008/10/20/new-web-services-features-in-sl2-rtw.aspx">this technology is no longer in evaluation</a> and can now be used and deployed as part of Silverlight 2 production applications.&#160; Finally, the previously mentioned <a target="_blank" href="http://blogs.msdn.com/silverlightws/archive/2008/10/20/new-web-services-features-in-sl2-rtw.aspx">DuplexReceiver functionality is now manifest as described here</a> and <a target="_blank" href="http://code.msdn.microsoft.com/silverlightws/Release/ProjectReleases.aspx">demonstrated here</a> as part of the Silverlight 2 RTW Web Services samples.</p>
<br />Posted in Silverlight Tagged: Samples, Silverlight 2 <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/165/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=165&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2008/10/21/silverlight-2-samples-updated-to-rtw/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>
	</item>
		<item>
		<title>Silverlight 2 RC0 Polling Duplex Evolution</title>
		<link>http://petermcg.wordpress.com/2008/09/30/silverlight-2-rc0-polling-duplex-evolution/</link>
		<comments>http://petermcg.wordpress.com/2008/09/30/silverlight-2-rc0-polling-duplex-evolution/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 13:47:55 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[PollingDuplex]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[Polling Duplex]]></category>
		<category><![CDATA[Samples]]></category>
		<category><![CDATA[Silverlight RC0]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2008/09/30/silverlight-2-rc0-polling-duplex-evolution/</guid>
		<description><![CDATA[The release of Silverlight RC0 presents some minor breaking changes for applications using the polling duplex support provided in Beta 2. The summary of these changes taken from the full Breaking Changes Since Beta 2 document is as follows: PollTimeout setting on the server side (PollingDuplexHttpBinding and PollingDuplexBindingElement) has been renamed to ServerPollTimeout PollTimeout setting [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=154&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://weblogs.asp.net/scottgu/archive/2008/09/25/silverlight-2-release-candidate-now-available.aspx" target="_blank">release of Silverlight RC0</a> presents some minor breaking changes for applications using the polling duplex support provided in Beta 2.</p>
<p>The summary of these changes taken from the full <a href="http://download.microsoft.com/download/6/f/e/6fe1f43d-9d0c-4346-ad08-602df9bcb3cf/BreakingChangesBetweenBeta2andRelease.doc" target="_blank">Breaking Changes Since Beta 2</a> document is as follows:</p>
<ul>
<li>
<p>PollTimeout setting on the server side (PollingDuplexHttpBinding and PollingDuplexBindingElement) has been renamed to ServerPollTimeout</p>
<li>
<p>PollTimeout setting on the PollingDuplexBindingElement (client side) has been renamed to ClientPollTimeout.</p>
<li>
<p>PollTimeout setting on the PollingDuplexHttpBinding (client side) has been cut. In most scenarios, it should not be necessary to change this. If a change is necessary, it can be achieved through the ClientPollTimeout on the PollingDuplexBindingElement.</p>
<li>
<p>Client-side support has been cut from the non-Silverlight (server-side) polling duplex assembly (i.e. BuildChannelFactory will throw a NotSupportedException). That is, in RTM, the client side for polling duplex must be Silverlight (and the server side must be the regular .NET Framework, but this restriction was already in place in Beta2).</p>
<li>
<p>Default timeouts have been changed for the Duplex channel. For most common scenarios, the new out-of-the-box defaults should be appropriate and there is no need to change them.</p>
<li>
<p>An error (404) on a polling request will cause the duplex channel to fault.</p>
<li>
<p>Various invalid messages used to be ignored by the Duplex stack but will now be rejected.</p>
<li>
<p>If any HTTP error (404,500,&#8230;) is encountered during a SOAP call, a CommunicationException is now thrown instead of a ProtocolException.</p>
</li>
</ul>
<p>Earlier this month I put together a series of posts representing somewhat of a deep-dive into the WCF Polling Duplex support in Silverlight 2 Beta 2.&nbsp; The series is in three parts covering <a href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture/" target="_blank">Architecture</a>, <a href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server/" target="_blank">The Server</a> and <a href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-3-the-client/" target="_blank">The Client</a> and will still be largely relevant.&nbsp; The source code for a Beta 2 sample application discussed across parts two and three is available for download.</p>
<p>I will be on vacation over the next week-and-a-bit and won&#8217;t be able to respond to emails/queries immediately but I do fully intend to update the polling duplex sample application to account for these breaking changes when I return.&nbsp; Applications built with Beta 2 will not run on final runtime builds so I will also update the other samples available on this blog including the pie/doughnut chart and Sockets samples in the near future.</p>
<br />Posted in PollingDuplex, Silverlight, WCF Tagged: Polling Duplex, Samples, Silverlight RC0 <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=154&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2008/09/30/silverlight-2-rc0-polling-duplex-evolution/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>
	</item>
		<item>
		<title>Debugging Polling Duplex on localhost with ipv4.fiddler</title>
		<link>http://petermcg.wordpress.com/2008/09/30/debugging-polling-duplex-on-localhost-with-ipv4-fiddler/</link>
		<comments>http://petermcg.wordpress.com/2008/09/30/debugging-polling-duplex-on-localhost-with-ipv4-fiddler/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 13:44:30 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Fiddler]]></category>
		<category><![CDATA[PollingDuplex]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[ipv4.fiddler]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2008/09/30/debugging-polling-duplex-on-localhost-with-ipv4-fiddler/</guid>
		<description><![CDATA[This post takes a brief look at the options for capturing localhost HTTP traffic in the superb Fiddler2 tool but in particular demonstrates how this can be achieved using the less-renowned ipv4.fiddler keyword in a Silverlight 2 polling duplex debugging session. HTTP traffic sent to or originating from http://localhost or http://127.0.0.1 by Internet Explorer and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=153&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post takes a brief look at the options for capturing localhost HTTP traffic in the superb <a href="http://fiddler2.com/fiddler2/" target="_blank">Fiddler2 tool</a> but in particular demonstrates how this can be achieved using the less-renowned ipv4.fiddler keyword in a Silverlight 2 polling duplex debugging session.</p>
<p>HTTP traffic sent to or originating from http://localhost or http://127.0.0.1 by Internet Explorer and the .NET Framework is not captured in Fiddler2 by default because the requests and responses do not pass through the WinInet proxy that it registers.&nbsp; A few simple workarounds do exist to commonly facilitate the capture of this traffic (without customizing Fiddler&#8217;s rules) however:</p>
<ul>
<li>Using 127.0.0.1 with a dot suffix
<li>Using the Machine Name
<li>Using ipv4.fiddler</li>
</ul>
<p>The rest of this post shows the results of using each of these methods in an attempt to achieve a complete trace of all HTTP traffic being sent and received between my sample Silverlight 2 Beta 2 <a href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-3-the-client/" target="_blank">polling duplex client</a> and <a href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server/" target="_blank">server application</a>, the results were quite interesting.&nbsp; The sample application consists of three projects:</p>
<ul>
<li>The Silverlight 2 Beta 2 client polling duplex application
<li>The Web Application hosting the Silverlight client
<li>The WCF polling duplex service hosted in a Console Application</li>
</ul>
<p>The server manually handles the Silverlight client access policy requirements and messages are sent in both directions by both parties.&nbsp; Capturing all the traffic between the client and server in Fiddler2 requires the base http://localhost url to be manipulated at design time according to the appropriate workaround in each of the three projects.&nbsp; Let&#8217;s take a look at the process using each workaround in turn and the ensuing results:</p>
<h4>1. Using 127.0.0.1 with a dot suffix</h4>
<p>I first read about this technique <a href="http://wildermuth.com/2008/06/07/Debugging_ADO_NET_Data_Services_with_Fiddler2" target="_blank">here</a> and it does work in a number of more common scenarios, let&#8217;s see how it fares in this scenario:</p>
<h6>A. Silverlight Client</h6>
<p>Firstly the manipulation of the default http://localhost url used to connect to the server duplex service from the Silverlight 2 client project:</p>
<pre class="code"><span style="color:green;">// From this
</span><span style="color:#2b91af;">EndpointAddress </span>endPoint = <span style="color:blue;">new </span><span style="color:#2b91af;">EndpointAddress</span>(<span style="color:#a31515;">"http://localhost:10201/StockService"</span>);
<span style="color:green;">// To this - Note the period after localhost
</span><span style="color:#2b91af;">EndpointAddress </span>endPoint = <span style="color:blue;">new </span><span style="color:#2b91af;">EndpointAddress</span>(<span style="color:#a31515;">http://127.0.0.1.:10201/StockService</span>);</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<h6>B. Hosting Web Application</h6>
<p>Secondly the same change to the Start URL for the web application that hosts the Silverlight 2 client:</p>
<p><img style="border-width:0;" height="173" alt="Start Url localhost dot suffix" src="http://petermcg.files.wordpress.com/2008/09/start-url-localhost-dot-suffix.png?w=584&#038;h=173" width="584" border="0"> </p>
<h6>C. WCF Service Console Application</h6>
<p>Lastly a change to the base address of the WCF polling duplex service in the server&#8217;s configuration file:</p>
<p><img style="border-width:0;" height="48" alt="Base address localhost dot suffix" src="http://petermcg.files.wordpress.com/2008/09/base-address-localhost-dot-suffix.png?w=446&#038;h=48" width="446" border="0"></p>
<h6>D. Results in Fiddler</h6>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p><a href="http://petermcg.files.wordpress.com/2008/09/fiddler-localhost-dot-suffix.png" target="_blank"><img style="border-width:0;" height="480" alt="Fiddler localhost dot suffix" src="http://petermcg.files.wordpress.com/2008/09/fiddler-localhost-dot-suffix-thumb.png?w=607&#038;h=480" width="607" border="0"></a> </p>
<p>The screenshot above shows the results of our efforts using this workaround.&nbsp; The session gets as far as the GET request for the built-in clientaccesspolicy.xml file.&nbsp; Due to our manually added suffix a HTTP 400 Bad Request &#8211; Invalid Hostname response is returned.&nbsp; This HTTP response is eventually translated into the following exception in the Silverlight client:</p>
<p><img style="border-width:0;" height="230" alt="Exception localhost dot suffix" src="http://petermcg.files.wordpress.com/2008/09/exception-localhost-dot-suffix.png?w=387&#038;h=230" width="387" border="0"> </p>
<h4>2. Using the Machine Name</h4>
<p>This is a technique listed in the relevant help section on the <a href="http://fiddler2.com/Fiddler/help/hookup.asp#Q-LocalTraffic" target="_blank">Fiddler2 website</a>, lets see what results this workaround yields:</p>
<h6>A. Silverlight Client</h6>
<p>Again we start with the manipulation of the default http://localhost url used to connect to the server duplex service from the Silverlight 2 client project:</p>
<pre class="code"><span style="color:green;">// From this
</span><span style="color:#2b91af;">EndpointAddress </span>endPoint = <span style="color:blue;">new </span><span style="color:#2b91af;">EndpointAddress</span>(<span style="color:#a31515;">"http://localhost:10201/StockService"</span>);
<span style="color:green;">// To this (i.e. Environment.MachineName)
</span><span style="color:#2b91af;">EndpointAddress </span>endPoint = <span style="color:blue;">new </span><span style="color:#2b91af;">EndpointAddress</span>(<span style="color:#a31515;">http://vgnar21s:10201/StockService</span>);</pre>
</p>
<h6>B. Hosting Web Application</h6>
<p>Again, the same change to the Start URL for the web application that hosts the Silverlight 2 client:</p>
<p><img style="border-width:0;" height="173" alt="Start Url Machine Name" src="http://petermcg.files.wordpress.com/2008/09/start-url-machine-name.png?w=584&#038;h=173" width="584" border="0"> </p>
<h6>C. WCF Service Console Application</h6>
<p>Lastly a change to the base address of the WCF polling duplex service in the server&#8217;s configuration file:</p>
<p><img style="border-width:0;" height="49" alt="Base address Machine Name" src="http://petermcg.files.wordpress.com/2008/09/base-address-machine-name.png?w=436&#038;h=49" width="436" border="0"> </p>
<h6>D. Results in Fiddler</h6>
<p><a href="http://petermcg.files.wordpress.com/2008/09/fiddler-machine-name.png" target="_blank"><img style="border-width:0;" height="480" alt="Fiddler Machine Name" src="http://petermcg.files.wordpress.com/2008/09/fiddler-machine-name-thumb.png?w=607&#038;h=480" width="607" border="0"></a> </p>
<p>The screenshot above shows the results of our efforts using this workaround.&nbsp; The session does not get past the request for the aspx page that hosts the Silverlight application and a HTTP 502 Connection Failed response is returned.&nbsp; This HTTP response message eventually appears as the following error in Internet Explorer:</p>
<p><img style="border-width:0;" height="176" alt="IE Machine Name" src="http://petermcg.files.wordpress.com/2008/09/ie-machine-name.png?w=518&#038;h=176" width="518" border="0"> </p>
<h4>3. Use ipv4.fiddler keyword</h4>
<p>At this stage the two previous workarounds have both proven unsuccessful, let&#8217;s try the same process this time with another technique listed in the relevant help section on the <a href="http://fiddler2.com/Fiddler/help/hookup.asp#Q-LocalTraffic" target="_blank">Fiddler2 website</a> &#8211; use of the ipv4.fiddler keyword.&nbsp; The ipv4.fiddler keyword requires Fiddler v2.1.8 or later to be running, I should also mention the ipv6.fiddler keyword (not covered in this post) for <a href="http://en.wikipedia.org/wiki/IPv6" target="_blank">IPV6</a> debugging.</p>
<h6>A. Silverlight Client</h6>
<p>Firstly the manipulation of the default http://localhost url used to connect to the server duplex service in the Silverlight 2 client project:</p>
<pre class="code"><span style="color:green;">// From this
</span><span style="color:#2b91af;">EndpointAddress </span>endPoint = <span style="color:blue;">new </span><span style="color:#2b91af;">EndpointAddress</span>(<span style="color:#a31515;">"http://localhost:10201/StockService"</span>);
<span style="color:green;">// To this (Fiddler keyword)
</span><span style="color:#2b91af;">EndpointAddress </span>endPoint = <span style="color:blue;">new </span><span style="color:#2b91af;">EndpointAddress</span>(<span style="color:#a31515;">http://ipv4.fiddler:10201/StockService</span>);</pre>
</p>
<h6>B. Hosting Web Application</h6>
<p>Secondly the same change to the Start URL for the web application that hosts the Silverlight 2 client:</p>
<p><img style="border-width:0;" height="162" alt="Start Url ipv4" src="http://petermcg.files.wordpress.com/2008/09/start-url-ipv4.png?w=550&#038;h=162" width="550" border="0"> </p>
<h6>C. WCF Service Console Application</h6>
<p>Lastly a change to the base address of the WCF polling duplex service in the server&#8217;s configuration file:</p>
<p><img style="border-width:0;" height="50" alt="Base address ipv4" src="http://petermcg.files.wordpress.com/2008/09/base-address-ipv4.png?w=464&#038;h=50" width="464" border="0"> </p>
<h6>D. Results in Fiddler</h6>
<p><a href="http://petermcg.files.wordpress.com/2008/09/fiddler-ipv4.png" target="_blank"><img style="border-width:0;" height="480" alt="Fiddler ipv4" src="http://petermcg.files.wordpress.com/2008/09/fiddler-ipv4-thumb.png?w=607&#038;h=480" width="607" border="0"></a> </p>
<p>Success &#8211; this workaround accomplishes exactly what we set out to achieve, the screenshot above shows the capture of all HTTP traffic going between the client and server.&nbsp; It shows everything from the initial request for the hosting aspx page, downloading the .xap file, the request and custom self-hosted response for the clientaccesspolicy.xml file and finally the actual polling duplex activity on the wire.&nbsp; Note the content of the User-defined column, this is as a result of turning on &#8216;Show Time-to-Last-Byte&#8217; and &#8216;Show Response Timestamp&#8217; under the Rules &gt; Performance menu in Fiddler2.</p>
<p>For a deep-dive into exactly what these polling duplex requests and responses contain, please see the &#8216;Anatomy of a Bi-Directional Message Exchange&#8217; heading in <a href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture/" target="_blank">Part 1 &#8211; Architecture</a> of my series of posts on polling duplex in Silverlight 2.</p>
<br />Posted in Debugging, Fiddler, PollingDuplex, Silverlight Tagged: Fiddler, ipv4.fiddler, Silverlight <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/153/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=153&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2008/09/30/debugging-polling-duplex-on-localhost-with-ipv4-fiddler/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/start-url-localhost-dot-suffix.png" medium="image">
			<media:title type="html">Start Url localhost dot suffix</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/base-address-localhost-dot-suffix.png" medium="image">
			<media:title type="html">Base address localhost dot suffix</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/fiddler-localhost-dot-suffix-thumb.png" medium="image">
			<media:title type="html">Fiddler localhost dot suffix</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/exception-localhost-dot-suffix.png" medium="image">
			<media:title type="html">Exception localhost dot suffix</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/start-url-machine-name.png" medium="image">
			<media:title type="html">Start Url Machine Name</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/base-address-machine-name.png" medium="image">
			<media:title type="html">Base address Machine Name</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/fiddler-machine-name-thumb.png" medium="image">
			<media:title type="html">Fiddler Machine Name</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/ie-machine-name.png" medium="image">
			<media:title type="html">IE Machine Name</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/start-url-ipv4.png" medium="image">
			<media:title type="html">Start Url ipv4</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/base-address-ipv4.png" medium="image">
			<media:title type="html">Base address ipv4</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/fiddler-ipv4-thumb.png" medium="image">
			<media:title type="html">Fiddler ipv4</media:title>
		</media:content>
	</item>
		<item>
		<title>Silverlight 2 WCF Polling Duplex Support &#8211; Part 3: The Client</title>
		<link>http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-3-the-client/</link>
		<comments>http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-3-the-client/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 11:36:15 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[PollingDuplex]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[ColorAnimationUsingKeyFrames]]></category>
		<category><![CDATA[DataContractSerializer]]></category>
		<category><![CDATA[DuplexReceiver]]></category>
		<category><![CDATA[Polling Duplex]]></category>
		<category><![CDATA[Storyboard]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-3-the-client/</guid>
		<description><![CDATA[Edited on 20/October/2008 : Code download updated to support Silverlight 2 RTW (Code download) Introduction This is the third and final post in my current series on the support for duplex communication with a WCF service added to Silverlight 2 Beta 2.&#160; I should point out that this technology in its current form has been [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=138&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong><span style="color:#ff0000;">Edited on 20/October/2008 : Code download updated to support Silverlight 2 RTW</span></strong></p>
<p><strong><span style="color:#ff0000;"></span></strong><strong>(<a target="_blank" href="http://cid-920505bfc4faba01.skydrive.live.com/embedrowdetail.aspx/Public/PollingDuplexDemoRTW.zip">Code download</a>)</strong></p>
<h5>Introduction</h5>
<p>This is the third and final post in my current series on the support for <a target="_blank" href="http://blogs.msdn.com/silverlightws/archive/2008/06/10/detailed-overview-of-silverlight-2-beta-2-web-service-features.aspx">duplex communication with a WCF service</a> added to <a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2008/06/06/silverlight-2-beta2-released.aspx">Silverlight 2 Beta 2</a>.&#160; I should point out that this technology in its current form has been deemed by Microsoft as not yet fit for production applications and is therefore currently for evaluation only.&#160; In this post I introduce the client part of a sample application available for download (the download includes the server discussed in the <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server">previous post</a> also) that uses the bi-directional communication discussed in <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture">part one</a>.&#160; The sample application as a whole represents a simple client and server application that illustrates polling duplex communication in both directions.&#160; The client displays stock prices in a grid and animates updates received from the server.&#160; The user of the client application can also enter notes against a stock and have those notes propagate to all other connected clients via the server using polling duplex communication in the other direction.&#160; Here is a screenshot of the sample application running with the server and two connected clients, the same stock price updates are being displayed by both clients and the notes entered in Internet Explorer have been pushed to another instance of the client running in Firefox:</p>
<p><img style="border-width:0;" border="0" alt="Sample Application Running" src="http://petermcg.files.wordpress.com/2008/09/sample-application-running2.png?w=856&#038;h=525" width="856" height="525" /> </p>
<h5>The Client</h5>
<p>The layout of the Visual Studio 2008 solution is as follows: </p>
<p><img style="border-width:0;" border="0" alt="PollingDuplexDemo Solution Explorer" src="http://petermcg.files.wordpress.com/2008/09/pollingduplexdemo-solution-explorer1.png?w=259&#038;h=544" width="259" height="544" /> </p>
<p>There are three projects in the PollingDuplexDemo solution, the first is the Silverlight Application project StockClient that references the client-side version of System.ServiceModel.PollingDuplex.dll.&#160; The .xap file produced by building this project is referenced by the Silverlight ASP.NET server control in the StockClientTestPage.aspx file as part of the hosting StockClientHost Web Application project.&#160; The StockServer project is a Console Application project that self-hosts the polling duplex WCF service.&#160; As you can see from the image there are multiple startup projects, the first to start is the StockServer project along with the StockClientHost project shortly after. </p>
<h5>Page.xaml and Page.xaml.cs </h5>
<p>The markup in Page.xaml (see code download) defines the StocksGrid Silverlight DataGrid along with the rest of the UI elements, the code in Page.xaml.cs adds some initialisation code to the default constructor and handlers for some UI events.&#160; When the Silverlight Application loads and assigns an instance of the Page class defined across these files to the RootVisual property of the Application class, the constructor shown below is executed:</p>
<pre class="code"><span style="color:blue;">namespace </span>StockClient
{
    <span style="color:blue;">public partial class </span><span style="color:#2b91af;">Page </span>: <span style="color:#2b91af;">UserControl
    </span>{
        <span style="color:blue;">private readonly </span><span style="color:#2b91af;">StockTicker </span>stockTicker = <span style="color:blue;">null</span>;

        <span style="color:blue;">public </span>Page()
        {
            InitializeComponent();

            stockTicker = <span style="color:blue;">new </span><span style="color:#2b91af;">StockTicker</span>(<span style="color:blue;">this</span>.Dispatcher);

            <span style="color:green;">// Bind DataGrid to ObservableCollection
            </span>StocksGrid.ItemsSource = stockTicker.StockList;

            <span style="color:green;">// Get deltas from stock delta service
            </span>stockTicker.SubscribeDeltas();
        }

        <span style="color:blue;">private void </span>AddNotes_Click(<span style="color:blue;">object </span>sender, <span style="color:#2b91af;">RoutedEventArgs </span>e)
        {
            <span style="color:#2b91af;">Stock </span>selectedStock = StocksGrid.SelectedItem <span style="color:blue;">as </span><span style="color:#2b91af;">Stock</span>;

            <span style="color:blue;">if </span>(selectedStock != <span style="color:blue;">null</span>)
            {
                selectedStock.Notes = Notes.Text;

                stockTicker.Sync(selectedStock);
            }
        }

        <span style="color:blue;">private void </span>StocksGrid_SelectionChanged(<span style="color:blue;">object </span>sender, <span style="color:#2b91af;">EventArgs </span>e)
        {
            <span style="color:#2b91af;">Stock </span>selectedStock = StocksGrid.SelectedItem <span style="color:blue;">as </span><span style="color:#2b91af;">Stock</span>;

            <span style="color:blue;">if </span>(selectedStock != <span style="color:blue;">null </span>&amp;&amp; !<span style="color:#2b91af;">String</span>.IsNullOrEmpty(selectedStock.Notes))
            {
                Notes.Text = selectedStock.Notes;
            }
        }
    }
}</pre>
<h5>The StockTicker Class </h5>
<p>It&#8217;s apparent from the code above that the instance of the StockTicker class is central to everything happening in the client application and indeed it&#8217;s the code in this class that implements the client-side PollingDuplex support:</p>
<pre class="code"><span style="color:blue;">namespace </span>StockClient
{
    <span style="color:blue;">public sealed class </span><span style="color:#2b91af;">StockTicker
    </span>{
        <span style="color:green;">// Reference to layout instance that created the StockTicker
        </span><span style="color:blue;">private readonly </span><span style="color:#2b91af;">Dispatcher </span>owner = <span style="color:blue;">null</span>;
        <span style="color:green;">// Object used to let ThreadPool know to stop waiting and proceed
        </span><span style="color:blue;">private readonly </span><span style="color:#2b91af;">AutoResetEvent </span>waitObject = <span style="color:blue;">new </span><span style="color:#2b91af;">AutoResetEvent</span>(<span style="color:blue;">false</span>);

        <span style="color:green;">// Asynchronously begins an open operation on an ICommunicationObject with code to call EndOpen when it completes
        </span><span style="color:blue;">private static readonly </span><span style="color:#2b91af;">Action</span>&lt;<span style="color:#2b91af;">ICommunicationObject</span>&gt; Open =
                                    ico =&gt; ico.BeginOpen(iar =&gt; ico.EndOpen(iar), ico);
        <span style="color:green;">// Asynchronously begins a send operation on an IDuplexSessionChannel with code to call EndSend when it completes
        </span><span style="color:blue;">private static readonly </span><span style="color:#2b91af;">Action</span>&lt;<span style="color:#2b91af;">IDuplexSessionChannel</span>, <span style="color:#2b91af;">Message</span>&gt; Send =
                                    (idc, msg) =&gt; idc.BeginSend(msg, iar =&gt; idc.EndSend(iar), idc);
        <span style="color:green;">// Asynchronously begins a receive operation on an IDuplexSessionChannel with code to call an Action&lt;Message&gt; when it completes
        </span><span style="color:blue;">private static readonly </span><span style="color:#2b91af;">Action</span>&lt;<span style="color:#2b91af;">IDuplexSessionChannel</span>, <span style="color:#2b91af;">Action</span>&lt;<span style="color:#2b91af;">Message</span>&gt;&gt; Receive =
                                    (idc, act) =&gt; idc.BeginReceive(iar =&gt; act(idc.EndReceive(iar)), idc);

        <span style="color:green;">// Serializes instances of the Stock type before they are sent on the wire
        </span><span style="color:blue;">private readonly </span><span style="color:#2b91af;">DataContractSerializer </span>stockSerializer = <span style="color:blue;">new </span><span style="color:#2b91af;">DataContractSerializer</span>(<span style="color:blue;">typeof</span>(<span style="color:#2b91af;">Stock</span>));
        <span style="color:green;">// Channel for communication to WCF service
        </span><span style="color:blue;">private </span><span style="color:#2b91af;">IDuplexSessionChannel </span>channel;

        <span style="color:green;">// List of stocks designed to be bound to a UI control
        </span><span style="color:blue;">private readonly </span><span style="color:#2b91af;">StockList </span>stockList = <span style="color:blue;">new </span><span style="color:#2b91af;">StockList</span>();

        <span style="color:blue;">public </span><span style="color:#2b91af;">StockList </span>StockList
        {
            <span style="color:blue;">get </span>{ <span style="color:blue;">return </span>stockList; }
        }

        <span style="color:blue;">public </span>StockTicker(<span style="color:#2b91af;">Dispatcher </span>owner)
        {
            <span style="color:blue;">if </span>(owner == <span style="color:blue;">null</span>)
            {
                <span style="color:blue;">throw new </span><span style="color:#2b91af;">ArgumentNullException</span>(<span style="color:#a31515;">&quot;owner&quot;</span>);
            }

            <span style="color:blue;">this</span>.owner = owner;
        }

        <span style="color:blue;">public void </span>SubscribeDeltas()
        {
            <span style="color:green;">// Create a channel factory capable of producing a channel of type IDuplexSessionChannel
            </span><span style="color:#2b91af;">IChannelFactory</span>&lt;<span style="color:#2b91af;">IDuplexSessionChannel</span>&gt; factory =
                <span style="color:blue;">new </span><span style="color:#2b91af;">PollingDuplexHttpBinding</span>().BuildChannelFactory&lt;<span style="color:#2b91af;">IDuplexSessionChannel</span>&gt;();
            Open(factory);

            <span style="color:green;">// Address of the polling duplex server and creation of the channel to that endpoint
            </span><span style="color:#2b91af;">EndpointAddress </span>endPoint = <span style="color:blue;">new </span><span style="color:#2b91af;">EndpointAddress</span>(<span style="color:#a31515;">&quot;http://localhost:10201/StockService&quot;</span>);
            channel = factory.CreateChannel(endPoint);
            Open(channel);

            <span style="color:green;">// Create a message with the appropriate SOAPAction and asynchronously send it on the channel
            </span><span style="color:#2b91af;">Message </span>message =
                <span style="color:#2b91af;">Message</span>.CreateMessage(<span style="color:#2b91af;">MessageVersion</span>.Soap11, <span style="color:#a31515;">&quot;Silverlight/IStockService/Register&quot;</span>);
            Send(channel, message);

            <span style="color:green;">// Use the thread pool to start only one asynchronous request to Receive messages from the server
            // Only start another asynchronous request when a signal is received that the first thread pool thread has received something
            </span><span style="color:#2b91af;">ThreadPool</span>.RegisterWaitForSingleObject(waitObject,
                                                   <span style="color:blue;">delegate </span>{ Receive(channel, CompleteReceive); },
                                                   <span style="color:blue;">null</span>,
                                                   <span style="color:#2b91af;">Timeout</span>.Infinite,
                                                   <span style="color:blue;">false</span>);
            waitObject.Set();
        }

        <span style="color:blue;">public void </span>Sync(<span style="color:#2b91af;">Stock </span>stock)
        {
            <span style="color:green;">// Create a message with the appropriate SOAPAction and asynchronously send it on the channel with the serialized Stock as the body of the envelope
            </span><span style="color:#2b91af;">Message </span>message =
                <span style="color:#2b91af;">Message</span>.CreateMessage(<span style="color:#2b91af;">MessageVersion</span>.Soap11, <span style="color:#a31515;">&quot;Silverlight/IStockService/Sync&quot;</span>, stock, stockSerializer);
            Send(channel, message);
        }

        <span style="color:blue;">private void </span>CompleteReceive(<span style="color:#2b91af;">Message </span>message)
        {
            <span style="color:green;">// Deserialize the body of the SOAP message into a Stock object
            </span><span style="color:#2b91af;">Stock </span>stock = message.GetBody&lt;<span style="color:#2b91af;">Stock</span>&gt;();

            <span style="color:green;">// Queue a call to UpdateStockList on the Dispatcher of the thread that created this instance
            </span><span style="color:#2b91af;">Action</span>&lt;<span style="color:#2b91af;">Stock</span>&gt; action = UpdateStockList;
            owner.BeginInvoke(action, stock);

            <span style="color:green;">// Signal the thread pool to start another single asynchronous request to Receive messages from the server
            </span>waitObject.Set();
        }

        <span style="color:blue;">private void </span>UpdateStockList(<span style="color:#2b91af;">Stock </span>delta)
        {
            <span style="color:green;">// NOTE : CheckAccess is there but intellisense doesn't see it because of the [EditorBrowsable(EditorBrowsableState.Never)] attribute
            </span><span style="color:blue;">if </span>(!owner.CheckAccess())
            {
                <span style="color:blue;">throw new </span><span style="color:#2b91af;">InvalidOperationException</span>(<span style="color:#a31515;">&quot;The calling thread cannot access this method because a different thread owns it.&quot;</span>);
            }

            <span style="color:green;">// Check if this Stock is already in the collection
            </span><span style="color:#2b91af;">Stock </span>existing = stockList.FirstOrDefault(s =&gt; s.Symbol == delta.Symbol);

            <span style="color:blue;">if </span>(existing == <span style="color:blue;">default</span>(<span style="color:#2b91af;">Stock</span>))
            {
                <span style="color:green;">// This delta is a new Stock
                </span>stockList.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">StockHighlight</span>(delta));
            }
            <span style="color:blue;">else
            </span>{
                <span style="color:green;">// This delta is an existing Stock
                </span>existing.Ask = delta.Ask;
                existing.Bid = delta.Bid;

                <span style="color:blue;">if </span>(!<span style="color:#2b91af;">String</span>.IsNullOrEmpty(delta.Notes))
                {
                    existing.Notes = delta.Notes;
                }
            }
        }
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>In order to create an instance of the StockTicker class a reference to an instance of the System.Threading.Dispatcher class is required.&#160; In the initialisation of the StockTicker instance in the Page class constructor the Dispatcher property inherited all the way from System.Windows.DependencyObject is used.&#160; This provides StockTicker with a queue to add tasks to for execution on the UI thread.&#160; It is essential to update collections that may be bound to UI controls (such as the StockList property) from the UI thread to avoid an invalid cross-thread access (UnauthorizedAccessException) exception; this restriction also applies to the animation of individual stock prices using Storyboards managed by the StockHighlight class.&#160; The stored Dispatcher reference is later used to queue calls to UpdateStockList to be executed on the UI thread from the CompleteReceive method and to check the correct thread has called UpdateStockList before updating the collection or the Stock properties that cause animation Storyboards to begin. </p>
<p>After the instance of StockTicker has been created in the constructor of the Page class the SubscribeDeltas method is called.&#160; This method performs all of the client setup necessary to begin a polling duplex session with the WCF service.&#160; The method body begins by creating an instance of the client-side version of <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.pollingduplexhttpbinding(VS.95).aspx">PollingDuplexHttpBinding</a> (see <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture">part one</a>) and extracting an instance of a <a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms789050.aspx">channel factory</a> of type <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.iduplexsessionchannel.aspx">IDuplexSessionChannel</a> from that binding.&#160; The factory is then opened asynchronously and the channel is created, the client then initiates communication by asynchronously opening the channel to the WCF service specified in EndpointAddress.&#160; The method progresses to create a SOAP 1.1 <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message(VS.95).aspx">Message</a> instance specifying the One Way Register method discussed in the previous post in the SOAPAction; the instance of this message is then sent asynchronously along the channel to the server.&#160; Finally the method uses an <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx">AutoResetEvent</a> to signal a ThreadPool thread to begin one asynchronous request to receive messages pushed from the server.&#160; When a message is eventually received the CompleteReceive callback method is executed to queue a call back to the UI thread with the received Stock object before signaling the wait handle; this signal in turn prompts the thread pool to release another single asynchronous request to receive another message. </p>
<p>The Sync method creates a new SOAP 1.1 Message with a different SOAPAction and with the Stock parameter (containing the Notes entered by the user) as the body of the envelope serialised via the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx">DataContractSerializer</a>.&#160; The method then uses the same channel opened in SubscribeDeltas to asynchronously send the message to the server for propagation to all connected clients.&#160; The code for the WCF service methods being called here is discussed in <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server">part two</a>, the make up of these asynchronous calls and their responses on the wire is discussed under the &#8216;Anatomy Of A Message Exchange&#8217; heading In <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture">part one</a>. </p>
<p>The UpdateStockList method checks the current thread as previously described and then searches the StockList collection for the current Stock object comparing Symbol properties.&#160; A new instance of the StockHighlight class is created to add to StockList if the received stock does not exist in the collection.&#160; As StockList is an ObservableCollection this insert will notify the DataGrid that it&#8217;s ItemsSource has changed and to update itself to honour the addition in the UI.&#160; If the stock already exists then only the relevant price and notes properties on the existing StockHighlight instance are updated, triggering the relevant animations.&#160; These updates in turn cause the PropertyChanged event from INotifyPropertyChanged implemented by the Stock class (see code download) to fire again causing the DataGrid to update the UI. </p>
<h5>The StockHighlight Class</h5>
<p>This class extends the basic Stock class overriding the Ask and Bid properties and exposing two public properties of type Brush:</p>
<pre class="code"><span style="color:blue;">namespace </span>StockClient
{
    [<span style="color:#2b91af;">DataContract</span>(Name = <span style="color:#a31515;">&quot;Stock&quot;</span>, Namespace = <span style="color:#a31515;">&quot;urn:petermcg.wordpress.com&quot;</span>)]
    <span style="color:blue;">public class </span><span style="color:#2b91af;">StockHighlight </span>: <span style="color:#2b91af;">Stock
    </span>{
        <span style="color:blue;">public </span><span style="color:#2b91af;">Brush </span>AskHighlight { <span style="color:blue;">get</span>; <span style="color:blue;">private set</span>; }
        <span style="color:blue;">public </span><span style="color:#2b91af;">Brush </span>BidHighlight { <span style="color:blue;">get</span>; <span style="color:blue;">private set</span>; }

        <span style="color:blue;">private </span><span style="color:#2b91af;">Storyboard </span>askPosStory = <span style="color:blue;">new </span><span style="color:#2b91af;">Storyboard</span>();
        <span style="color:blue;">private </span><span style="color:#2b91af;">Storyboard </span>askNegStory = <span style="color:blue;">new </span><span style="color:#2b91af;">Storyboard</span>();
        <span style="color:blue;">private </span><span style="color:#2b91af;">Storyboard </span>bidPosStory = <span style="color:blue;">new </span><span style="color:#2b91af;">Storyboard</span>();
        <span style="color:blue;">private </span><span style="color:#2b91af;">Storyboard </span>bidNegStory = <span style="color:blue;">new </span><span style="color:#2b91af;">Storyboard</span>();

        <span style="color:blue;">private static readonly </span><span style="color:#2b91af;">Duration </span>DefaultDuration = <span style="color:blue;">new </span><span style="color:#2b91af;">Duration</span>(<span style="color:#2b91af;">TimeSpan</span>.FromSeconds(2.0));
        <span style="color:blue;">private static readonly </span><span style="color:#2b91af;">Color </span>DefaultColor = <span style="color:#2b91af;">Colors</span>.Transparent;

        <span style="color:blue;">public </span>StockHighlight(<span style="color:#2b91af;">Stock </span>stock)
        {
            <span style="color:blue;">base</span>.Ask = stock.Ask;
            <span style="color:blue;">base</span>.Bid = stock.Bid;
            <span style="color:blue;">base</span>.Notes = stock.Notes;
            <span style="color:blue;">base</span>.Symbol = stock.Symbol;

            InitializeAnimation();
        }

        <span style="color:blue;">private void </span>InitializeAnimation()
        {
            <span style="color:green;">// Default highlight color to Transparent
            </span><span style="color:blue;">this</span>.AskHighlight = <span style="color:blue;">new </span><span style="color:#2b91af;">SolidColorBrush</span>(DefaultColor);
            <span style="color:blue;">this</span>.BidHighlight = <span style="color:blue;">new </span><span style="color:#2b91af;">SolidColorBrush</span>(DefaultColor);

            InitializeAnimation(AskHighlight, askPosStory, askNegStory);
            InitializeAnimation(BidHighlight, bidPosStory, bidNegStory);
        }

        <span style="color:blue;">private static void </span>InitializeAnimation(<span style="color:#2b91af;">Brush </span>brush, <span style="color:#2b91af;">Storyboard </span>pos, <span style="color:#2b91af;">Storyboard </span>neg)
        {
            <span style="color:green;">// Set up a unique Positive and Negative ColorAnimationUsingKeyFrames for  price
            </span><span style="color:#2b91af;">ColorAnimationUsingKeyFrames </span>posAnim = <span style="color:blue;">new </span><span style="color:#2b91af;">ColorAnimationUsingKeyFrames</span>();
            posAnim.KeyFrames.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">LinearColorKeyFrame</span>() { KeyTime = <span style="color:#2b91af;">TimeSpan</span>.FromSeconds(0.0), Value = <span style="color:#2b91af;">Colors</span>.Green });
            posAnim.KeyFrames.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">LinearColorKeyFrame</span>() { KeyTime = DefaultDuration.TimeSpan, Value = DefaultColor });
            posAnim.Duration = DefaultDuration;

            <span style="color:#2b91af;">ColorAnimationUsingKeyFrames </span>negAnim = <span style="color:blue;">new </span><span style="color:#2b91af;">ColorAnimationUsingKeyFrames</span>();
            negAnim.KeyFrames.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">LinearColorKeyFrame</span>() { KeyTime = <span style="color:#2b91af;">TimeSpan</span>.FromSeconds(0.0), Value = <span style="color:#2b91af;">Colors</span>.Red });
            negAnim.KeyFrames.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">LinearColorKeyFrame</span>() { KeyTime = DefaultDuration.TimeSpan, Value = DefaultColor });
            negAnim.Duration = DefaultDuration;

            <span style="color:green;">// Add animations to storyboard
            </span>pos.Children.Add(posAnim);
            neg.Children.Add(negAnim);

            <span style="color:green;">// Target the  color animations to the  brush
            </span><span style="color:#2b91af;">Storyboard</span>.SetTarget(posAnim, brush);
            <span style="color:#2b91af;">Storyboard</span>.SetTarget(negAnim, brush);

            <span style="color:green;">// Target the property of the  brush to animate
            </span><span style="color:#2b91af;">Storyboard</span>.SetTargetProperty(posAnim, <span style="color:blue;">new </span><span style="color:#2b91af;">PropertyPath</span>(<span style="color:#a31515;">&quot;(Brush.Color)&quot;</span>));
            <span style="color:#2b91af;">Storyboard</span>.SetTargetProperty(negAnim, <span style="color:blue;">new </span><span style="color:#2b91af;">PropertyPath</span>(<span style="color:#a31515;">&quot;(Brush.Color)&quot;</span>));
        }

        <span style="color:blue;">public override double </span>Ask
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return base</span>.Ask;
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">if </span>((<span style="color:blue;">base</span>.Ask.Equals(<span style="color:blue;">value</span>) != <span style="color:blue;">true</span>))
                {
                    <span style="color:#2b91af;">Func</span>&lt;<span style="color:blue;">double</span>, <span style="color:blue;">double</span>, <span style="color:#2b91af;">Storyboard</span>&gt; GetAskStory = (o, n) =&gt; (n &gt; o) ? askPosStory : askNegStory;
                    GetAskStory(<span style="color:blue;">this</span>.Ask, <span style="color:blue;">value</span>).Begin();

                    <span style="color:blue;">base</span>.Ask = <span style="color:blue;">value</span>;
                }
            }
        }

        <span style="color:blue;">public override double </span>Bid
        {
            <span style="color:blue;">get
            </span>{
                <span style="color:blue;">return base</span>.Bid;
            }
            <span style="color:blue;">set
            </span>{
                <span style="color:blue;">if </span>((<span style="color:blue;">base</span>.Bid.Equals(<span style="color:blue;">value</span>) != <span style="color:blue;">true</span>))
                {
                    <span style="color:#2b91af;">Func</span>&lt;<span style="color:blue;">double</span>, <span style="color:blue;">double</span>, <span style="color:#2b91af;">Storyboard</span>&gt; GetBidStory = (o, n) =&gt; (n &gt; o) ? bidPosStory : bidNegStory;
                    GetBidStory(<span style="color:blue;">this</span>.Bid, <span style="color:blue;">value</span>).Begin();

                    <span style="color:blue;">base</span>.Bid = <span style="color:blue;">value</span>;

                    <span style="color:blue;">this</span>.RaisePropertyChanged(<span style="color:#a31515;">&quot;Bid&quot;</span>);
                }
            }
        }
    }
}</pre>
<p>Each cell in the Bid and Ask columns of the DataGrid declared in Page.xaml contains a StackPanel whose Background property is bound to the respective Brush property.&#160; This way each cell is able to play it&#8217;s own unique animation specific to the Stock displayed.&#160; These Brush properties need to be part of each individual Stock object rather than global resources so the whole column does not change colour when one stock changes price.&#160; The InitializeAnimation method associates animations of type <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.media.animation.coloranimationusingkeyframes(VS.95).aspx">ColorAnimationUsingKeyFrames</a> with each of these Brushes for both positive and negative changes.&#160; The appropriate Storyboard to play is chosen in the Bid and Ask property setters based on the new value.</p>
<p>The most salient parts of the client code are now covered, download the solution, press F5 to start the server and one client automatically, you can then browse to StockClientTestPage.aspx using the same address from multiple clients in separate browsers once the service is running.</p>
<p>In the future it looks likely that the client side Silverlight 2 Polling Duplex API will be simplified to enable a less verbose method of connecting to and receiving pushed messages from a WCF service.&#160; This post talks more about the possibility of a DuplexReceiver&lt;T&gt; class for simple client scenarios in the future; it&#8217;s always prudent to know what such a class will be doing for you behind the scenes.</p>
<h5>Further Reading</h5>
<p>A few links on polling duplex support in Silverlight 2 Beta 2 you might find useful:</p>
<p><a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc645028(VS.95).aspx">MSDN &#8211; Access a Duplex Service with the Channel Model</a></p>
<p><a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc645027(VS.95).aspx">MSDN &#8211; How to: Build a Duplex Service</a></p>
<p><a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc645026(VS.95).aspx">MSDN &#8211; Accessing Duplex Services</a></p>
<p><a target="_blank" href="http://weblogs.asp.net/dwahlin/archive/2008/06/16/pushing-data-to-a-silverlight-client-with-wcf-duplex-service-part-i.aspx">Pushing Data to a Silverlight Client with a WCF Duplex Service &#8211; Part I</a> </p>
<p><a target="_blank" href="http://weblogs.asp.net/dwahlin/archive/2008/06/19/pushing-data-to-a-silverlight-client-with-a-wcf-duplex-service-part-ii.aspx">Pushing Data to a Silverlight Client with a WCF Duplex Service &#8211; Part II</a></p>
<p><a target="_blank" href="http://blogs.msdn.com/cqwang/archive/2008/06/12/detailed-overview-of-silverlight-2-beta-2-web-service-features.aspx">Detailed Overview of Silverlight 2 Beta 2 Web Service Features</a></p>
<p><a target="_blank" href="http://eugeneos.blogspot.com/2008/04/pushing-data-to-silverlight-application.html">&quot;Pushing&quot; Data to a Silverlight Application</a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/petermcg.wordpress.com/138/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/petermcg.wordpress.com/138/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/138/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=138&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-3-the-client/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/sample-application-running2.png" medium="image">
			<media:title type="html">Sample Application Running</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/pollingduplexdemo-solution-explorer1.png" medium="image">
			<media:title type="html">PollingDuplexDemo Solution Explorer</media:title>
		</media:content>
	</item>
		<item>
		<title>Silverlight 2 WCF Polling Duplex Support &#8211; Part 2: The Server</title>
		<link>http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server/</link>
		<comments>http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 11:35:08 +0000</pubDate>
		<dc:creator>petermcg</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[AsyncPattern]]></category>
		<category><![CDATA[ClientAccessPolicy]]></category>
		<category><![CDATA[Polling Duplex]]></category>
		<category><![CDATA[Self Hosted]]></category>

		<guid isPermaLink="false">http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server/</guid>
		<description><![CDATA[Edited on 20/October/2008 : Code download updated to support Silverlight 2 RTW (Code download) Introduction This is the second in a series of posts on the support for duplex communication with a WCF service added to Silverlight 2 Beta 2.&#160; I should point out that this technology in its current form has been deemed by [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=135&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[</p>
<p><strong><span style="color:#ff0000;">Edited on 20/October/2008 : Code download updated to support Silverlight 2 RTW</span></strong></p>
<p><strong><span style="color:#ff0000;"></span></strong><strong>(<a target="_blank" href="http://cid-920505bfc4faba01.skydrive.live.com/embedrowdetail.aspx/Public/PollingDuplexDemoRTW.zip">Code download</a>)</strong></p>
<h5>Introduction</h5>
<p>This is the second in a series of posts on the support for <a target="_blank" href="http://blogs.msdn.com/silverlightws/archive/2008/06/10/detailed-overview-of-silverlight-2-beta-2-web-service-features.aspx">duplex communication with a WCF service</a> added to <a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2008/06/06/silverlight-2-beta2-released.aspx">Silverlight 2 Beta 2</a>.&#160; I should point out that this technology in its current form has been deemed by Microsoft as not yet fit for production applications and is therefore currently for evaluation only.&#160; In this post I introduce the server part of a sample application available for download (the download includes the client also) that uses the bi-directional communication discussed in <a target="_blank" href="http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-1-architecture">part one</a>.&#160; The sample application as a whole represents a simple client and server application that illustrates polling duplex communication in both directions.&#160; The client displays stock prices in a grid and animates updates received from the server.&#160; The user of the client application can also enter notes against a stock and have those notes propagate to all other connected clients via the server using polling duplex communication in the other direction.&#160; Here is a screenshot of the sample application running with the server and two connected clients, the same stock price updates are being displayed by both clients and the notes entered in Internet Explorer have been pushed to another instance of the client running in Firefox:</p>
<p><img style="border-width:0;" border="0" alt="Sample Application Running" src="http://petermcg.files.wordpress.com/2008/09/sample-application-running1.png?w=856&#038;h=525" width="856" height="525" /> </p>
<h5>The Server</h5>
<p>The layout of the Visual Studio 2008 solution is as follows:</p>
<p><img style="border-width:0;" border="0" alt="PollingDuplexDemo Solution Explorer" src="http://petermcg.files.wordpress.com/2008/09/pollingduplexdemo-solution-explorer.png?w=259&#038;h=544" width="259" height="544" /> </p>
<p>There are three projects in the PollingDuplexDemo solution, the first is the Silverlight Application project StockClient.&#160; The .xap file produced by building this project is referenced by the <a target="_blank" href="http://petermcg.wordpress.com/2008/07/16/silverlight-initialization-via-the-silverlight-server-control/">Silverlight ASP.NET server control</a> in the StockClientTestPage.aspx file as part of the hosting StockClientHost Web Application project.&#160; The StockServer project is a Console Application that self-hosts the polling duplex WCF service and represents the server.&#160; You can see from the Visual Studio 2008 solution that there are multiple startup projects, the first to start is the StockServer project along with the StockClientHost project shortly after.</p>
<h5>Preliminaries</h5>
<p>In order to self-host a WCF service in a Console Application the server needs to register itself as the HTTP handler for a certain URI; this is also termed as registering a portion of the local HTTP namespace.&#160; In order to do this the application needs to run as a local Administrator or the current non-administrative user needs to have been assigned to the <a target="_blank" href="http://en.wikipedia.org/wiki/Access_control_list">ACL</a> for a particular URI, <a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms733768.aspx">you can read more about this here</a>.&#160; If the server Console Application does not have the appropriate permissions a System.ServiceModel.AddressAccessDeniedException exception is raised with the message &quot;HTTP could not register URL <a href="http://+:10201/StockService/">http://+:10201/StockService/</a>. Your process does not have access rights to this namespace.&quot;</p>
<p><img style="border-width:0;" border="0" alt="AddressAccessDeniedException Exception" src="http://petermcg.files.wordpress.com/2008/09/addressaccessdeniedexception-exception.png?w=436&#038;h=269" width="436" height="269" /> </p>
<p>If you are using Visual Studio 2008 as an Administrator or using Windows XP you won&#8217;t run into this problem and I have accounted for it on Windows Vista by creating a <a target="_blank" href="http://www.danielmoth.com/Blog/labels/UAC.html">UAC manifest</a> (see the app.manifest file) that requires the server to be run as an Administrator.&#160; As a result of this configuration you may encounter the following message the first time you press F5:</p>
<p><img style="border-width:0;" border="0" alt="Restart using different Credentials" src="http://petermcg.files.wordpress.com/2008/09/restart-using-different-credentials.png?w=508&#038;h=262" width="508" height="262" /> </p>
<p>Selecting &#8216;Restart under different credentials&#8217; re-starts Visual Studio as a local Administrator resulting in the server being able to register and listen at the HTTP address it has been configured with.</p>
<h5>The WCF Service Interfaces</h5>
<p>The StockServer project references the server-side System.ServiceModel.PollingDuplex.dll assembly and defines one WCF service called StockService.&#160; Here are the ServiceContract interfaces defined in the StockServer namespace:</p>
<pre class="code"><span style="color:blue;">namespace </span>StockServer
{
    [<span style="color:#2b91af;">ServiceContract</span>(Namespace = <span style="color:#a31515;">&quot;Silverlight&quot;</span>, CallbackContract = <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">IStockClient</span>))]
    <span style="color:blue;">public interface </span><span style="color:#2b91af;">IStockService
    </span>{
        [<span style="color:#2b91af;">OperationContract</span>(IsOneWay = <span style="color:blue;">true</span>)]
        <span style="color:blue;">void </span>Register(<span style="color:#2b91af;">Message </span>message);

        [<span style="color:#2b91af;">OperationContract</span>(IsOneWay = <span style="color:blue;">true</span>)]
        <span style="color:blue;">void </span>Sync(<span style="color:#2b91af;">Message </span>message);
    }

    [<span style="color:#2b91af;">ServiceContract</span>]
    <span style="color:blue;">public interface </span><span style="color:#2b91af;">IStockClient
    </span>{
        [<span style="color:#2b91af;">OperationContract</span>(IsOneWay = <span style="color:blue;">true</span>, AsyncPattern = <span style="color:blue;">true</span>)]
        <span style="color:#2b91af;">IAsyncResult </span>BeginReceive(<span style="color:#2b91af;">Message </span>message, <span style="color:#2b91af;">AsyncCallback </span>callback, <span style="color:blue;">object </span>state);

        <span style="color:blue;">void </span>EndReceive(<span style="color:#2b91af;">IAsyncResult </span>result);
    }

    [<span style="color:#2b91af;">ServiceContract</span>]
    <span style="color:blue;">public interface </span><span style="color:#2b91af;">IPolicyProvider
    </span>{
        [<span style="color:#2b91af;">OperationContract</span>, <span style="color:#2b91af;">WebGet</span>(UriTemplate = <span style="color:#a31515;">&quot;/ClientAccessPolicy.xml&quot;</span>)]
        <span style="color:#2b91af;">Stream </span>ProvidePolicy();
    }
}</pre>
<p>Three interfaces are defined in all: IStockService, IStockClient and IPolicyProvider.&#160; IStockService defines the two methods Register and Sync specified as One Way operations, hence the method signatures cannot specify anything other than void as the return type.&#160; Setting <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.isoneway.aspx">IsOneWay</a> to true has the effect that clients will not block waiting for a return message after having called the service as they would with a default request response operation.&#160; A client configured for polling duplex will rather poll asynchronously and pick up messages pushed to them from the service as discussed in part one.&#160; You may also recall these two operations from the value of SOAPAction in the traced HTTP requests in the previous article.&#160; The IStockClient type is specified via the <a target="_blank" href="http://msdn.microsoft.com/en-us/magazine/cc163537.aspx">CallbackContract</a> property as the type that will callback to the client from instances of services that implement IStockService. </p>
<p>IStockClient defines the Receive operation as an asynchronous operation by setting <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.asyncpattern.aspx">AsyncPattern</a> to true and defining Begin and End methods matching the required pattern.&#160; This method is specified as asynchronous to cater for a problem I was encountering when one client aborted or faulted while many other clients were connected.&#160; In this scenario a synchronous method call back to the faulted client resulted in the server thread blocking until the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.pollingduplexbindingelement.polltimeout(VS.95).aspx">PollTimeout</a> period elapsed for that client with the exception shown in the previous post.&#160; This is fine for the faulted client but the blocking stopped the other connected clients receiving their updates.&#160; The asynchronous version handles the reply using the thread pool so that in the same situation the faulted client will block and timeout on a thread pool thread while the other connected clients still receive their updates as normal. </p>
<p>The IPolicyProvider interface sets up a creative solution (<a target="_blank" href="http://blogs.msdn.com/carlosfigueira/archive/2008/03/07/enabling-cross-domain-calls-for-silverlight-apps-on-self-hosted-web-services.aspx">thanks to this post</a>) to the problem of serving up policy requirements to Silverlight 2 clients when using a self-hosted WCF service.&#160; The only change I had to make was to include http-request-headers=&quot;*&quot; in the response to ensure compatibility with the Silverlight 2 Beta 2 policy requirements instead of Beta 1.&#160; The declaration above specifies that the ProvidePolicy method should be called in the event of a GET request whose URI includes the relative string specified in UriTemplate.&#160; I have not included support for Flash compatible crossdomain.xml files but this could be easily added using the same method.&#160; WebGet was introduced as part of WCF 3.5, its interesting (though not relevant to Silverlight self-hosted policy requirements) to note that the UriTemplate can also contain curly bracket <a target="_blank" href="http://jeffbarnes.net/portal/blogs/jeff_barnes/archive/2007/09/11/wcf-3-5-webget-attribute.aspx">placeholders that resolve to method parameters</a> for use with REST requests, similar functionality is provided in <a target="_blank" href="http://haacked.com/archive/2008/08/29/asp.net-mvc-codeplex-preview-5-released.aspx">ASP.NET MVC</a> <a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx">routing</a>. </p>
<h5>The WCF Service Class</h5>
<p>The following shows how the previously discussed interfaces are used throughout the declaration of the StockService class.&#160; The StockService class implements only two of the interfaces: IStockService and IPolicyProvider, the usage of the IStockClient interface is shown in the Register method:</p>
<pre class="code"><span style="color:blue;">namespace </span>StockServer
{
    <span style="color:blue;">public sealed class </span><span style="color:#2b91af;">StockService </span>: <span style="color:#2b91af;">IStockService</span>, <span style="color:#2b91af;">IPolicyProvider
    </span>{
        <span style="color:blue;">private </span><span style="color:#2b91af;">StockClient </span>client = <span style="color:blue;">null</span>;

        <span style="color:blue;">public void </span>Register(<span style="color:#2b91af;">Message </span>message)
        {
            client = <span style="color:blue;">new </span><span style="color:#2b91af;">StockClient</span>(<span style="color:#2b91af;">OperationContext</span>.Current.GetCallbackChannel&lt;<span style="color:#2b91af;">IStockClient</span>&gt;(),
                                          <span style="color:#a31515;">&quot;Silverlight/IStockService/Receive&quot;</span>);
            client.Faulted += OnClientFaulted;

            InitialReply();

            <span style="color:#2b91af;">StockGenerator</span>.Instance.DeltaReceived += OnDeltaReceived;
        }

        <span style="color:blue;">public void </span>Sync(<span style="color:#2b91af;">Message </span>message)
        {
            <span style="color:#2b91af;">Stock </span>delta = message.GetBody&lt;<span style="color:#2b91af;">Stock</span>&gt;();

            <span style="color:#2b91af;">StockGenerator</span>.Instance.Sync(delta);
        }

        <span style="color:blue;">private void </span>InitialReply()
        {
            <span style="color:blue;">foreach </span>(<span style="color:#2b91af;">Stock </span>stock <span style="color:blue;">in </span><span style="color:#2b91af;">StockGenerator</span>.Instance.DemoStocks)
            {
                Reply(stock);
            }
        }

        <span style="color:blue;">private void </span>Reply(<span style="color:#2b91af;">Stock </span>stock)
        {
            <span style="color:blue;">if </span>(client != <span style="color:blue;">null</span>)
            {
                client.Send(stock);
            }
        }

        <span style="color:blue;">private void </span>OnDeltaReceived(<span style="color:blue;">object </span>sender, <span style="color:#2b91af;">DeltaReceivedEventArgs </span>e)
        {
            Reply(e.Stock);
        }

        <span style="color:blue;">private void </span>OnClientFaulted(<span style="color:blue;">object </span>sender, <span style="color:#2b91af;">FaultedEventArgs </span>e)
        {
            <span style="color:blue;">if </span>(client != <span style="color:blue;">null</span>)
            {
                <span style="color:#2b91af;">StockGenerator</span>.Instance.DeltaReceived -= OnDeltaReceived;
                client = <span style="color:blue;">null</span>;
            }
        }

        <span style="color:blue;">public </span><span style="color:#2b91af;">Stream </span>ProvidePolicy()
        {
            <span style="color:#2b91af;">WebOperationContext</span>.Current.OutgoingResponse.ContentType = <span style="color:#a31515;">&quot;application/xml&quot;</span>;
            <span style="color:blue;">return new </span><span style="color:#2b91af;">MemoryStream</span>(<span style="color:#2b91af;">File</span>.ReadAllBytes(<span style="color:#a31515;">&quot;ClientAccessPolicy.xml&quot;</span>), <span style="color:blue;">false</span>);
        }
    }
}</pre>
<p>The StockService does not specify a <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.aspx">ServiceBehavior attribute</a> as part of it&#8217;s declaration so the defaults apply, the most relevant being InstanceContext.PerSession and ConcurrenyMode.Single.&#160; As such, a new instance of the StockService WCF service is created for every client that connects although it is also possible to configure the service as a singleton using the code download with very few changes if that is something you are interested in. </p>
<p>The Register method is called by clients when they first connect to the service, the Message parameter although required by the underlying framework is not used in the method body.&#160; The body firstly creates a new instance of the StockClient class (see code download) passing two parameters to the constructor: a reference to the channel back to the client along with the SOAPAction to use when sending a return message.&#160; Note this SOAPAction string does not mention the IStockClient interface but rather the IStockService interface and contains the name of the synchronous version of the Receive method which is not defined anywhere in user code.&#160; The rest of the method and indeed the class is fairly self-explanatory and centres around subscribing the current instance of StockService to receive deltas from the singleton StockGenerator class (see code download) when a client connects and unsubscribing when a fault occurs attempting to communicate with that client. </p>
<p>The Sync method does make use of the <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.aspx">Message</a> parameter sent from the client to extract the Stock (see code download) object and the notes entered against it.&#160; This is again passed on to the singleton StockGenerator class to update it&#8217;s state and raise a notification to all other subscribed clients.&#160; The implementation of the ProvidePolicy method simply returns a stream containing the contents of the ClientAccessPolicy.xml file (which is copied to the output directory of the executable) to satisfy the <a target="_blank" href="http://timheuer.com/blog/archive/2008/06/10/silverlight-services-cross-domain-404-not-found.aspx">policy requirements</a> required to allow Silverlight clients to connect to this self-hosted service cross-domain. </p>
<h5>Hosting the WCF Service </h5>
<p>The hosting information for the StockService service is split between the App.config file&#8230;</p>
<pre class="code"><span style="color:blue;">&lt;?</span><span style="color:#a31515;">xml </span><span style="color:red;">version</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">1.0</span>&quot; <span style="color:red;">encoding</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">utf-8</span>&quot; <span style="color:blue;">?&gt;
&lt;</span><span style="color:#a31515;">configuration</span><span style="color:blue;">&gt;
  &lt;</span><span style="color:#a31515;">system.serviceModel</span><span style="color:blue;">&gt;
    &lt;</span><span style="color:#a31515;">diagnostics </span><span style="color:red;">performanceCounters</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">All</span>&quot; <span style="color:blue;">/&gt;
    &lt;</span><span style="color:#a31515;">services</span><span style="color:blue;">&gt;
      &lt;</span><span style="color:#a31515;">service </span><span style="color:red;">name</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">StockServer.StockService</span>&quot;
               <span style="color:red;">behaviorConfiguration</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">StockServiceBehaviour</span>&quot;<span style="color:blue;">&gt;
        &lt;</span><span style="color:#a31515;">host</span><span style="color:blue;">&gt;
          &lt;</span><span style="color:#a31515;">baseAddresses</span><span style="color:blue;">&gt;
            &lt;</span><span style="color:#a31515;">add </span><span style="color:red;">baseAddress</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">http://localhost:10201/StockService</span>&quot; <span style="color:blue;">/&gt;
          &lt;/</span><span style="color:#a31515;">baseAddresses</span><span style="color:blue;">&gt;
        &lt;/</span><span style="color:#a31515;">host</span><span style="color:blue;">&gt;
        &lt;</span><span style="color:#a31515;">endpoint </span><span style="color:red;">address</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">mex</span>&quot;
                  <span style="color:red;">binding</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">mexHttpBinding</span>&quot;
                  <span style="color:red;">contract</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">IMetadataExchange</span>&quot; <span style="color:blue;">/&gt;
      &lt;/</span><span style="color:#a31515;">service</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">services</span><span style="color:blue;">&gt;
    &lt;</span><span style="color:#a31515;">behaviors</span><span style="color:blue;">&gt;
      &lt;</span><span style="color:#a31515;">serviceBehaviors</span><span style="color:blue;">&gt;
        &lt;</span><span style="color:#a31515;">behavior </span><span style="color:red;">name</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">StockServiceBehaviour</span>&quot;<span style="color:blue;">&gt;
          &lt;</span><span style="color:#a31515;">serviceMetadata </span><span style="color:red;">httpGetEnabled</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">true</span>&quot; <span style="color:blue;">/&gt;
          &lt;</span><span style="color:#a31515;">serviceDebug </span><span style="color:red;">includeExceptionDetailInFaults</span><span style="color:blue;">=</span>&quot;<span style="color:blue;">true</span>&quot; <span style="color:blue;">/&gt;
        &lt;/</span><span style="color:#a31515;">behavior</span><span style="color:blue;">&gt;
      &lt;/</span><span style="color:#a31515;">serviceBehaviors</span><span style="color:blue;">&gt;
    &lt;/</span><span style="color:#a31515;">behaviors</span><span style="color:blue;">&gt;
  &lt;/</span><span style="color:#a31515;">system.serviceModel</span><span style="color:blue;">&gt;
&lt;/</span><span style="color:#a31515;">configuration</span><span style="color:blue;">&gt;</span></pre>
<p>&#8230; and the StockServiceHost class that inherits from ServiceHost:</p>
<pre class="code"><span style="color:blue;">namespace </span>StockServer
{
    <span style="color:blue;">public class </span><span style="color:#2b91af;">StockServiceHost </span>: <span style="color:#2b91af;">ServiceHost
    </span>{
        <span style="color:blue;">public </span>StockServiceHost(<span style="color:blue;">object </span>singletonInstance, <span style="color:blue;">params </span><span style="color:#2b91af;">Uri</span>[] baseAddresses)
            : <span style="color:blue;">base</span>(singletonInstance, baseAddresses)
        {
        }

        <span style="color:blue;">public </span>StockServiceHost(<span style="color:#2b91af;">Type </span>serviceType, <span style="color:blue;">params </span><span style="color:#2b91af;">Uri</span>[] baseAddresses)
            : <span style="color:blue;">base</span>(serviceType, baseAddresses)
        {
        }

        <span style="color:blue;">protected override void </span>InitializeRuntime()
        {
            <span style="color:#2b91af;">Uri </span>baseAddress = <span style="color:blue;">this</span>.BaseAddresses[0];
            <span style="color:#2b91af;">Uri </span>policyAddress = <span style="color:blue;">new </span><span style="color:#2b91af;">Uri</span>(baseAddress.AbsoluteUri.Replace(baseAddress.AbsolutePath, <span style="color:#a31515;">&quot;&quot;</span>));

            <span style="color:blue;">this</span>.AddServiceEndpoint(
                <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">IStockService</span>),
                <span style="color:blue;">new </span><span style="color:#2b91af;">PollingDuplexHttpBinding</span>(),
                baseAddress);

            <span style="color:blue;">this</span>.AddServiceEndpoint(
                <span style="color:blue;">typeof</span>(<span style="color:#2b91af;">IPolicyProvider</span>),
                <span style="color:blue;">new </span><span style="color:#2b91af;">WebHttpBinding</span>(),
                policyAddress).Behaviors.Add(<span style="color:blue;">new </span><span style="color:#2b91af;">WebHttpBehavior</span>());

            <span style="color:blue;">base</span>.InitializeRuntime();
        }
    }
}</pre>
<p>This is where the server instance of <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.servicemodel.pollingduplexhttpbinding(VS.95).aspx">PollingDuplexHttpBinding</a> is instantiated and published as a service endpoint on the base address retrieved from the configuration file.&#160; Two other endpoints are defined for this service, one is the Metadata Exchange endpoint which you can navigate to in a browser when the server is running; the other is the endpoint for the policy response bound to the root of the base address.&#160; The constructors included simply defer to the base constructors of ServiceHost, the first one allows this class to be optionally used as a host of a singleton polling duplex service instance.&#160; When the Console Application starts it simply creates an instance of the StockServiceHost class and opens the communication channel to accept clients:</p>
<pre class="code"><span style="color:blue;">namespace </span>StockServer
{
    <span style="color:blue;">class </span><span style="color:#2b91af;">Program
    </span>{
        <span style="color:blue;">static void </span>Main(<span style="color:blue;">string</span>[] args)
        {
            <span style="color:green;">// Set Console display info
            </span><span style="color:#2b91af;">Console</span>.Title = <span style="color:#a31515;">&quot;Polling Duplex Stock Service&quot;</span>;
            <span style="color:#2b91af;">Console</span>.ForegroundColor = <span style="color:#2b91af;">ConsoleColor</span>.Cyan;

            <span style="color:blue;">using </span>(<span style="color:#2b91af;">StockServiceHost </span>serviceHost = <span style="color:blue;">new </span><span style="color:#2b91af;">StockServiceHost</span>(<span style="color:blue;">typeof</span>(<span style="color:#2b91af;">StockService</span>)))
            {
                serviceHost.Open();

                <span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&quot;Polling Duplex Stock Service Started...&quot;</span>);
                <span style="color:#2b91af;">Console</span>.WriteLine(<span style="color:#a31515;">&quot;Press &lt;ENTER&gt; to terminate service.&quot;</span>);
                <span style="color:#2b91af;">Console</span>.ReadLine();
            }
        }
    }
}</pre>
<p>The same stock prices are sent to all client channels at approximately the same time in each StockService instance&#8217;s handler for the singleton StockGenerator class&#8217;s DeltaReceived event via the StockClient instance.&#160; The full code for the definitions of the StockGenerator and StockClient classes is available in the code download.&#160; Currently new deltas are generated every 250.0 milliseconds using the ThreadPool, obviously the more this interval is reduced the more noticeable the performance degradation; especially below 100.0 milliseconds on my machine with two clients in separate browsers or tabs things eventually get out of sync.&#160; Comparing this solution to a similar <a target="_blank" href="http://petermcg.wordpress.com/2008/07/04/stock-list-demo-optimised/">solution I&#8217;ve published using Sockets</a> which can keep clients in sync at 1.0 millisecond intervals it&#8217;s clear to see there is work to be done on performance and it&#8217;s good to see the Silverlight Webservices Team <a target="_blank" href="http://blogs.msdn.com/silverlightws/archive/2008/06/10/detailed-overview-of-silverlight-2-beta-2-web-service-features.aspx">acknowledge this themselves</a>.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/petermcg.wordpress.com/135/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/petermcg.wordpress.com/135/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/petermcg.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/petermcg.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/petermcg.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/petermcg.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/petermcg.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/petermcg.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/petermcg.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/petermcg.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/petermcg.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/petermcg.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/petermcg.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/petermcg.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/petermcg.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/petermcg.wordpress.com/135/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=petermcg.wordpress.com&amp;blog=3360530&amp;post=135&amp;subd=petermcg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://petermcg.wordpress.com/2008/09/03/silverlight-polling-duplex-part-2-the-server/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">Peter</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/sample-application-running1.png" medium="image">
			<media:title type="html">Sample Application Running</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/pollingduplexdemo-solution-explorer.png" medium="image">
			<media:title type="html">PollingDuplexDemo Solution Explorer</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/addressaccessdeniedexception-exception.png" medium="image">
			<media:title type="html">AddressAccessDeniedException Exception</media:title>
		</media:content>

		<media:content url="http://petermcg.files.wordpress.com/2008/09/restart-using-different-credentials.png" medium="image">
			<media:title type="html">Restart using different Credentials</media:title>
		</media:content>
	</item>
	</channel>
</rss>
