<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.irm.se/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Johan's Blog</title><subtitle type="html">This and that in a developer's life in general</subtitle><id>http://blog.irm.se/blogs/johan/atom.aspx</id><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blog.irm.se/blogs/johan/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.60809.935">Community Server</generator><updated>2010-09-19T19:56:50Z</updated><entry><title>Command Handling the Nancy Way</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/09/08/Command-Handling-the-Nancy-Way.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/09/08/Command-Handling-the-Nancy-Way.aspx</id><published>2011-09-08T13:50:55Z</published><updated>2011-09-08T13:50:55Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/minibuss_small_thumb1_thumb_thumb_353836CC.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="minibuss_small_thumb1_thumb_thumb" border="0" alt="minibuss_small_thumb1_thumb_thumb" src="http://weblogs.asp.net/blogs/jdanforth/minibuss_small_thumb1_thumb_thumb_thumb_5FA467E9.png" width="36" height="28" /&gt;&lt;/a&gt; MiniBuss is a micro service bus framework over msmq which consists of less than 400 lines of code, sitting inside one single source file. The project is hosted over at &lt;a href="http://minibuss.codeplex.com"&gt;http://minibuss.codeplex.com&lt;/a&gt; and the source code is maintained at &lt;a title="https://github.com/johandanforth/MiniBuss" href="https://github.com/johandanforth/MiniBuss"&gt;https://github.com/johandanforth/MiniBuss&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’ve been a fan of &lt;a href="https://github.com/NancyFx/Nancy" target="_blank"&gt;the Sinatra inspired web framework called Nancy&lt;/a&gt;, especially the neat way of setting up handlers for routes. The simplest sample on their site is this:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Module : NancyModule
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; Module()
    {
        Get[&lt;span class="str"&gt;&amp;quot;/greet/{name}&amp;quot;&lt;/span&gt;] = x =&amp;gt; {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;.Concat(&lt;span class="str"&gt;&amp;quot;Hello &amp;quot;&lt;/span&gt;, x.name);
        };
    }
}&lt;/pre&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;So, I shamelessly dug into the Nancy code and borrowed some 20-30 lines of code and came up with something like this for registering handlers for certain incoming commands on the minibus, what do you think?&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; CommandHandler : MessageHandler
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; CommandHandler()
    {
        WhenReceiving[&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(SampleMessage1)] = x =&amp;gt;
        {
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;sample 1 message: &amp;quot;&lt;/span&gt; + x.Text);
        };

        WhenReceiving[&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(SampleMessage2)] = x =&amp;gt;
        {
            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;sample 2 message: &amp;quot;&lt;/span&gt; + x.Text);
        };
    }
}&lt;/pre&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;It’s a bit more code but it helps/enforces you to move the handlers off to a certain module. Thoughts?&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48776" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="Open Source" scheme="http://blog.irm.se/blogs/johan/archive/tags/Open+Source/default.aspx" /><category term="Service Bus" scheme="http://blog.irm.se/blogs/johan/archive/tags/Service+Bus/default.aspx" /><category term="MiniBuss" scheme="http://blog.irm.se/blogs/johan/archive/tags/MiniBuss/default.aspx" /></entry><entry><title>More MiniBuss Updates</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/09/02/More-MiniBuss-Updates.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/09/02/More-MiniBuss-Updates.aspx</id><published>2011-09-02T20:23:23Z</published><updated>2011-09-02T20:23:23Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/minibuss_small_thumb1_thumb_51B22E2D.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="minibuss_small_thumb1_thumb" border="0" alt="minibuss_small_thumb1_thumb" src="http://weblogs.asp.net/blogs/jdanforth/minibuss_small_thumb1_thumb_thumb_02D168CE.png" width="36" height="28" /&gt;&lt;/a&gt; MiniBuss is a micro service bus framework over msmq which consists of less than 400 lines of code, sitting inside one single source file. The project is hosted over at &lt;a href="http://minibuss.codeplex.com"&gt;http://minibuss.codeplex.com&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Thanks to @CodingInsomnia for testing out the MiniBuss stuff a bit more than I did &lt;img style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://weblogs.asp.net/blogs/jdanforth/wlEmoticon-winkingsmile_61DDF626.png" /&gt; For the samples, and for my initial testing code, I used a shared assembly with messages (events and commands), which shouldn’t be necessary. So I made a few simple changes and now you can choose to either share messages in an assembly between your sender/receiver and publisher/subscribers OR you can declare local message classes &lt;strong&gt;as long as those classes use the same class name and properties&lt;/strong&gt; it should work.&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;NuGet package has been updated&lt;/strong&gt;, and the new code is in package version 1.0.2.0.&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48775" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term=".NET" scheme="http://blog.irm.se/blogs/johan/archive/tags/.NET/default.aspx" /><category term="Open Source" scheme="http://blog.irm.se/blogs/johan/archive/tags/Open+Source/default.aspx" /><category term="Codeplex" scheme="http://blog.irm.se/blogs/johan/archive/tags/Codeplex/default.aspx" /><category term="Service Bus" scheme="http://blog.irm.se/blogs/johan/archive/tags/Service+Bus/default.aspx" /><category term="CQRS" scheme="http://blog.irm.se/blogs/johan/archive/tags/CQRS/default.aspx" /><category term="msmq" scheme="http://blog.irm.se/blogs/johan/archive/tags/msmq/default.aspx" /><category term="MiniBuss" scheme="http://blog.irm.se/blogs/johan/archive/tags/MiniBuss/default.aspx" /></entry><entry><title>MiniBuss Updates</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/09/01/MiniBuss-Updates.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/09/01/MiniBuss-Updates.aspx</id><published>2011-09-01T09:35:31Z</published><updated>2011-09-01T09:35:31Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/minibuss_small_thumb1_377C04CA.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="minibuss_small_thumb1" border="0" alt="minibuss_small_thumb1" src="http://weblogs.asp.net/blogs/jdanforth/minibuss_small_thumb1_thumb_61E835E7.png" width="36" height="28" /&gt;&lt;/a&gt; I made a small update to &lt;a href="http://minibuss.codeplex.com/" target="_blank"&gt;MiniBuss&lt;/a&gt;, the micro service bus framework. The messages you send, Commands and Events, are &lt;strong&gt;no longer dependent on IMessage&lt;/strong&gt;. The messages sent on the bus can now be any .NET class which can be safely serialized.&lt;/p&gt;  &lt;p&gt;The MiniBuss package on NuGet has been updated (version 1.1.0.1).&lt;/p&gt;  &lt;p&gt;I’m looking for testers, reviewers and co-authors. Areas I want to look more at are multithreading/concurrency and the reply-feature (especially being able to reply to current message in multithreaded scenarios. &lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48774" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="Open Source" scheme="http://blog.irm.se/blogs/johan/archive/tags/Open+Source/default.aspx" /><category term="Codeplex" scheme="http://blog.irm.se/blogs/johan/archive/tags/Codeplex/default.aspx" /><category term="Service Bus" scheme="http://blog.irm.se/blogs/johan/archive/tags/Service+Bus/default.aspx" /><category term="msmq" scheme="http://blog.irm.se/blogs/johan/archive/tags/msmq/default.aspx" /><category term="MiniBuss" scheme="http://blog.irm.se/blogs/johan/archive/tags/MiniBuss/default.aspx" /></entry><entry><title>MiniBuss on Codeplex</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/08/30/MiniBuss-on-Codeplex.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/08/30/MiniBuss-on-Codeplex.aspx</id><published>2011-08-30T11:48:17Z</published><updated>2011-08-30T11:48:17Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/minibuss_small_3A94372C.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="minibuss_small" border="0" alt="minibuss_small" src="http://weblogs.asp.net/blogs/jdanforth/minibuss_small_thumb_478E173D.png" width="36" height="28" /&gt;&lt;/a&gt; The micro service bus framework for msmq called MiniBuss is now open source on Codeplex at &lt;a href="http://minibuss.codeplex.com"&gt;http://minibuss.codeplex.com&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There is also now a NuGet package available for easy install into projects: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/image_06EBCACE.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/jdanforth/image_thumb_25C23EAC.png" width="644" height="364" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If you’re interested in co-op on this project, please contact me via Codeplex! I’m looking for devs and tester who knows their c#, msmq and concurrency.&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48772" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="c#" scheme="http://blog.irm.se/blogs/johan/archive/tags/c_2300_/default.aspx" /><category term="Open Source" scheme="http://blog.irm.se/blogs/johan/archive/tags/Open+Source/default.aspx" /><category term="Codeplex" scheme="http://blog.irm.se/blogs/johan/archive/tags/Codeplex/default.aspx" /><category term="Service Bus" scheme="http://blog.irm.se/blogs/johan/archive/tags/Service+Bus/default.aspx" /><category term="msmq" scheme="http://blog.irm.se/blogs/johan/archive/tags/msmq/default.aspx" /></entry><entry><title>A One File .NET Micro Service Bus for MSMQ?</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/08/19/A-One-File-.NET-Micro-Service-Bus-for-MSMQ_3F00_.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/08/19/A-One-File-.NET-Micro-Service-Bus-for-MSMQ_3F00_.aspx</id><published>2011-08-19T11:15:00Z</published><updated>2011-08-19T11:15:00Z</updated><content type="html">&lt;p&gt;This last year our company has invested quite some time in looking at CQRS, which led to looking at great looking service-buses like &lt;a href="http://www.nservicebus.com/" target="_blank"&gt;nServiceBus&lt;/a&gt;, &lt;a href="http://hibernatingrhinos.com/open-source/rhino-service-bus" target="_blank"&gt;Rhino Service Bus&lt;/a&gt; and &lt;a href="http://masstransit-project.com/" target="_blank"&gt;Mass Transit&lt;/a&gt;, which led me to do some bus-coding on my own, mostly for fun and for learning MSMQ.&lt;/p&gt;  &lt;p&gt;Inspired by the service buses mentioned above, the result became a bare-bones-one-file “micro service bus” that I call MiniBuss which sits on top of MSMQ. The file itself is only some 400 lines of code and supports send, receive, reply, publish and subscribe/unsubscribe.&lt;/p&gt;  &lt;p&gt;Setting up a &lt;strong&gt;sender&lt;/strong&gt; may look something like this:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7c91c1dd-8041-425f-a9d5-74f4974fb427" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bus = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MiniBuss.&lt;span style="color:#2b91af;"&gt;ServiceBus&lt;/span&gt;();&lt;br&gt; &lt;br&gt; bus.RegisterMessageEndpoint&amp;lt;&lt;span style="color:#2b91af;"&gt;HelloCommand&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_receiver1@johan-dell-ssd&amp;quot;&lt;/span&gt;);&lt;br&gt; &lt;br&gt; bus.Start();&lt;br&gt; &lt;br&gt; bus.Send(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HelloCommand&lt;/span&gt; { Guid = &lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;.NewGuid(), Message = &lt;span style="color:#a31515;"&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt; });&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Create the bus, register a message and tell it where messages of this type should go, start the bus and send the message.&lt;/p&gt;  &lt;p&gt;Setting up a &lt;strong&gt;receiver&lt;/strong&gt; may look something like this:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a8260128-689a-43e0-8fea-0ed31dbbd249" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bus = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ServiceBus&lt;/span&gt; { LocalEndpoint = &lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_receiver1&amp;quot;&lt;/span&gt; };&lt;br&gt; &lt;br&gt; bus.RegisterMessageHandler&amp;lt;&lt;span style="color:#2b91af;"&gt;HelloCommand&lt;/span&gt;&amp;gt;(command =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(command.Message + &lt;span style="color:#a31515;"&gt;&amp;quot; Guid: &amp;quot;&lt;/span&gt; + command.Guid));&lt;br&gt; &lt;br&gt; bus.Start();&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Create the bus and tell it which endpoint to listen to (which creates a local MSMQ queue if necessary) and tell it which message type to listen for and which delegate to kick off when such a message is received.&lt;/p&gt;  &lt;p&gt;Similarly, when doing a &lt;strong&gt;receive/reply&lt;/strong&gt;, you would have to create the bus on the sender side with a local endpoint and register a message-handler for replies, like this:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d63f6e83-aed9-4415-a01a-7ab8d97f3c4c" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bus = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MiniBuss.&lt;span style="color:#2b91af;"&gt;ServiceBus&lt;/span&gt; { LocalEndpoint = &lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_sender1&amp;quot;&lt;/span&gt; };&lt;br&gt; &lt;br&gt; bus.RegisterMessageEndpoint&amp;lt;&lt;span style="color:#2b91af;"&gt;HelloCommand&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_receiver1@johan-dell-ssd&amp;quot;&lt;/span&gt;);&lt;br&gt; &lt;br&gt; bus.RegisterMessageHandler&amp;lt;&lt;span style="color:#2b91af;"&gt;HelloResponse&lt;/span&gt;&amp;gt;(reply =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Reply from receiver: &amp;quot;&lt;/span&gt; + reply.Message));&lt;br&gt; &lt;br&gt; bus.Start();&lt;br&gt; &lt;br&gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Sending command...&amp;quot;&lt;/span&gt;);&lt;br&gt; bus.Send(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HelloCommand&lt;/span&gt; { Guid = &lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;.NewGuid(), Message = &lt;span style="color:#a31515;"&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt; });&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;The receiver would do a bus.reply() like this:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e2609164-3adf-4752-8d4f-d7aa51446180" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bus = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ServiceBus&lt;/span&gt; { LocalEndpoint = &lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_receiver1&amp;quot;&lt;/span&gt; };&lt;br&gt; &lt;br&gt; bus.RegisterMessageHandler&amp;lt;&lt;span style="color:#2b91af;"&gt;HelloCommand&lt;/span&gt;&amp;gt;(command =&amp;gt;&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(command.Message + &lt;span style="color:#a31515;"&gt;&amp;quot; Guid: &amp;quot;&lt;/span&gt; + command.Guid);&lt;br&gt; &lt;br&gt;     bus.Reply(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HelloResponse&lt;/span&gt; { Guid = &lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;.NewGuid(), Message = &lt;span style="color:#a31515;"&gt;&amp;quot;Hello back!&amp;quot;&lt;/span&gt; });&lt;br&gt; });&lt;br&gt; &lt;br&gt; bus.Start();&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;The MiniBus also supports &lt;strong&gt;publish&lt;/strong&gt; to multiple subscribers. A simple publisher would create a bus with a local endpoint (to receive subscribe/unsubscribe commands), tell it to handle subscriptions for a certain event, then start publishing something every 5 seconds (as an example):&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8e2c90a7-7645-4d2a-a34d-8a850245d8a5" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bus = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MiniBuss.&lt;span style="color:#2b91af;"&gt;ServiceBus&lt;/span&gt; { LocalEndpoint = &lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_publisher1&amp;quot;&lt;/span&gt; };&lt;br&gt; &lt;br&gt; bus.HandleSubscriptionsFor&amp;lt;&lt;span style="color:#2b91af;"&gt;SomethingHappenedEvent&lt;/span&gt;&amp;gt;();&lt;br&gt; &lt;br&gt; bus.Start();    &lt;br&gt; &lt;br&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; PublishingThread(bus), &lt;span style="color:#2b91af;"&gt;TaskCreationOptions&lt;/span&gt;.LongRunning);&lt;br&gt; &lt;br&gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Done, press ENTER to exit&amp;quot;&lt;/span&gt;);&lt;br&gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;              &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:85028e28-2d61-410b-aad4-3802770c2117" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; PublishingThread(MiniBuss.&lt;span style="color:#2b91af;"&gt;ServiceBus&lt;/span&gt; bus)&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)&lt;br&gt;     {&lt;br&gt;         &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(5000);&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; guid = &lt;span style="color:#2b91af;"&gt;Guid&lt;/span&gt;.NewGuid();&lt;br&gt;         &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Publishing event with guid &amp;quot;&lt;/span&gt; + guid);&lt;br&gt;         bus.Publish(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SomethingHappenedEvent&lt;/span&gt;() { Guid = guid, Sent = &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now });&lt;br&gt;     }&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Any clients interesting in &lt;strong&gt;subscribing&lt;/strong&gt; to events from the publisher would create a bus with a local endpoint, start the bus and then send a subscribe command to the publisher, telling it you’re interested in subscribing to a certain type of event and which delegate to handle it:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d8be7b59-5742-4b54-a002-bddbc79dc7e2" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bus = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MiniBuss.&lt;span style="color:#2b91af;"&gt;ServiceBus&lt;/span&gt; {LocalEndpoint = &lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_subscriber1&amp;quot;}&lt;/span&gt;;&lt;br&gt; &lt;br&gt; bus.Start();&lt;br&gt; &lt;br&gt; bus.Subscribe&amp;lt;&lt;span style="color:#2b91af;"&gt;SomethingHappenedEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_publisher1@localhost&amp;quot;&lt;/span&gt;, &lt;br&gt;     @event =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;something happened at {&lt;/span&gt;&lt;span style="color:#3cb371;"&gt;0}&lt;/span&gt;&lt;span style="color:#a31515;"&gt;, event id {&lt;/span&gt;&lt;span style="color:#3cb371;"&gt;1}&lt;/span&gt;&lt;span style="color:#a31515;"&gt;&amp;quot;&lt;/span&gt;,&lt;br&gt;         @event.Sent, @event.Guid));&lt;br&gt; &lt;br&gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Waiting for events, press ENTER to exit&amp;quot;&lt;/span&gt;);&lt;br&gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();&lt;br&gt; &lt;br&gt; bus.UnSubscribe&amp;lt;&lt;span style="color:#2b91af;"&gt;SomethingHappenedEvent&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;minibuss_publisher1&amp;quot;&lt;/span&gt;);&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&lt;strong&gt;Now, the question is, what do you think?&lt;/strong&gt; I &lt;em&gt;know&lt;/em&gt; there are issues with the code, like how to make message-handlers multi-threaded/concurrent without messing things up (it’s single threaded right now), and how to best handle exceptions, rollbacks and re-tries . Right now handling exceptions in send and receive works pretty well within a TransactionScope() together with ADO.NET, and if there’s an exception, the message is moved the an error-queue. No re-try or anything, only rollback and move to xxx_error. Also, the publisher doesn’t persist subscriptions, so if it is restarted subscribers wouldn’t know. You know, things like that.&lt;/p&gt;  &lt;p&gt;I’m a user of the micro-orm called &lt;a href="http://code.google.com/p/dapper-dot-net/" target="_blank"&gt;Dapper&lt;/a&gt; and like it a lot, so I’m thinking that maybe I should release this micro-bus as open source and see where people may take it, if anywhere? Maybe just down the drain because they figure out this service bus is dangerous to use and risk loosing messages or something (which would be extremely good to know :)&lt;/p&gt;  &lt;p&gt;Or maybe this code is useless because you already got nServiceBus and Rhino out there and coders don’t need another service bus?&lt;/p&gt;  &lt;p&gt;What do you say?&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48769" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term=".NET" scheme="http://blog.irm.se/blogs/johan/archive/tags/.NET/default.aspx" /><category term="Open Source" scheme="http://blog.irm.se/blogs/johan/archive/tags/Open+Source/default.aspx" /><category term="Service Bus" scheme="http://blog.irm.se/blogs/johan/archive/tags/Service+Bus/default.aspx" /><category term="CQRS" scheme="http://blog.irm.se/blogs/johan/archive/tags/CQRS/default.aspx" /></entry><entry><title>Pomodoro Timer for the Windows 7 TaskBar</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/08/16/Pomodoro-Timer-for-the-Windows-7-TaskBar.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/08/16/Pomodoro-Timer-for-the-Windows-7-TaskBar.aspx</id><published>2011-08-16T11:08:00Z</published><updated>2011-08-16T11:08:00Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;EDIT:&amp;nbsp; The code is now open source on codeplex, on &lt;a href="http://pomodorotaskbar.codeplex.com" target="_blank"&gt;http://pomodorotaskbar.codeplex.com &lt;/a&gt;There's a new version available&amp;nbsp;for download there too.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If you’re into &lt;a href="http://www.pomodorotechnique.com/" target="_blank"&gt;the Pomodoro technique&lt;/a&gt; and looking for a pretty simple out-of-the-way timer which sits in the Windows 7 taskbar and is controlled from the Win7 JumpList, this one might be worth trying out. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;NOTE: Icon overlays will NOT work if you're using small TaskBar icons!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/image_69FABFDE.png"&gt;&lt;img style="border-width:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/jdanforth/image_thumb_0F180A4B.png" width="334" height="43"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That’s the timer looking like a tomato, with the remaining session minutes written out dynamically as icon overlay.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/image_34A187AC.png"&gt;&lt;img style="border-width:0px;margin:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/jdanforth/image_thumb_3E1A4622.png" width="244" height="192"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The timer has a couple of JumpList Tasks which you can use to control it. The program works well when “pinned” to the taskbar if you prefer it.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/image_63A3C383.png"&gt;&lt;img style="border-width:0px;margin:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/jdanforth/image_thumb_5420B1B4.png" width="244" height="164"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can also control the timer from the main window with one large action-button (stop, start, stop ringing and restart session).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/image_12A5FF5B.png"&gt;&lt;img style="border-width:0px;margin:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/jdanforth/image_thumb_0CEAE5B5.png" width="244" height="164"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When the timer is stopped, you can just click on the remaining minutes-textbox and change the default session length to whatever you like. The value is stored.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/image_1D82E0A3.png"&gt;&lt;img style="border-width:0px;margin:0px;padding-top:0px;padding-right:0px;padding-left:0px;display:inline;background-image:none;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/jdanforth/image_thumb_7503FE8E.png" width="244" height="51"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When the session is ended, the window flashes, the tomato shakes and a ringing sound is played a few times to get your attention. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;, this is a very simple program which I’m planning to release as open source when I’ve received some feedback. I prefer to keep it simple, but may add session logging. The name as well as the looks may change. .NET 4.0 is required.&lt;/p&gt;  &lt;div style="margin:0px;padding:0px;float:none;display:inline;" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:894107a9-6eca-4992-92a8-652e78cd280a" class="wlWriterEditableSmartContent"&gt;&lt;p&gt;Download the Pomodoro Timer: &lt;a href="http://pomodorotaskbar.codeplex.com/releases/view/71998"&gt;http://pomodorotaskbar.codeplex.com/releases/view/71998&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48768" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="Windows 7" scheme="http://blog.irm.se/blogs/johan/archive/tags/Windows+7/default.aspx" /><category term="Open Source" scheme="http://blog.irm.se/blogs/johan/archive/tags/Open+Source/default.aspx" /><category term=".NET 4.0" scheme="http://blog.irm.se/blogs/johan/archive/tags/.NET+4.0/default.aspx" /><category term="Pomodoro" scheme="http://blog.irm.se/blogs/johan/archive/tags/Pomodoro/default.aspx" /></entry><entry><title>Create Tag-Cloud from RSS Feed in ASP.NET MVC</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/08/08/Create-Tag_2D00_Cloud-from-RSS-Feed-in-ASP.NET-MVC.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/08/08/Create-Tag_2D00_Cloud-from-RSS-Feed-in-ASP.NET-MVC.aspx</id><published>2011-08-08T11:40:12Z</published><updated>2011-08-08T11:40:12Z</updated><content type="html">&lt;p&gt;Say you want to generate your own tag-cloud from a list of categories or tags you pull from an RSS-feed or similar. This is one way to do it. I’m using ASP.NET MVC for this sample which creates a simple tag-cloud in a Razor-view with HTML looking something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/image_0507121F.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/jdanforth/image_thumb_3CD95642.png" width="436" height="239" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The controller-code to start out with looks like this, where you read in the RSS-feed into a &lt;strong&gt;SyndicationFeed&lt;/strong&gt; class, then pull out and flatten all the categories you have in that feed. Then group all those categories and count them to build up this simple view-model which is a Dictionary of category and percentage:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e018791a-8bdf-4fb2-8e96-7476fe3d5b1d" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;HomeController&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Controller&lt;/span&gt;&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ActionResult&lt;/span&gt; Index()&lt;br&gt;     {&lt;br&gt;         &lt;span style="color:#008000;"&gt;//get feed&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; feed = &lt;span style="color:#2b91af;"&gt;SyndicationFeed&lt;/span&gt;.Load(&lt;span style="color:#2b91af;"&gt;XmlReader&lt;/span&gt;.Create(&lt;span style="color:#a31515;"&gt;&amp;quot;http://blog.irm.se/blogs/MainFeed.aspx&amp;quot;&lt;/span&gt;));&lt;br&gt; &lt;br&gt;         &lt;span style="color:#008000;"&gt;//get flat list of all categories/tags in the feed&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; categoriesList = feed.Items.SelectMany(item =&amp;gt; item.Categories).Select(category =&amp;gt; category.Name);&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; categoryGroups = categoriesList.GroupBy(category =&amp;gt; category);&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt; maxNrOfACategory = categoryGroups.Max(w =&amp;gt; w.Count());&lt;br&gt; &lt;br&gt;         &lt;span style="color:#008000;"&gt;//build a dictionary with category/percentage of all categories&lt;/span&gt;&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; tagCloudDictionary = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;();&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; tag &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; categoryGroups)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; percent = (tag.Count() / maxNrOfACategory) * 100;&lt;br&gt;             tagCloudDictionary.Add(tag.Key, (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;)percent);&lt;br&gt;         }&lt;br&gt; &lt;br&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; View(tagCloudDictionary);&lt;br&gt;     }&lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt; 
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }  &lt;p&gt;So now we got this view-model which is a &lt;strong&gt;Dictionary&amp;lt;string,int&amp;gt;&lt;/strong&gt; and contains category/percentage data like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/image_62CF0698.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/jdanforth/image_thumb_21C08734.png" width="251" height="328" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So all we need to do is create some kind of cloud in HTML or similar in the view. One way of doing it is this, which creates the output shown at the top:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5be2cc55-9b3d-4844-ac07-c8de04ab8194" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;"&gt;&lt;span style="background:#ffff00;"&gt;@model &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;&lt;br&gt; &lt;br&gt; &lt;span style="background:#ffff00;"&gt;@{&lt;/span&gt;&lt;br&gt;     ViewBag.Title = &lt;span style="color:#a31515;"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;;&lt;br&gt; }&lt;br&gt; &lt;br&gt; &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;h2&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Tag cloud&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;h2&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt; &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;width&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;: 400px; &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;font-size&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;: 25px;&amp;quot;&amp;gt;&lt;/span&gt;&lt;br&gt;     &lt;span style="background:#ffff00;"&gt;@&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; tag &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; Model)&lt;br&gt;     {&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;font-size: &lt;/span&gt;&lt;span style="background:#ffff00;"&gt;@(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;tag.Value / 2 + 50&lt;/span&gt;&lt;span style="background:#ffff00;"&gt;)&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;%; &amp;quot;&amp;gt;&lt;/span&gt;&lt;br&gt;         &lt;span style="background:#ffff00;"&gt;@&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (tag.Value &amp;gt; 10)&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;style&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot; &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;font-weight&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;: bold;&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="background:#ffff00;"&gt;@&lt;/span&gt;tag.Key &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;         }&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;br&gt;         {&lt;br&gt;             &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background:#ffff00;"&gt;@&lt;/span&gt;tag.Key &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;         }&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;span&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;     }&lt;br&gt; &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;div&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Obviously, to be able to click on a tag and so on you need to create a richer view-model, I just wanted to show how I grab and count the tags from the feed &lt;img style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://weblogs.asp.net/blogs/jdanforth/wlEmoticon-smile_79ADD814.png" /&gt;&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48763" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="ASP.NET MVC" scheme="http://blog.irm.se/blogs/johan/archive/tags/ASP.NET+MVC/default.aspx" /><category term="LINQ" scheme="http://blog.irm.se/blogs/johan/archive/tags/LINQ/default.aspx" /><category term="c#" scheme="http://blog.irm.se/blogs/johan/archive/tags/c_2300_/default.aspx" /></entry><entry><title>Never, never, never do Office interop on the server</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/05/15/Never_2C00_-never_2C00_-never-do-Office-interop-on-the-server.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/05/15/Never_2C00_-never_2C00_-never-do-Office-interop-on-the-server.aspx</id><published>2011-05-15T17:14:37Z</published><updated>2011-05-15T17:14:37Z</updated><content type="html">&lt;p&gt;I’ve been telling people this for years and years, and still I stepped right into the mudhole a month ago. I blame stress, but still I shouldn’t have. It’s so easy to just add the interop assemblies and off you go… until you try running your stuff on the 2008 r2 server, hosted somewhere else, with just enough user rights. And even though I managed to get the !”#!¤¤”% working after a while, I got mem-leaks and follow-up probs due to the workarounds I had to do to get the interop working in the first place.&lt;/p&gt;  &lt;p&gt;Then I sat down and relaxed for a minute and realized I need to do this the right way, which is the OpenXML way.&lt;/p&gt;  &lt;p&gt;The thing is, OpenXML is – compared to Office-interop - not easy, and the Microsoft OpenXML SDK 2.0 is just lipstick on top of the XML and some things which were so easy to do with the interop assemblies gives you nightmares to do with OpenXML. Try fill in formsfields in a protected word document for example. I ditched the SDK and ended up doing it directly against the XML directly instead.&lt;/p&gt;  &lt;p&gt;I also had to fill out a few Excel spreadsheets with data, which was somewhat easier to handle than the Word-story above. But I ran into problems here too, because I wanted to do such a simple thing as setting text wrap on a few cells! I don’t know, but I’m sure Microsoft could have done something better for us poor developers that need to create docs on the server! Are we supposed to spend 40% of the coding time to just create a few simple docs, just because we go the OpenXML way? There are a quite a few pages on MSDN with samples, as well as code snippets to download, but as soon as you need to do something outside the “demo-path” you’re banging your head. Maybe I’m just stupid and doesn’t get it, or maybe I’m getting grumpy, because OpenXML is not a developer-friendly framework! There, feels much better now…&lt;/p&gt;  &lt;p&gt;Now, for Excel spreadsheets there’s good hope because you got more than a few decent packages out there to help you out, and &lt;strong&gt;the best one I’ve found so far is called &lt;/strong&gt;&lt;a href="http://closedxml.codeplex.com/" target="_blank"&gt;&lt;strong&gt;ClosedXML on Codeplex&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt; It’s free and it did everything I needed to do right out of the box! It took me 5 minutes to create the 2 different spreadsheets I needed for my project, including cell formatting, text wrapping and so on. &lt;strong&gt;Cheers to MDeLeon for doing this!&lt;/strong&gt;&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48751" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="Office" scheme="http://blog.irm.se/blogs/johan/archive/tags/Office/default.aspx" /><category term="Interop" scheme="http://blog.irm.se/blogs/johan/archive/tags/Interop/default.aspx" /><category term="OpenXML" scheme="http://blog.irm.se/blogs/johan/archive/tags/OpenXML/default.aspx" /><category term="Codeplex" scheme="http://blog.irm.se/blogs/johan/archive/tags/Codeplex/default.aspx" /></entry><entry><title>Refactored Dapper Extensions</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/05/11/Refactored-Dapper-Extensions.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/05/11/Refactored-Dapper-Extensions.aspx</id><published>2011-05-10T22:48:29Z</published><updated>2011-05-10T22:48:29Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/jdanforth/archive/2011/05/10/simple-insert-extension-for-dapper.aspx" target="_blank"&gt;Making extensions for Dapper-dot-net&lt;/a&gt; was so fun and I needed a few more simple ones so I refactored a bit and made a few Update() and Delete() extensions as well. I’m also looking for Id-properties with the [Key] attribute on them. The class grew a bit, but it now supports the functions below. Note that this will only work for very simple objects and tables, but it might be helpful for some of you &lt;img style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://weblogs.asp.net/blogs/jdanforth/wlEmoticon-smile_74B2939D.png"&gt;&lt;/p&gt; &lt;p&gt;I’m trying to follow the overall Dapper syntax as much as I can. If you done specify the table name with the input parameter, I’m using the name of the class/entity as table name, except where anonymous types are used.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The object I’m using for testing&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test
    {
        [Key]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Id { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }
    }
&lt;/pre&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }


&lt;p&gt;&lt;strong&gt;Insert typed object&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;                var entity = &lt;span class="kwrd"&gt;new&lt;/span&gt; Test() { Name = &lt;span class="str"&gt;"Johan"&lt;/span&gt;, Age = 44 };
                connection.Insert(entity);
&lt;/pre&gt;
&lt;p&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Insert anonymous object&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;                connection.Insert(&lt;span class="str"&gt;"insert into test"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; { Name = &lt;span class="str"&gt;"Johan"&lt;/span&gt;, Age = 20 });
&lt;/pre&gt;
&lt;p&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update typed object&lt;/strong&gt; (where-clause built up from Id-properties)&lt;/p&gt;&lt;pre class="csharpcode"&gt;                var entity = &lt;span class="kwrd"&gt;new&lt;/span&gt; Test() { Id = 16, Name = &lt;span class="str"&gt;"Johan"&lt;/span&gt;, Age = 50 };
                connection.Update(entity);
&lt;/pre&gt;
&lt;p&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Delete typed object&lt;/strong&gt; (where-clause built up from Id-properties)&lt;/p&gt;&lt;pre class="csharpcode"&gt;                var entity = &lt;span class="kwrd"&gt;new&lt;/span&gt; Test() { Id = 4, Name = &lt;span class="str"&gt;"Johan"&lt;/span&gt;, Age = 44 };
                var deletedCount = connection.Delete(entity);
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Delete anonymous object&lt;/strong&gt; (where-clause built up from anonymous object)&lt;/p&gt;&lt;pre class="csharpcode"&gt;                var deletedCount = connection.Delete(&lt;span class="str"&gt;"delete from test"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; { Name = &lt;span class="str"&gt;"Johan"&lt;/span&gt; });
&lt;/pre&gt;
&lt;h4&gt;The Code:&lt;/h4&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DapperExtensions
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDbConnection connection, &lt;span class="kwrd"&gt;object&lt;/span&gt; entityToInsert)
    {
        Insert(connection, &lt;span class="kwrd"&gt;null&lt;/span&gt;, entityToInsert);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDbConnection connection, &lt;span class="kwrd"&gt;string&lt;/span&gt; sql, &lt;span class="kwrd"&gt;object&lt;/span&gt; entityToInsert)
    {
        var name = entityToInsert.GetType().Name;
        var sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder(sql);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (sql == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            sb.AppendFormat(&lt;span class="str"&gt;"insert into {0}"&lt;/span&gt;, name);
        sb.Append(&lt;span class="str"&gt;" ("&lt;/span&gt;);
        BuildInsertParameters(entityToInsert, sb);
        sb.Append(&lt;span class="str"&gt;") values ("&lt;/span&gt;);
        BuildInsertValues(entityToInsert, sb);
        sb.Append(&lt;span class="str"&gt;")"&lt;/span&gt;);
        connection.Execute(sb.ToString(), entityToInsert);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Update(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDbConnection connection, &lt;span class="kwrd"&gt;object&lt;/span&gt; entityToUpdate)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; Update(connection, &lt;span class="kwrd"&gt;null&lt;/span&gt;, entityToUpdate);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Update(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDbConnection connection, &lt;span class="kwrd"&gt;string&lt;/span&gt; sql, &lt;span class="kwrd"&gt;object&lt;/span&gt; entityToUpdate)
    {
        var idProps = GetIdProperties(entityToUpdate);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (idProps.Count() == 0)
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentException(&lt;span class="str"&gt;"Entity must have at least one [Key] property"&lt;/span&gt;);

        var name = entityToUpdate.GetType().Name;

        var sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder(sql);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (sql == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            sb.AppendFormat(&lt;span class="str"&gt;"update {0}"&lt;/span&gt;, name);

        sb.AppendFormat(&lt;span class="str"&gt;" set "&lt;/span&gt;);
        BuildUpdateSet(entityToUpdate, sb);
        sb.Append(&lt;span class="str"&gt;" where "&lt;/span&gt;);
        BuildWhere(sb, idProps.ToArray());

        &lt;span class="kwrd"&gt;return&lt;/span&gt; connection.Execute(sb.ToString(), entityToUpdate);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Delete&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDbConnection connection, T entityToDelete)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; Delete(connection, &lt;span class="kwrd"&gt;null&lt;/span&gt;, entityToDelete);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Delete&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDbConnection connection, &lt;span class="kwrd"&gt;string&lt;/span&gt; sql, T entityToDelete)
    {
        var idProps = &lt;span class="kwrd"&gt;typeof&lt;/span&gt; (T).IsAnonymousType() ? 
            GetAllProperties(entityToDelete) : 
            GetIdProperties(entityToDelete);

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (idProps.Count() == 0)
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentException(&lt;span class="str"&gt;"Entity must have at least one [Key] property"&lt;/span&gt;);

        var name = entityToDelete.GetType().Name;

        var sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder(sql);
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (sql == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            sb.AppendFormat(&lt;span class="str"&gt;"delete from {0}"&lt;/span&gt;, name);

        sb.Append(&lt;span class="str"&gt;" where "&lt;/span&gt;);
        BuildWhere(sb, idProps);

        &lt;span class="kwrd"&gt;return&lt;/span&gt; connection.Execute(sb.ToString(), entityToDelete);
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; BuildUpdateSet(&lt;span class="kwrd"&gt;object&lt;/span&gt; entityToUpdate, StringBuilder sb)
    {
        var nonIdProps = GetNonIdProperties(entityToUpdate).ToArray();

        &lt;span class="kwrd"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; nonIdProps.Length; i++)
        {
            var property = nonIdProps&lt;img src="http://blog.irm.se/emoticons/emotion-55.gif" alt="Idea" /&gt;;

            sb.AppendFormat(&lt;span class="str"&gt;"{0} = @{1}"&lt;/span&gt;, property.Name, property.Name);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (i &amp;lt; nonIdProps.Length - 1)
                sb.AppendFormat(&lt;span class="str"&gt;", "&lt;/span&gt;);
        }
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; BuildWhere(StringBuilder sb, IEnumerable&amp;lt;PropertyInfo&amp;gt; idProps)
    {
        &lt;span class="kwrd"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; idProps.Count(); i++)
        {
            sb.AppendFormat(&lt;span class="str"&gt;"{0} = @{1}"&lt;/span&gt;, idProps.ElementAt(i).Name, idProps.ElementAt(i).Name);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (i &amp;lt; idProps.Count() - 1)
                sb.AppendFormat(&lt;span class="str"&gt;" and "&lt;/span&gt;);
        }
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; BuildInsertValues(&lt;span class="kwrd"&gt;object&lt;/span&gt; entityToInsert, StringBuilder sb)
    {
        var props = GetAllProperties(entityToInsert);

        &lt;span class="kwrd"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; props.Count(); i++)
        {
            var property = props.ElementAt(i);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (property.GetCustomAttributes(&lt;span class="kwrd"&gt;true&lt;/span&gt;).Where(a =&amp;gt; a &lt;span class="kwrd"&gt;is&lt;/span&gt; KeyAttribute).Any()) &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
            sb.AppendFormat(&lt;span class="str"&gt;"@{0}"&lt;/span&gt;, property.Name);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (i &amp;lt; props.Count() - 1)
                sb.Append(&lt;span class="str"&gt;", "&lt;/span&gt;);
        }
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; BuildInsertParameters(&lt;span class="kwrd"&gt;object&lt;/span&gt; entityToInsert, StringBuilder sb)
    {
        var props = GetAllProperties(entityToInsert);

        &lt;span class="kwrd"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; props.Count(); i++)
        {
            var property = props.ElementAt(i);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (property.GetCustomAttributes(&lt;span class="kwrd"&gt;true&lt;/span&gt;).Where(a =&amp;gt; a &lt;span class="kwrd"&gt;is&lt;/span&gt; KeyAttribute).Any()) &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
            sb.Append(property.Name);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (i &amp;lt; props.Count() - 1)
                sb.Append(&lt;span class="str"&gt;", "&lt;/span&gt;);
        }
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;PropertyInfo&amp;gt; GetAllProperties(&lt;span class="kwrd"&gt;object&lt;/span&gt; entity)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; entity.GetType().GetProperties();
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;PropertyInfo&amp;gt; GetNonIdProperties(&lt;span class="kwrd"&gt;object&lt;/span&gt; entity)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; GetAllProperties(entity).Where(p =&amp;gt; p.GetCustomAttributes(&lt;span class="kwrd"&gt;true&lt;/span&gt;).Any(a =&amp;gt; a &lt;span class="kwrd"&gt;is&lt;/span&gt; KeyAttribute) == &lt;span class="kwrd"&gt;false&lt;/span&gt;);
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;PropertyInfo&amp;gt; GetIdProperties(&lt;span class="kwrd"&gt;object&lt;/span&gt; entity)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; GetAllProperties(entity).Where( p =&amp;gt; p.GetCustomAttributes(&lt;span class="kwrd"&gt;true&lt;/span&gt;).Any(a =&amp;gt; a &lt;span class="kwrd"&gt;is&lt;/span&gt; KeyAttribute));
    }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TypeExtension
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Boolean IsAnonymousType(&lt;span class="kwrd"&gt;this&lt;/span&gt; Type type)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (type == &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;

        var hasCompilerGeneratedAttribute = type.GetCustomAttributes(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(CompilerGeneratedAttribute), &lt;span class="kwrd"&gt;false&lt;/span&gt;).Count() &amp;gt; 0;
        var nameContainsAnonymousType = type.FullName.Contains(&lt;span class="str"&gt;"AnonymousType"&lt;/span&gt;);
        var isAnonymousType = hasCompilerGeneratedAttribute &amp;amp;&amp;amp; nameContainsAnonymousType;

        &lt;span class="kwrd"&gt;return&lt;/span&gt; isAnonymousType;
    }
}
&lt;/pre&gt;&lt;pre class="csharpcode"&gt;Feel free to fork the code as much as you can, I’m too tired to stay up longer. &lt;a href="http://code.google.com/p/dapper-dot-net/" target="_blank"&gt;Dapper&lt;/a&gt; is getting really useful &lt;img style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://weblogs.asp.net/blogs/jdanforth/wlEmoticon-smile_74B2939D.png"&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48750" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="c#" scheme="http://blog.irm.se/blogs/johan/archive/tags/c_2300_/default.aspx" /><category term=".NET 4.0" scheme="http://blog.irm.se/blogs/johan/archive/tags/.NET+4.0/default.aspx" /></entry><entry><title>Simple Insert Extension for Dapper</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/05/10/Simple-Insert-Extension-for-Dapper.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/05/10/Simple-Insert-Extension-for-Dapper.aspx</id><published>2011-05-10T17:20:20Z</published><updated>2011-05-10T17:20:20Z</updated><content type="html">&lt;p&gt;Last week I started using Dapper (&lt;a href="http://code.google.com/p/dapper-dot-net/" target="_blank"&gt;dapper-dot-net on Google Code&lt;/a&gt;) for a project I’m working on. Dapper is a micro ORM, which extends IDbConnection. It’s very fast and works very well for queries where you want to return both typed and dynamic lists of objects. Have a quick look at the webpage and you’ll see what I mean.&lt;/p&gt;  &lt;p&gt;Today I needed to do some inserting, which you can do with the Execute() extension, but you’d have to type out all the “insert into xxx (col1,col2) values (@val1, @val2)” stuff. Some guys suggested to create a dapper.contrib and adding extensions of insert, update, delete and so on but it’s not there yet (at time of writing).&lt;/p&gt;  &lt;p&gt;Anyway, the extensions in dapper are already so well written I thought it should be quite easy to just add a dead simple (or stupid if you prefer) Insert() extensions on top of the existing Execute(), and I ended up with this raw unrefactored code. All it does really is building up the SQL for the insert using some property reflection, dapper itself does the heavy lifting:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DapperExtensions
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Insert(&lt;span class="kwrd"&gt;this&lt;/span&gt; IDbConnection connection, &lt;br /&gt;                              &lt;span class="kwrd"&gt;object&lt;/span&gt; entityToInsert, &lt;span class="kwrd"&gt;string&lt;/span&gt; sql = &lt;span class="str"&gt;&amp;quot;insert into &amp;quot;&lt;/span&gt; )
    {
        var name = entityToInsert.GetType().Name;

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (sql == &lt;span class="str"&gt;&amp;quot;insert into &amp;quot;&lt;/span&gt;)
        {
            sql = &lt;span class="str"&gt;&amp;quot;insert into &amp;quot;&lt;/span&gt; + name + &lt;span class="str"&gt;&amp;quot; &amp;quot;&lt;/span&gt;;
        }
        sql += &lt;span class="str"&gt;&amp;quot; (&amp;quot;&lt;/span&gt;;
        &lt;span class="kwrd"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; entityToInsert.GetType().GetProperties().Length; i++)
        {
            var propertyInfo = entityToInsert.GetType().GetProperties()&lt;img src="http://blog.irm.se/emoticons/emotion-55.gif" alt="Idea" /&gt;;
            sql += propertyInfo.Name;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (i &amp;lt; entityToInsert.GetType().GetProperties().Length - 1)
                sql += &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;;
        }
        sql += &lt;span class="str"&gt;&amp;quot;) values (&amp;quot;&lt;/span&gt;;
        &lt;span class="kwrd"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; entityToInsert.GetType().GetProperties().Length; i++)
        {
            var propertyInfo = entityToInsert.GetType().GetProperties()&lt;img src="http://blog.irm.se/emoticons/emotion-55.gif" alt="Idea" /&gt;;
            sql += &lt;span class="str"&gt;&amp;quot;@&amp;quot;&lt;/span&gt; + propertyInfo.Name;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (i &amp;lt; entityToInsert.GetType().GetProperties().Length - 1)
                sql += &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;;
        }
        sql += &lt;span class="str"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;;
        connection.Execute(sql, entityToInsert);
    }
}&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;I’m using it like this with a type:&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (var connection = &lt;span class="kwrd"&gt;new&lt;/span&gt; SqlConnection(connectionString))
{
    connection.Open();
    var entity = &lt;span class="kwrd"&gt;new&lt;/span&gt; Test() { Name = &lt;span class="str"&gt;&amp;quot;Johan&amp;quot;&lt;/span&gt;, Age = 43 };
    connection.Insert(entity);
}&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }
}&lt;/pre&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;…or like this with an anonymous type:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (var connection = &lt;span class="kwrd"&gt;new&lt;/span&gt; SqlConnection(connectionString))
{
    connection.Open();
    connection.Insert(&lt;span class="kwrd"&gt;new&lt;/span&gt; { Name = &lt;span class="str"&gt;&amp;quot;Johan&amp;quot;&lt;/span&gt;, Age = 43 }, &lt;span class="str"&gt;&amp;quot;insert into test&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;p&gt;Works for me ™ &lt;img style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://weblogs.asp.net/blogs/jdanforth/wlEmoticon-winkingsmile_63BA8282.png" /&gt;&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48749" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="c#" scheme="http://blog.irm.se/blogs/johan/archive/tags/c_2300_/default.aspx" /><category term=".NET 4.0" scheme="http://blog.irm.se/blogs/johan/archive/tags/.NET+4.0/default.aspx" /></entry><entry><title>Detecting Idle Time with Global Mouse and Keyboard Hooks in WPF</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2011/03/19/Detecting-Idle-Time-with-Global-Mouse-and-Keyboard-Hooks-in-WPF.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2011/03/19/Detecting-Idle-Time-with-Global-Mouse-and-Keyboard-Hooks-in-WPF.aspx</id><published>2011-03-19T11:29:47Z</published><updated>2011-03-19T11:29:47Z</updated><content type="html">&lt;p&gt;Years and years ago I wrote &lt;a href="http://weblogs.asp.net/jdanforth/archive/2006/06/21/454219.aspx" target="_blank"&gt;this blog post about detecting if the user was idle or active at the keyboard (and mouse)&lt;/a&gt; using a global hook. Well that code was for .NET 2.0 and Windows Forms and for some reason I wanted to try the same in WPF and noticed that a few things around the keyboard and mouse hooks didn’t work as expected in the WPF environment. So I had to change a few things and here’s the code for it, working in .NET 4.&lt;/p&gt;  &lt;p&gt;I took the liberty and refactored a few things while at it and here’s the code now. I’m sure I will need it in the far future as well.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;using &lt;/span&gt;System;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Diagnostics;
&lt;span style="color:blue;"&gt;using &lt;/span&gt;System.Runtime.InteropServices;

&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;Irm.Tim.Snapper.Util
{
    &lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ClientIdleHandler &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IDisposable
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;IsActive { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

        &lt;span style="color:blue;"&gt;int &lt;/span&gt;_hHookKbd;
        &lt;span style="color:blue;"&gt;int &lt;/span&gt;_hHookMouse;

        &lt;span style="color:blue;"&gt;public delegate int &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HookProc&lt;/span&gt;(&lt;span style="color:blue;"&gt;int &lt;/span&gt;nCode, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;wParam, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;lParam);
        &lt;span style="color:blue;"&gt;public event &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HookProc &lt;/span&gt;MouseHookProcedure;
        &lt;span style="color:blue;"&gt;public event &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HookProc &lt;/span&gt;KbdHookProcedure;

        &lt;span style="color:green;"&gt;//Use this function to install thread-specific hook.
        &lt;/span&gt;[&lt;span style="color:#2b91af;"&gt;DllImport&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;user32.dll&amp;quot;&lt;/span&gt;, CharSet = &lt;span style="color:#2b91af;"&gt;CharSet&lt;/span&gt;.Auto,
             CallingConvention = &lt;span style="color:#2b91af;"&gt;CallingConvention&lt;/span&gt;.StdCall)]
        &lt;span style="color:blue;"&gt;public static extern int &lt;/span&gt;SetWindowsHookEx(&lt;span style="color:blue;"&gt;int &lt;/span&gt;idHook, &lt;span style="color:#2b91af;"&gt;HookProc &lt;/span&gt;lpfn,
            &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;hInstance, &lt;span style="color:blue;"&gt;int &lt;/span&gt;threadId);

        &lt;span style="color:green;"&gt;//Call this function to uninstall the hook.
        &lt;/span&gt;[&lt;span style="color:#2b91af;"&gt;DllImport&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;user32.dll&amp;quot;&lt;/span&gt;, CharSet = &lt;span style="color:#2b91af;"&gt;CharSet&lt;/span&gt;.Auto,
             CallingConvention = &lt;span style="color:#2b91af;"&gt;CallingConvention&lt;/span&gt;.StdCall)]
        &lt;span style="color:blue;"&gt;public static extern bool &lt;/span&gt;UnhookWindowsHookEx(&lt;span style="color:blue;"&gt;int &lt;/span&gt;idHook);

        &lt;span style="color:green;"&gt;//Use this function to pass the hook information to next hook procedure in chain.
        &lt;/span&gt;[&lt;span style="color:#2b91af;"&gt;DllImport&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;user32.dll&amp;quot;&lt;/span&gt;, CharSet = &lt;span style="color:#2b91af;"&gt;CharSet&lt;/span&gt;.Auto,
             CallingConvention = &lt;span style="color:#2b91af;"&gt;CallingConvention&lt;/span&gt;.StdCall)]
        &lt;span style="color:blue;"&gt;public static extern int &lt;/span&gt;CallNextHookEx(&lt;span style="color:blue;"&gt;int &lt;/span&gt;idHook, &lt;span style="color:blue;"&gt;int &lt;/span&gt;nCode,
            &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;wParam, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;lParam);

        &lt;span style="color:green;"&gt;//Use this hook to get the module handle, needed for WPF environment
        &lt;/span&gt;[&lt;span style="color:#2b91af;"&gt;DllImport&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;kernel32.dll&amp;quot;&lt;/span&gt;, CharSet = &lt;span style="color:#2b91af;"&gt;CharSet&lt;/span&gt;.Auto)]
        &lt;span style="color:blue;"&gt;public static extern &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;GetModuleHandle(&lt;span style="color:blue;"&gt;string &lt;/span&gt;lpModuleName);

        &lt;span style="color:blue;"&gt;public enum &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HookType &lt;/span&gt;: &lt;span style="color:blue;"&gt;int
        &lt;/span&gt;{
            GlobalKeyboard = &lt;span style="color:purple;"&gt;13&lt;/span&gt;,
            GlobalMouse = &lt;span style="color:purple;"&gt;14
        &lt;/span&gt;}

        &lt;span style="color:blue;"&gt;public int &lt;/span&gt;MouseHookProc(&lt;span style="color:blue;"&gt;int &lt;/span&gt;nCode, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;wParam, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;lParam)
        {
            &lt;span style="color:green;"&gt;//user is active, at least with the mouse
            &lt;/span&gt;IsActive = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;
            &lt;span style="color:#2b91af;"&gt;Debug&lt;/span&gt;.Print(&lt;span style="color:#a31515;"&gt;&amp;quot;Mouse active&amp;quot;&lt;/span&gt;);

            &lt;span style="color:green;"&gt;//just return the next hook
            &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;CallNextHookEx(_hHookMouse, nCode, wParam, lParam);
        }

        &lt;span style="color:blue;"&gt;public int &lt;/span&gt;KbdHookProc(&lt;span style="color:blue;"&gt;int &lt;/span&gt;nCode, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;wParam, &lt;span style="color:#2b91af;"&gt;IntPtr &lt;/span&gt;lParam)
        {
            &lt;span style="color:green;"&gt;//user is active, at least with the keyboard
            &lt;/span&gt;IsActive = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;
            &lt;span style="color:#2b91af;"&gt;Debug&lt;/span&gt;.Print(&lt;span style="color:#a31515;"&gt;&amp;quot;Keyboard active&amp;quot;&lt;/span&gt;);

            &lt;span style="color:green;"&gt;//just return the next hook
            &lt;/span&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;CallNextHookEx(_hHookKbd, nCode, wParam, lParam);
        }

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Start()
        {
            &lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;currentProcess = &lt;span style="color:#2b91af;"&gt;Process&lt;/span&gt;.GetCurrentProcess())
            &lt;span style="color:blue;"&gt;using &lt;/span&gt;(&lt;span style="color:blue;"&gt;var &lt;/span&gt;mainModule = currentProcess.MainModule)
            {

                &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_hHookMouse == &lt;span style="color:purple;"&gt;0&lt;/span&gt;)
                {
                    &lt;span style="color:green;"&gt;// Create an instance of HookProc.
                    &lt;/span&gt;MouseHookProcedure = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HookProc&lt;/span&gt;(MouseHookProc);
                    &lt;span style="color:green;"&gt;// Create an instance of HookProc.
                    &lt;/span&gt;KbdHookProcedure = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;HookProc&lt;/span&gt;(KbdHookProc);

                    &lt;span style="color:green;"&gt;//register a global hook
                    &lt;/span&gt;_hHookMouse = SetWindowsHookEx((&lt;span style="color:blue;"&gt;int&lt;/span&gt;)&lt;span style="color:#2b91af;"&gt;HookType&lt;/span&gt;.GlobalMouse,
                                                  MouseHookProcedure,
                                                  GetModuleHandle(mainModule.ModuleName),
                                                  &lt;span style="color:purple;"&gt;0&lt;/span&gt;);
                    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_hHookMouse == &lt;span style="color:purple;"&gt;0&lt;/span&gt;)
                    {
                        Close();
                        &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApplicationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;SetWindowsHookEx() failed for the mouse&amp;quot;&lt;/span&gt;);
                    }
                }

                &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_hHookKbd == &lt;span style="color:purple;"&gt;0&lt;/span&gt;)
                {
                    &lt;span style="color:green;"&gt;//register a global hook
                    &lt;/span&gt;_hHookKbd = SetWindowsHookEx((&lt;span style="color:blue;"&gt;int&lt;/span&gt;)&lt;span style="color:#2b91af;"&gt;HookType&lt;/span&gt;.GlobalKeyboard,
                                                KbdHookProcedure,
                                                GetModuleHandle(mainModule.ModuleName),
                                                &lt;span style="color:purple;"&gt;0&lt;/span&gt;);
                    &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_hHookKbd == &lt;span style="color:purple;"&gt;0&lt;/span&gt;)
                    {
                        Close();
                        &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApplicationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;SetWindowsHookEx() failed for the keyboard&amp;quot;&lt;/span&gt;);
                    }
                }
            }
        }

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Close()
        {
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_hHookMouse != &lt;span style="color:purple;"&gt;0&lt;/span&gt;)
            {
                &lt;span style="color:blue;"&gt;bool &lt;/span&gt;ret = UnhookWindowsHookEx(_hHookMouse);
                &lt;span style="color:blue;"&gt;if &lt;/span&gt;(ret == &lt;span style="color:blue;"&gt;false&lt;/span&gt;)
                {
                    &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApplicationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;UnhookWindowsHookEx() failed for the mouse&amp;quot;&lt;/span&gt;);
                }
                _hHookMouse = &lt;span style="color:purple;"&gt;0&lt;/span&gt;;
            }

            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_hHookKbd != &lt;span style="color:purple;"&gt;0&lt;/span&gt;)
            {
                &lt;span style="color:blue;"&gt;bool &lt;/span&gt;ret = UnhookWindowsHookEx(_hHookKbd);
                &lt;span style="color:blue;"&gt;if &lt;/span&gt;(ret == &lt;span style="color:blue;"&gt;false&lt;/span&gt;)
                {
                    &lt;span style="color:blue;"&gt;throw new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ApplicationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;UnhookWindowsHookEx() failed for the keyboard&amp;quot;&lt;/span&gt;);
                }
                _hHookKbd = &lt;span style="color:purple;"&gt;0&lt;/span&gt;;
            }
        }

        &lt;span style="color:blue;"&gt;#region &lt;/span&gt;IDisposable Members

        &lt;span style="color:blue;"&gt;public void &lt;/span&gt;Dispose()
        {
            &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_hHookMouse != &lt;span style="color:purple;"&gt;0 &lt;/span&gt;|| _hHookKbd != &lt;span style="color:purple;"&gt;0&lt;/span&gt;)
                Close();
        }

        &lt;span style="color:blue;"&gt;#endregion
    &lt;/span&gt;}
}&lt;/pre&gt;



&lt;p&gt;The way you use it is quite simple, for example in a WPF application with a simple Window and a TextBlock:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Window &lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;WpfApplication2.MainWindow&amp;quot;
        &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;
        &lt;/span&gt;&lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;
        &lt;/span&gt;&lt;span style="color:red;"&gt;Title&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;MainWindow&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Height&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;350&amp;quot; &lt;/span&gt;&lt;span style="color:red;"&gt;Width&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;525&amp;quot;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;TextBlock &lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;IdleTextBox&amp;quot;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Grid&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Window&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;

&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;And in the code behind we wire up the ClientIdleHandler and a DispatcherTimer that ticks every second:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public partial class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;MainWindow &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Window
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DispatcherTimer &lt;/span&gt;_dispatcherTimer;
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ClientIdleHandler &lt;/span&gt;_clientIdleHandler;

    &lt;span style="color:blue;"&gt;public &lt;/span&gt;MainWindow()
    {
        InitializeComponent();
    }

    &lt;span style="color:blue;"&gt;private void &lt;/span&gt;Window_Loaded(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;RoutedEventArgs &lt;/span&gt;e)
    {
        &lt;span style="color:green;"&gt;//start client idle hook
        &lt;/span&gt;_clientIdleHandler = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ClientIdleHandler&lt;/span&gt;();
        _clientIdleHandler.Start();
        
        &lt;span style="color:green;"&gt;//start timer
        &lt;/span&gt;_dispatcherTimer = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;DispatcherTimer&lt;/span&gt;();
        _dispatcherTimer.Tick += TimerTick;
        _dispatcherTimer.Interval = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;(&lt;span style="color:purple;"&gt;0&lt;/span&gt;, &lt;span style="color:purple;"&gt;0&lt;/span&gt;, &lt;span style="color:purple;"&gt;0&lt;/span&gt;, &lt;span style="color:purple;"&gt;1&lt;/span&gt;);
        _dispatcherTimer.Start();
    }

    &lt;span style="color:blue;"&gt;private void &lt;/span&gt;TimerTick(&lt;span style="color:blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color:#2b91af;"&gt;EventArgs &lt;/span&gt;e)
    {
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(_clientIdleHandler.IsActive)
        {
            IdleTextBox.Text = &lt;span style="color:#a31515;"&gt;&amp;quot;Active&amp;quot;&lt;/span&gt;;
            &lt;span style="color:green;"&gt;//reset IsActive flag
            &lt;/span&gt;_clientIdleHandler.IsActive = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;    
        }
        &lt;span style="color:blue;"&gt;else &lt;/span&gt;IdleTextBox.Text = &lt;span style="color:#a31515;"&gt;&amp;quot;Idle&amp;quot;&lt;/span&gt;;
    }
}&lt;/pre&gt;


&lt;p&gt;Remember to reset the ClientIdleHandle IsActive flag after a check.&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48736" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="WPF" scheme="http://blog.irm.se/blogs/johan/archive/tags/WPF/default.aspx" /><category term=".NET 4.0" scheme="http://blog.irm.se/blogs/johan/archive/tags/.NET+4.0/default.aspx" /></entry><entry><title>Azure Summit Sweden</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2010/11/21/Azure-Summit-Sweden.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2010/11/21/Azure-Summit-Sweden.aspx</id><published>2010-11-21T16:26:48Z</published><updated>2010-11-21T16:26:48Z</updated><content type="html">&lt;p&gt;   &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:right;padding-top:0px;" id="scid:8747F07C-CDE8-481f-B0DF-C6CFD074BF67:a3e769ba-f8cf-4002-b28f-17edc0ade05d" class="wlWriterEditableSmartContent"&gt;&lt;a href="http://weblogs.asp.net/blogs/jdanforth/WP_000007-8x6_4C93E667.jpg" title="Crowded house" rel="thumbnail"&gt;&lt;img border="0" src="http://weblogs.asp.net/blogs/jdanforth/WP_000007_5BE74876.png" width="346" height="309" /&gt;&lt;/a&gt;&lt;/div&gt;   &lt;a href="http://azuresummit.cloudapp.net/" target="_blank"&gt;Azure Summit Sweden&lt;/a&gt;, held at Microsoft Sweden, was quite successful I would say. Every session was more or less fully booked and had 100 people or so attending.&lt;/p&gt;  &lt;p&gt;I held a session with Dag König on the basics of Web Role and Worker Role and promised to put the code for the “Twitted Demo” on Codeplex so that those who were interested could work on the code together and transform it into something that would or could work in a larger scenario.&lt;/p&gt;  &lt;p&gt;So I put the code up on Codeplex and called it Another Azure Demo Project - &lt;a href="http://anotherazuredemoproj.codeplex.com/"&gt;http://anotherazuredemoproj.codeplex.com/&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Feel free to go there, and &lt;strong&gt;request to join the project if you like&lt;/strong&gt;!&lt;/p&gt;  &lt;p&gt;The initial version of the code is made as a simple getting started demo, made for one instance of a web role and one instance of a worker role. The code has a worker role which does a search for specific words or tags on Twitter and stores the number of hits for that word in a table storage. A web page displays the number of hits per minute in a graph. This hand/mouse written sketch should explain the overall idea pretty much I think/hope (it's sketchy on purpose :)   &lt;br /&gt;&lt;img title="twitter demo sketch.png" alt="twitter demo sketch.png" src="http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=anotherazuredemoproj&amp;amp;DownloadId=170581" /&gt;    &lt;br /&gt;&lt;b&gt;The Future Version&lt;/b&gt;    &lt;br /&gt;The idea is to make the code grow into something that is more &amp;quot;Azureable&amp;quot;, something that would support multiple instances of the web and worker role. I've not worked out the final scenario yet, but one place to start would be to support searching for loads of tags, and have the search distributed between multiple instances of the worker role. &lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48720" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="Azure" scheme="http://blog.irm.se/blogs/johan/archive/tags/Azure/default.aspx" /></entry><entry><title>Extended Silverlight AutoCompleteBox for Handling Enter and Command Binding</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2010/10/27/Extended-Silverlight-AutoCompleteBox-for-Handling-Enter-and-Command-Binding.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2010/10/27/Extended-Silverlight-AutoCompleteBox-for-Handling-Enter-and-Command-Binding.aspx</id><published>2010-10-27T11:54:44Z</published><updated>2010-10-27T11:54:44Z</updated><content type="html">&lt;p&gt;In our RIA Services application, we’re using the AutoCompleteBox control, but what if you want to select something from the list, press Enter and bind to a Command in a viewmodel? Sort of like the Button Command property.&lt;/p&gt;  &lt;p&gt;I decided to extend the control and add a “Command” DependencyProperty for an ICommand which is executed when Enter is pressed and if an item is selected in the AutoCompleteBox. Works for us:&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;font face="Consolas"&gt;&lt;span style="font-family:;color:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size:9.5pt;"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;AutoCompleteBoxEx&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;/font&gt;&lt;span style="color:;"&gt;&lt;font style="font-size:9.5pt;" color="#2b91af"&gt;AutoCompleteBox&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size:9.5pt;" color="#000000"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; OnKeyDown(&lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;KeyEventArgs&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; e)&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; (SelectedItem != &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; &amp;amp;&amp;amp; e.Key == &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;Key&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.Enter)&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; (Command != &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;Command.Execute(SelectedItem);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size:9.5pt;" color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;base&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.OnKeyDown(e);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size:9.5pt;" color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;readonly&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;DependencyProperty&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; CommandProperty = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;DependencyProperty&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.RegisterAttached(&lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#a31515"&gt;&amp;quot;Command&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;ICommand&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;),&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;AutoCompleteBoxEx&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;),&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size:9.5pt;" color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;ICommand&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Command &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;{ &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;font face="Consolas"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; { &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; (&lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#2b91af"&gt;ICommand&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;)GetValue(CommandProperty); }&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;font face="Consolas"&gt;&lt;span style="font-family:;font-size:;mso-ansi-language:en-us;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;span style="font-family:;color:;font-size:;"&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="font-family:;font-size:;"&gt;&lt;font style="font-size:9.5pt;"&gt;&lt;font color="#000000"&gt; { SetValue(CommandProperty, &lt;/font&gt;&lt;span style="color:;"&gt;&lt;font color="#0000ff"&gt;value&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;); }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;font style="font-size:9.5pt;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size:9.5pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:normal;margin:0cm 0cm 0pt;text-autospace:;mso-layout-grid-align:none;" class="MsoNormal"&gt;&lt;span style="font-family:;font-size:;"&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size:9.5pt;" color="#000000"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="line-height:13pt;margin:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;font face="Calibri"&gt;&lt;font style="font-size:11pt;" color="#000000"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48716" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="Silverlight" scheme="http://blog.irm.se/blogs/johan/archive/tags/Silverlight/default.aspx" /></entry><entry><title>Silverlight AutoCompleteBox DataTemplate</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2010/09/22/Silverlight-AutoCompleteBox-DataTemplate.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2010/09/22/Silverlight-AutoCompleteBox-DataTemplate.aspx</id><published>2010-09-22T14:57:31Z</published><updated>2010-09-22T14:57:31Z</updated><content type="html">&lt;p&gt;This is more a note for myself how to do this. The &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=298170d6-567c-4b90-9917-490ffcddba87" target="_blank"&gt;Silverlight 4 SDK&lt;/a&gt; contains a pretty good AutoCompleteBox that you can use. Download/install the SDK and and the control will be available in your Silverlight Controls Toolbox.&lt;/p&gt;  &lt;p&gt;If you try to use this with RIA Services, you may notice it is displaying the Id/Key in the dropdown, but you yourself want to show a name or description. In that case you have to add a DataTemplate section to the AutoCompleteBox:&lt;/p&gt;  &lt;pre style="font-family:consolas;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;sdk&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;AutoCompleteBox&lt;/span&gt;&lt;span style="color:red;"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color:red;"&gt;x&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:red;"&gt;Name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;quot;FilterTextBox&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:red;"&gt; FilterMode&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;quot;Contains&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:red;"&gt; MaxDropDownHeight&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;quot;150&amp;quot;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color:red;"&gt;ItemsSource&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color:red;"&gt; Data&lt;/span&gt;&lt;span style="color:blue;"&gt;,&lt;/span&gt;&lt;span style="color:red;"&gt; ElementName&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:blue;"&gt;dds&lt;/span&gt;&lt;span style="color:blue;"&gt;}&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:red;"&gt; ValueMemberBinding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color:red;"&gt; Name&lt;/span&gt;&lt;span style="color:blue;"&gt;}&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#a31515;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;sdk&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;AutoCompleteBox.ItemTemplate&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#a31515;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#a31515;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;TextBlock&lt;/span&gt;&lt;span style="color:red;"&gt; Text&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Binding&lt;/span&gt;&lt;span style="color:red;"&gt; Name&lt;/span&gt;&lt;span style="color:blue;"&gt;}&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#a31515;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#a31515;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;sdk&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;AutoCompleteBox.ItemTemplate&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;sdk&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:#a31515;"&gt;AutoCompleteBox&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;That should do it.&lt;/p&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48711" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="Silverlight" scheme="http://blog.irm.se/blogs/johan/archive/tags/Silverlight/default.aspx" /></entry><entry><title>Masked Silverlight TextBox for Swedish National Identification Number (Personnummer)</title><link rel="alternate" type="text/html" href="http://blog.irm.se/blogs/johan/archive/2010/09/19/Masked-Silverlight-TextBox-for-Swedish-National-Identification-Number-_2800_Personnummer_2900_.aspx" /><id>http://blog.irm.se/blogs/johan/archive/2010/09/19/Masked-Silverlight-TextBox-for-Swedish-National-Identification-Number-_2800_Personnummer_2900_.aspx</id><published>2010-09-19T17:56:50Z</published><updated>2010-09-19T17:56:50Z</updated><content type="html">&lt;p&gt;In our upcoming Silverlight 4 project there’s a need for a textbox with a mask for entering a Swedish national identification number (personnummer) with either 10 or 12 digits, in the form of yyyymmdd-nnnn. It’s quite simple, I just want to make sure only digits are entered and that the dash (-) is placed automatically and a few other small things that I’d like to tweak.&lt;/p&gt;  &lt;p&gt;As far as I can see (correct me if I’m wrong here) there’s no mask feature in SL4 (yet), so I’m simply going to inherit and extend the built in TextBox. Validation of the number is done in the viewmodel instead of built into the control. See upcoming blogpost for that.&lt;/p&gt;  &lt;p&gt;So, enough talk already, hope it can be of use:&lt;/p&gt;  &lt;pre style="font-family:consolas;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color:#2b91af;"&gt;PersonnummerTextBox&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;TextBox&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; TwelveDigits { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;int&lt;/span&gt; _leftPart;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color:#2b91af;"&gt;Key&lt;/span&gt; _lastKey;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; PersonnummerTextBox()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TextChanged += OnTextChanged;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Loaded += OnLoaded;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;void&lt;/span&gt; OnLoaded(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;RoutedEventArgs&lt;/span&gt; e)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _leftPart = TwelveDigits ? 8 : 6;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; Only allow digits and tab, no shifts or ctrl&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;quot;e&amp;quot;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;protected&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;override&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;void&lt;/span&gt; OnKeyDown(&lt;span style="color:#2b91af;"&gt;KeyEventArgs&lt;/span&gt; e)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _lastKey = e.Key;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;//used in OnTextChanged to handle Del key&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;base&lt;/span&gt;.OnKeyDown(e);&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (((e.Key &amp;gt;= &lt;span style="color:#2b91af;"&gt;Key&lt;/span&gt;.NumPad0 &amp;amp;&amp;amp; e.Key &amp;lt;= &lt;span style="color:#2b91af;"&gt;Key&lt;/span&gt;.NumPad9) ||&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (e.Key &amp;gt;= &lt;span style="color:#2b91af;"&gt;Key&lt;/span&gt;.D0 &amp;amp;&amp;amp; e.Key &amp;lt;= &lt;span style="color:#2b91af;"&gt;Key&lt;/span&gt;.D9) ||&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e.Key == &lt;span style="color:#2b91af;"&gt;Key&lt;/span&gt;.Tab) &amp;amp;&amp;amp;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;//so that we can TAB out from the control ;)&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&lt;span style="color:#2b91af;"&gt;Keyboard&lt;/span&gt;.Modifiers &amp;amp; &lt;span style="color:#2b91af;"&gt;ModifierKeys&lt;/span&gt;.Shift) == 0 &amp;amp;&amp;amp;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&lt;span style="color:#2b91af;"&gt;Keyboard&lt;/span&gt;.Modifiers &amp;amp; &lt;span style="color:#2b91af;"&gt;ModifierKeys&lt;/span&gt;.Control) == 0)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e.Handled = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; e.Handled = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; Make sure the dash (-) is placed on the correct place automatically&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; either as yyyymmdd-nnnn or yymmdd-nnnn&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;quot;sender&amp;quot;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#160;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;quot;e&amp;quot;&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color:blue;"&gt;void&lt;/span&gt; OnTextChanged(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;TextChangedEventArgs&lt;/span&gt; e)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; leftPartPlusDash = (_leftPart + 1);&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; cursorPosition = SelectionStart;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; strippedText = Text.Replace(&lt;span style="color:#a31515;"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (strippedText.Length &amp;gt; _leftPart)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;//move the cursor after the dash&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (strippedText.Length == leftPartPlusDash &amp;amp;&amp;amp;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cursorPosition == leftPartPlusDash &amp;amp;&amp;amp; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _lastKey != &lt;span style="color:#2b91af;"&gt;Key&lt;/span&gt;.Delete) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cursorPosition = (_leftPart + 2);&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;//put a dash in the right place&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text = &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;{0}-{1}&amp;quot;&lt;/span&gt;, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; strippedText.Substring(0, _leftPart), &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; strippedText.Substring(_leftPart, &lt;span style="color:#2b91af;"&gt;Math&lt;/span&gt;.Min(4, strippedText.Length - _leftPart)));&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text = strippedText;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:green;"&gt;//move cursor to the wanted position&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SelectionStart = cursorPosition;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;i&gt;Cross-posted from my blog at &lt;a href="http://weblogs.asp.net/jdanforth"&gt;http://weblogs.asp.net/jdanforth&lt;/a&gt;&lt;/i&gt;&lt;img src="http://blog.irm.se/aggbug.aspx?PostID=48710" width="1" height="1"&gt;</content><author><name>johan</name><uri>http://blog.irm.se/members/johan.aspx</uri></author><category term="Silverlight" scheme="http://blog.irm.se/blogs/johan/archive/tags/Silverlight/default.aspx" /></entry></feed>
