<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>adamjcooper.com/blog</title>
    <description>Enterprise Software Development in C#</description>
    <link>http://adamjcooper.com/blog/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.4.5.0</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://adamjcooper.com/blog/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Adam J. Cooper</dc:creator>
    <dc:title>adamjcooper.com/blog</dc:title>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/adamjcoopercom/blog" type="application/rss+xml" /><item>
      <title>Casting to a Specific Subclass at Runtime Based on the Value of an NHibernate Discriminator</title>
      <description>&lt;p&gt;So you have a class hierarchy, like this:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Fruit  &lt;ul&gt; &lt;li&gt;Apple  &lt;li&gt;Orange&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Then, when loading persisted instances, your repository returns a Fruit. Fine. But in order to get your work done, you really need an Apple or an Orange. So you need to cast the returned Fruit to its actual type. Fine. Just add a simple read-only enum property to the Fruit class denoting the specific type of fruit. Then, at runtime use that property to determine what cast to make:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;if (someFruit.Type == FruitType.Apple)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var apple = (Apple) someFruit; &lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Do something useful with the apple...&lt;br&gt;}&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Fine. One last wrinkle: you're using NHibernate to persist your objects, and you're using a table-per-class-hierarchy mapping for Fruit (which means you've got a single database table to store any type of Fruit, which is a nice type of mapping if your specific subclasses are light and your parent is heavy).&lt;/p&gt; &lt;p&gt;How do you do this?&lt;/p&gt; &lt;h2&gt;Mapping the Enum to a Discriminator&lt;/h2&gt; &lt;p&gt;In NHibernate, you use a discriminator to differentiate whether records in a Fruit table are Apples or Oranges (or whatever). But NHibernate discriminators are &lt;em&gt;not&lt;/em&gt; mapped to object properties, like our FruitType enum. They are simply an internal way for NHibernate to determine what type of class to instantiate at runtime.&lt;/p&gt; &lt;p&gt;Here's a simple XML mapping example:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&amp;lt;class name="Fruit" table="FRUIT" discriminator-value="fruit"&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id name="Id"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;generator class="native" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/id&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&amp;lt;discriminator column="FRUIT_TYPE_COLUMN" /&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;subclass name="Apple" discriminator-value="apple"&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/subclass&amp;gt;&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;subclass name="Orange" discriminator-value="orange"&amp;gt; &lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ... &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/subclass&amp;gt;&lt;br&gt;&amp;lt;/class&amp;gt; &lt;p&gt;All this mapping is saying is that you have a base Fruit class with two child subclasses, Apple and Orange, which are mapped to a database table named FRUIT. At runtime, NHibernate will know whether a particular record in the FRUIT table is a persisted Apple or a persisted Orange based on the value in the FRUIT_TYPE_COLUMN, which will either be "apple" for an Apple or "orange" for an Orange. &lt;p&gt;There are a couple of important things to remember about discriminators: &lt;ul&gt; &lt;li&gt;Their default type is string (nvarchar in the database - don't use nchar or you'll get bitten by white space!)&lt;/li&gt; &lt;li&gt;They are not mapped to properties in your object model&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Not having any access to the discriminator in your object model is fine if your repository methods return Apples or Oranges specifically, but what if your repository returns a the parent Fruit object? In that case, it would be nice if we &lt;em&gt;did&lt;/em&gt; have access to the NHibernate discriminator, preferably mapped to our handy FruitType enum property. Well, there is a way to do this, but it is not obvious. &lt;p&gt;Basically your mapping needs to declare a discriminator &lt;em&gt;and&lt;/em&gt; a property which use the same database column, but you make the property mapping "read only" by turning off database updates and inserts, allowing the discriminator to handle that part instead. Here's a summary: &lt;p&gt;&lt;strong&gt;How to Map an Enum Property to an NHibernate Discriminator Column:&lt;/strong&gt; &lt;ol&gt; &lt;li&gt;In your database, create an int column that will hold the enum value.&lt;/li&gt; &lt;li&gt;In your NHibernate mapping, declare a discriminator whose type is Int32 (rather than the default string, which won't work with an enum).&lt;/li&gt; &lt;li&gt;In your NHibernate mapping, declare a property mapping which maps to the same column as the discriminator, but be sure to add &lt;strong&gt;insert="false"&lt;/strong&gt; and &lt;strong&gt;update="false"&lt;/strong&gt;.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;So, here's how our above example would change:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&amp;lt;class name="Fruit" table="FRUIT" discriminator-value="0"&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id name="Id"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;generator class="native" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/id&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&amp;lt;discriminator column="FRUIT_TYPE_COLUMN" type="Int32" /&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name="FruitType" column="FRUIT_TYPE_COLUMN" insert="false" update="false" /&amp;gt;&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;subclass name="Apple" discriminator-value="1"&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/subclass&amp;gt;&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;subclass name="Orange" discriminator-value="2"&amp;gt; &lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ... &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/subclass&amp;gt;&lt;br&gt;&amp;lt;/class&amp;gt;&lt;/p&gt; &lt;p&gt;With that, our enum property is successfully mapped to the discriminator. But we're not out of the woods yet--there's one last gotcha you need to know about if you're going to be casting at runtime...&lt;/p&gt; &lt;h2&gt;No Lazy Loading!&lt;/h2&gt; &lt;p&gt;By default, NHibernate uses lazy loading to improve database performance. But in order to do this, NHibernate must create a &lt;em&gt;proxy&lt;/em&gt;, something that looks like the type you requested but which is, in reality, a newly derived child type with lazy-loading automatically baked into the associations. What that means is that if your repository method returns Fruit, NHibernate won't give you Fruit, but some sort of FruitProxy_blah_blah_blah, which is a new type derived from Fruit. It is a Fruit, but it's not an Apple, nor an Orange, and if you try to cast to either of them it will blow up in your face.&lt;/p&gt; &lt;p&gt;The good news is that there is a workaround, but the workaround is also the bad news: You must turn off lazy loading. Once you do that you can cast to an Apple or Orange just fine. You just lose all the advantages of the lazy-loading.&lt;/p&gt; &lt;p&gt;So, here's our example re-written once again to support casting at runtime:&lt;/p&gt;&lt;strong&gt;&amp;lt;class name="Fruit" table="FRUIT" discriminator-value="0" lazy="false"&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;id name="Id"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;generator class="native" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/id&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&amp;lt;discriminator column="FRUIT_TYPE_COLUMN" type="Int32" /&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name="FruitType" column="FRUIT_TYPE_COLUMN" insert="false" update="false" /&amp;gt;&lt;/strong&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;subclass name="Apple" discriminator-value="1" lazy="false"&amp;gt;&lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/subclass&amp;gt;&lt;br&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;subclass name="Orange" discriminator-value="2" lazy="false"&amp;gt; &lt;br&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ... &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/subclass&amp;gt;&lt;br&gt;&amp;lt;/class&amp;gt; &lt;h2&gt;Conclusion&lt;/h2&gt; &lt;p&gt;Exposing a discriminator in your object model as an enum property is easy enough (see above). But if you need to actually use that property to cast the type at runtime, you must turn off lazy loading. If someone knows how to do both, I'd love to hear about it.&lt;/p&gt; &lt;p&gt;Hope it helps.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/cRZwjeAsqIQ/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Casting-to-a-Specific-Subclass-at-Runtime-Based-on-the-Value-of-an-NHibernate-Discriminator.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=034d1a75-3c2c-410f-9988-72641fb10140</guid>
      <pubDate>Fri, 12 Dec 2008 10:42:57 -1100</pubDate>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=034d1a75-3c2c-410f-9988-72641fb10140</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=034d1a75-3c2c-410f-9988-72641fb10140</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Casting-to-a-Specific-Subclass-at-Runtime-Based-on-the-Value-of-an-NHibernate-Discriminator.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=034d1a75-3c2c-410f-9988-72641fb10140</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=034d1a75-3c2c-410f-9988-72641fb10140</feedburner:origLink></item>
    <item>
      <title>Happy Birthday!</title>
      <description>&lt;p&gt;
The day has finally come! Timothy Stephen Cooper was born on Saturday, November 29, 2008 at 8:37 am, weighing in at 7 lbs. and 5.5 ounces.
&lt;/p&gt;
 
&lt;p&gt;
Mommy and baby are both healthy and doing well, for which we are very thankful. As with Lydia, Holly elected to give birth naturally (meaning without medication), and she did a fantastic job. No screaming, no crying; just focused, controlled labor. I could not be more proud of her. And because we delivered at &lt;a href="http://laborluv.com/" target="_blank"&gt;a local birth center&lt;/a&gt; rather than a hospital, and because there were no major complications during labor and delivery, we were able to go home with Timothy just a few hours after he was born.
&lt;/p&gt;
 
&lt;p&gt;
It just so happened that I was born 28 years earlier on the morning of the same date, which made this birthday a particularly happy one.
&lt;/p&gt;
 
&lt;h2&gt;Birthday Pictures&lt;/h2&gt; 
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/Family_2.jpg"&gt;&lt;img style="border-width: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/Family_thumb.jpg" border="0" alt="Family" width="640" height="531" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;
&lt;strong&gt;Our family, a few hours after Timothy was born&lt;br /&gt;
&lt;/strong&gt;(after waking up at 6:00 am and being present for the birth, Lydia was a little tired)
&lt;/p&gt;
 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2173.jpg"&gt;&lt;img style="border-width: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2173_thumb.jpg" border="0" alt="IMG_2173" width="640" height="480" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;
&lt;strong&gt;Our midwife, who was absolutely wonderful&lt;/strong&gt;
&lt;/p&gt;
 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2177.jpg"&gt;&lt;img style="border-width: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2177_thumb.jpg" border="0" alt="IMG_2177" width="640" height="480" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;
&lt;strong&gt;Timothy, at home and sleeping soundly&lt;/strong&gt;
&lt;/p&gt;
 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2186.jpg"&gt;&lt;img style="border-width: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2186_thumb.jpg" border="0" alt="IMG_2186" width="360" height="480" /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;strong&gt;Admiring new baby brother&lt;/strong&gt;
&lt;/p&gt;
 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2209.jpg"&gt;&lt;img style="border-width: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2209_thumb.jpg" border="0" alt="IMG_2209" width="640" height="480" /&gt;&lt;/a&gt; &lt;br /&gt;
&lt;strong&gt;My favorite people&lt;/strong&gt;
&lt;/p&gt;
 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2201.jpg"&gt;&lt;img style="border-width: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2201_thumb.jpg" border="0" alt="IMG_2201" width="640" height="480" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;
&lt;strong&gt;Just after his first bath&lt;/strong&gt;
&lt;/p&gt;
 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2231_1.jpg"&gt;&lt;img style="border-width: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HappyBirthday_F1B9/IMG_2231_thumb_1.jpg" border="0" alt="IMG_2231" width="640" height="480" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;
&lt;strong&gt;Brother-and-sister bedtime&lt;/strong&gt;
&lt;/p&gt;
 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
 
&lt;p&gt;
&lt;em&gt;Sons are indeed a heritage from the LORD, &lt;br /&gt;
the fruit of the womb a reward.&lt;br /&gt;
&lt;/em&gt;Psalm 127:3
&lt;/p&gt;
 
&lt;p&gt;
&lt;em&gt;An excellent wife, who can find?&lt;br /&gt;
For her worth is far above jewels.&lt;br /&gt;
Her children rise up and bless her;&lt;br /&gt;
Her husband also, and he praises her, saying:&lt;br /&gt;
Many daughters have done nobly,&lt;br /&gt;
But you excel them all.&lt;br /&gt;
&lt;/em&gt;Proverbs 31:10, 28-29
&lt;/p&gt;
 
&lt;p&gt;
&lt;em&gt;You formed my inward parts; &lt;br /&gt;
You wove me in my mother&amp;#39;s womb.&amp;nbsp; &lt;br /&gt;
I will give thanks to You, &lt;br /&gt;
for I am fearfully and wonderfully made; &lt;br /&gt;
Wonderful are Your works, &lt;br /&gt;
And my soul knows it very well.&lt;/em&gt;&lt;br /&gt;
Psalm 139:13-14 
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/qwJgvf0qGe8/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Happy-Birthday!.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=2c98fd94-2f8a-4098-8500-23777f6b3d30</guid>
      <pubDate>Sun, 30 Nov 2008 17:33:00 -1100</pubDate>
      <category>Personal</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=2c98fd94-2f8a-4098-8500-23777f6b3d30</pingback:target>
      <slash:comments>6</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=2c98fd94-2f8a-4098-8500-23777f6b3d30</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Happy-Birthday!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=2c98fd94-2f8a-4098-8500-23777f6b3d30</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=2c98fd94-2f8a-4098-8500-23777f6b3d30</feedburner:origLink></item>
    <item>
      <title>Migrating to ASP.NET MVC Beta from Preview 5</title>
      <description>&lt;p&gt;Congratulations to the ASP.NET MVC team, the first official Beta is out. You can &lt;a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=A24D1E00-CD35-4F66-BAA0-2362BDDE0766&amp;amp;displaylang=en"&gt;download it here&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;&lt;a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2008/10/16/asp-net-mvc-beta-released.aspx"&gt;ScottGu&lt;/a&gt; offers an excellent guide to what has changed, and &lt;a target="_blank" href="http://www.hanselman.com/blog/ASPNETMVCBetaReleasedCoolnessEnsues.aspx"&gt;Scott Hanselman&lt;/a&gt; and &lt;a target="_blank" href="http://haacked.com/archive/2008/10/16/aspnetmvc-beta-release.aspx"&gt;Phil Haack&lt;/a&gt; also announce the Beta and summarize what's new. I'll let you read their blogs to get the new features list. I'm going to use this post to outline what I had to do in order to get my existing Preview 5 project converted over to MVC Beta. &lt;/p&gt; &lt;h2&gt;Installation&lt;/h2&gt; &lt;p&gt;You will need to uninstall Preview 5 (or any other Preview) before you can install the new version. &lt;/p&gt; &lt;h2&gt;Update Your References&lt;/h2&gt; &lt;p&gt;If you have any projects that are currently depending on the Preview 5 assemblies, you will need to remove the references to these assemblies and then add references to the new assemblies. Specifically, you need to update: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;System.Web.Abstractions.dll  &lt;li&gt;System.Web.Mvc.dll  &lt;li&gt;System.Web.Routing.dll &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The new assemblies are typically located in &lt;strong&gt;C:\Program Files\Microsoft ASP.NET\ASP.NET MVC Beta&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;The installer apparently also places these assemblies in the GAC, but I don't recommend using them this way. First, the .NET tab of the Add References dialog is mysteriously missing System.Web.Mvc (though it contains .Abstractions and .Routing). But more importantly, if you want to deploy to your web server without having to change anything on the server itself, you should add local references for these three assemblies.&lt;/p&gt; &lt;h3&gt;Use Local Copies of the MVC Assemblies for Easy Deployment (Avoid the GAC)&lt;/h3&gt; &lt;p&gt;I had an issue with my application running fine on my local machine but not on the web server that turned out to be a GAC/local bin conflict. I had added references to the MVC assemblies by browsing to &lt;strong&gt;C:\Program Files\Microsoft ASP.NET\ASP.NET MVC Beta&lt;/strong&gt;, like so:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MigratingtoASP.NETMVCBetafromPreview5_2893/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MigratingtoASP.NETMVCBetafromPreview5_2893/image_thumb.png" width="508" height="433"&gt;&lt;/a&gt;&amp;nbsp; &lt;/p&gt; &lt;p&gt;However, each of these references had "Copy Local" set to False, and my web.config file contained assembly references in the compilation section that referenced the GAC. So, when I ran on my local machine, the GAC assemblies were present and it worked fine. But when I pushed out to the server, the MVC assemblies were not included in the local bin folder, and since the MVC Beta installer hadn't been run on the web server, it obviously didn't work.&lt;/p&gt; &lt;p&gt;The solution is to make sure that the MVC assemblies have Copy Local set to True, which ensures that you get a copy of the assembly in the local bin folder:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MigratingtoASP.NETMVCBetafromPreview5_2893/image_6.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MigratingtoASP.NETMVCBetafromPreview5_2893/image_thumb_2.png" width="419" height="757"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;And you can remove any lines in your web.config that reference the GAC versions:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MigratingtoASP.NETMVCBetafromPreview5_2893/image_8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MigratingtoASP.NETMVCBetafromPreview5_2893/image_thumb_3.png" width="1086" height="259"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;If I'm misrepresenting something here someone let me know.&lt;/p&gt; &lt;h3&gt;Futures Assembly (Microsoft.Web.Mvc.dll)&lt;/h3&gt; &lt;p&gt;If you have any references to the ASP.NET MVC Futures assembly (Microsoft.Web.Mvc.dll), it will also need to be updated. However, now that MVC has entered Beta status, the Futures assembly is no longer being included in the installer. You will need to &lt;a target="_blank" href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=18459"&gt;download the updated Microsoft.Web.Mvc.dll, updated for MVC Beta, from CodePlex&lt;/a&gt;. &lt;/p&gt; &lt;h3&gt;Rebuild Your Projects and Correct and Breaking Changes&lt;/h3&gt; &lt;p&gt;If you're lucky, all you'll need to do is update your references, rebuild, and you're done. If you're like me, you'll hit a few snags along the way and need to make some changes to your code. &lt;/p&gt; &lt;h2&gt;Gotchas&lt;/h2&gt; &lt;p&gt;Here's what got me when I updated to MVC Beta: &lt;/p&gt; &lt;h3&gt;ActionLink Bug?&lt;/h3&gt; &lt;p&gt;I tried using one of the new ActionLink overloads, specifically ActionLink(string linkText, string actionName, string controllerName, object values) but I could never get it to produce a link with a correct href. Instead of a valid URL, I'd get a URL that had a ?Length=&lt;em&gt;n&lt;/em&gt; tacked onto the end of it, where n was the length of the controllerName string. Very strange, and very frustrating. Has anyone else noticed this? &lt;/p&gt; &lt;h3&gt;Strongly-typed Html.ActionLink moved to the Futures Assembly&lt;/h3&gt; &lt;p&gt;The strongly-typed version of ActionLink is now in the ASP.NET MVC Futures assembly (Microsoft.Web.Mvc). If you want it back, you'll need to &lt;a target="_blank" href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=18459"&gt;download the new Beta-compatible Futures assembly from CodePlex&lt;/a&gt; and add it to your project. &lt;/p&gt; &lt;h3&gt;ViewContext.ViewName Removed&lt;/h3&gt; &lt;p&gt;I'm not sure why. In the meantime, you can use the much uglier &lt;strong&gt;ViewContext.RouteData.Values["action"].ToString()&lt;/strong&gt;. But I'd sure like to see that property come back (or at least get a good explanation of why it disappeared). &lt;/p&gt; &lt;h3&gt;AddModelError Changes&lt;/h3&gt; &lt;p&gt;If you were using the ViewData.ModelState.AddModelError method, you'll notice the second parameter, attemptedValue, is gone. That's because the there's a new, independent &lt;strong&gt;SetAttemptedValue &lt;/strong&gt;method you should use instead. This makes sense--you may need to set multiple errors for a single attempted value, so the two operations should be teased apart. &lt;/p&gt; &lt;h3&gt;Html.Form is now Html.BeginForm&lt;/h3&gt; &lt;p&gt;If you're looking for the Html.Form helper method, it's now named Html.BeginForm. &lt;a target="_blank" href="http://weblogs.asp.net/scottgu/archive/2008/10/16/asp-net-mvc-beta-released.aspx#nine"&gt;Scott Guthrie elaborates&lt;/a&gt;. &lt;/p&gt; &lt;h3&gt;MvcContrib.Ninject&lt;/h3&gt; &lt;p&gt;I'm currently using Ninject in combination with NHibernate. With Preview 5 I was using the Ninject support offered in MvcContrib, but this doesn't work with MVC Beta. The good news is that the latest version of Ninject comes with its own, more streamlined support for ASP.NET MVC, and it works fine with the Beta version. I may blog more about the details in a future post, but the short story is this: You need to checkout the latest version of the Ninject source code (&lt;strong&gt;svn checkout &lt;/strong&gt;&lt;a href="http://ninject.googlecode.com/svn/trunk/"&gt;&lt;strong&gt;http://ninject.googlecode.com/svn/trunk/&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; ninject-trunk&lt;/strong&gt;), add references to Ninject.Core.dll, Ninject.Conditions.dll, and Ninject.Framework.Mvc.dll to your MVC project, and then update your Global.asax file as outlined in Emad Ibrahim's blog: &lt;a title="http://www.emadibrahim.com/2008/08/21/ninject-killer-ioc/" href="http://www.emadibrahim.com/2008/08/21/ninject-killer-ioc/"&gt;http://www.emadibrahim.com/2008/08/21/ninject-killer-ioc/&lt;/a&gt;. &lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/cRPSmIUkM74/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Migrating-to-ASPNET-MVC-Beta-from-Preview-5.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=d1c487fb-e8c0-4079-849a-dacd2d85cd27</guid>
      <pubDate>Thu, 16 Oct 2008 19:52:00 -1100</pubDate>
      <category>ASP.NET MVC</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=d1c487fb-e8c0-4079-849a-dacd2d85cd27</pingback:target>
      <slash:comments>10</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=d1c487fb-e8c0-4079-849a-dacd2d85cd27</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Migrating-to-ASPNET-MVC-Beta-from-Preview-5.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=d1c487fb-e8c0-4079-849a-dacd2d85cd27</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=d1c487fb-e8c0-4079-849a-dacd2d85cd27</feedburner:origLink></item>
    <item>
      <title>Why I Abandoned Silverlight for ASP.NET MVC</title>
      <description>&lt;p&gt;I'm currently tasked with building a web-based tool that helps social event coordinators keep track of their invitees--who has been contacted, who has sent in an RSVP, who has paid, what particular activities a person will be participating in, etc. It's essentially a big contacts list with a lot of enhanced functionality around registration and payment. The basic domain model and data layer are in place, and I've spent the past month building a user interface in Silverlight. It's been an interesting journey, and there's a lot about Silverlight that I really, really like, but in the end I've finally decided a monolithic Silverlight application is not the right path. I probably should have heeded &lt;a target="_blank" href="http://wildermuth.com/2008/06/26/Silverlight_and_Line_of_Business_Applications"&gt;Shawn Wildermuth's warning about not building a monolithic Silverlight line-of-business application&lt;/a&gt; before I got started, but it's hard to know how to use or how not to use a platform if you've never built anything with it. So I tried, and it was working, but in the end it just became too laborious.&lt;/p&gt; &lt;p&gt;Why? Because even though Silverlight has a super-cool UI model, gives you mini .NET framework, and let's you program in C#, it still can't give me what I really want: my domain objects.&lt;/p&gt; &lt;p&gt;Traditional web applications are strange in that the server is responsible--in one way or another--for building and adjusting the UI that will run on the client. Stop and think about that. JavaScript aside, the client is just a dumb terminal, and the server is in command. Web 2.0 has changed a lot of that, with AJAX frameworks that are putting more burden on the client, but the fact that the initial rendering of so many web UI's is still done server-side shows the strange sort of blurring of the client/server boundary line that exists in traditional web development.&lt;/p&gt; &lt;p&gt;Silverlight, on the other hand, makes a complete break. It is the client in command. At runtime it is the client itself which builds the UI and which is responsible for updating it, not the web server. That is a big paradigm shift from traditional web development and it brings with it some consequences, one of which is interaction with your domain model. In a traditional web app you can dynamically build up the HTML to send to the client using the domain model that lived on the server. But in Silverlight, any part of the UI that depends on server-side assemblies will need to make calls to the server to maintain itself. At first this doesn't seem so bad since Silverlight comes with an impressive networking stack. But after a month of laborious and painful development, I've finally decided it's just too complex for my style of development.&lt;/p&gt; &lt;p&gt;Now, if you're not particularly interested in being domain-driven, if you just need to get the data into the UI so you can mess with it, you can probably get a basic data-driven Silverlight app running without too much hassle. But if you like to build robust domain models that the UI layer depends on, you need to carefully consider the development cost of using a UI platform that requires you to do &lt;em&gt;all&lt;/em&gt; of your communication with your domain model via web services and &lt;em&gt;forbids&lt;/em&gt; you from dynamically building the UI on the server (unless you're planning to send XAML over the wire).&lt;/p&gt; &lt;p&gt;For the application I've been developing it wasn't that Silverlight wasn't capable of doing what I wanted, but that what I wanted took too long to do and required too much busywork. Here is a summary of my pain points:&lt;/p&gt; &lt;p&gt;&lt;img style="border-right-width: 0px; padding-right: 1em; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" align="left" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/WhyIAbandonedSilverlightforASP.NETMVC_338/image_16.png" width="81" height="57"&gt; &lt;strong&gt;Data Transaction Objects.&lt;/strong&gt; Sprinkling my domain model with lots of WCF data contract attributes was out of the question, not only because I didn't want to pollute the model, but because not everything that needed to go over the wire was in the form of a property. So a lot of the hassle came from the unavoidable evil of converting domain objects to stale DTOs and then re-hydrating them after they come back from the client. The conversion to and from a DTO involved lots of mundane property assignments with sprinkles of complexity to handle constructors, immutable types, and lists. It wound up being an unusual combination of boring and yet error-prone code that required a lot of maintenance.&lt;/p&gt; &lt;p&gt;&lt;img style="border-right-width: 0px; padding-right: 1em; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" align="left" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/WhyIAbandonedSilverlightforASP.NETMVC_338/image_17.png" width="46" height="57"&gt; &lt;strong&gt;WCF Service Configuration.&lt;/strong&gt; It took a lot of head-banging to figure out how to successfully update my WCF services during development, and it only got uglier when I implemented ASP.NET-based authentication to keep the services locked down. Eventually it became second nature, but I spent an awful lot of time adjusting authentication in web.config, deleting the service reference in the Silverlight project, re-adding it, etc.&lt;/p&gt; &lt;p&gt;&lt;img style="border-right-width: 0px; padding-right: 1em; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" align="left" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/WhyIAbandonedSilverlightforASP.NETMVC_338/image_18.png" width="48" height="48"&gt; &lt;strong&gt;The Lack of SOAP Faults. &lt;/strong&gt;This one really got to me. The inability for exceptions to travel across the wire as SOAP faults was extremely frustrating. It made debugging difficult, and sending useful error messages cumbersome. I wound up wrapping all of my service return values to include a possible exception information object. What a mess.&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;img style="border-right-width: 0px; padding-right: 1em; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" align="left" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/WhyIAbandonedSilverlightforASP.NETMVC_338/image_19.png" width="46" height="74"&gt; &lt;strong&gt;The Lack of Domain Object Functionality. &lt;/strong&gt;Initially the idea of a pure separation of client/server was very attractive to me. After all, why should the burden of updating the user interface be split between the client and server as in most Web 2.0 web apps? But in practice, the inability to send the &lt;em&gt;functional &lt;/em&gt;side of my domain objects across the wire made things difficult. I realize this is what services are for, but there were so many times when I had a simple problem to solve and the web services barrier was getting in the way.&lt;br&gt;&lt;br&gt;For example, my domain model includes a rather robust object for a person's name (first, middle, last, friendly, preferred, prefix, suffix, etc.). I also have a PersonNameFormattingService object which I use to build different strings, from the formal "Dr. L. David McClister" to the simpler "McClister, Dave". There are even methods to take a current and former name to generate a name string that includes a maiden name. The point is that all of that formatting logic is housed in the PersonNameFormattingService, on the server, and I &lt;em&gt;don't&lt;/em&gt; want to duplicate it.&lt;br&gt;&lt;br&gt;Now, on the Silverlight side, there were lots of times when I needed a person's name formatted in different ways. But the service I need to format the data lives on the server. This left me with two options, neither of which I liked: 1) create an identical PersonNameFormattingService in a Silverlight library that does essentially the same thing, or 2) format the name on the server and send the result over the wire as needed.&lt;br&gt;&lt;br&gt;The problem with the first approach is that it forces me to update two copies of the code base. And, while it may work just fine for simple name formatting, if it involves heavier lifting in the .NET framework, it may not be entirely portable to a Silverlight library. It's an option to consider, but it's not a silver bullet. The problem with the second approach is that it's a big hassle, and it forces you to build lots of services and DTOs just to get leverage your domain model logic. This is just one example. I fought this sort of stuff on a daily basis. It seemed the more robust my domain model, the more difficult it was to use.&lt;/p&gt; &lt;p&gt;I'm sure experienced SOA developers would have better intuition than I do about how to organize and build services and DTOs to appropriately leverage their domain layer from a remote Silverlight client, but I got to the point where I was spending more time building a bridge to access my domain model rather than using the model to get real work done.&lt;/p&gt; &lt;p&gt;So now I'm using &lt;a target="_blank" href="http://www.asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt;, and I'm loving it. I can build a clean, testable UI layer that leverages the full power of my domain model. Add in some jQuery for AJAX, and I can leverage the client to get partial page updates while still leveraging the server to generate the UI. From my perspective, a beautiful compromise.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/XP-kg9oySu8/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Why-I-Abandoned-Silverlight-for-ASPNET-MVC.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=ecf6fb20-acf0-476e-be92-8c4a2b467bd0</guid>
      <pubDate>Sat, 11 Oct 2008 17:13:00 -1100</pubDate>
      <category>Silverlight</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=ecf6fb20-acf0-476e-be92-8c4a2b467bd0</pingback:target>
      <slash:comments>20</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=ecf6fb20-acf0-476e-be92-8c4a2b467bd0</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Why-I-Abandoned-Silverlight-for-ASPNET-MVC.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=ecf6fb20-acf0-476e-be92-8c4a2b467bd0</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=ecf6fb20-acf0-476e-be92-8c4a2b467bd0</feedburner:origLink></item>
    <item>
      <title>Visual Studio Power Commands Crashing Visual Studio When Opening a File</title>
      <description>&lt;p&gt;
I finally found the source of a problem that&amp;#39;s been plaguing me for a while: When working in Visual Studio I&amp;#39;ll double-click on a file and, rather than opening the file, Visual Studio simply closes. No error message, no explanation, just a vanishing IDE. Typically a restart of Visual Studio solves the problem, but I just finished installing ASP.NET MVC Preview 5 and now my IDE is closing &lt;em&gt;every&lt;/em&gt; time I try to open an .aspx view page, regardless of how many times I restart (or reinstall!) Visual Studio.
&lt;/p&gt;
&lt;p&gt;
I finally found the problem: the Visual Studio Power Commands plugin. After uninstalling it, I can open my files just fine. Thanks to &lt;a href="http://www.timvw.be/visual-studio-2008-sp1-crashes-when-opening-viewpage-in-designer/" target="_blank"&gt;Tim Van Wassenhove&lt;/a&gt; and many &lt;a href="http://haacked.com/archive/2008/09/05/mvcfutures-and-asp.net-mvc-beta.aspx" target="_blank"&gt;others on Phil Haack&amp;#39;s blog&lt;/a&gt; who pointed out the problem.
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/Lseg5rhgC48/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Visual-Studio-Power-Commands-Crashing-Visual-Studio-When-Opening-a-File.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=a5783f8a-34f3-43f4-8ded-81f6aa2cef9c</guid>
      <pubDate>Thu, 25 Sep 2008 17:52:00 -1100</pubDate>
      <category>Visual Studio</category>
      <category>ASP.NET MVC</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=a5783f8a-34f3-43f4-8ded-81f6aa2cef9c</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=a5783f8a-34f3-43f4-8ded-81f6aa2cef9c</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Visual-Studio-Power-Commands-Crashing-Visual-Studio-When-Opening-a-File.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=a5783f8a-34f3-43f4-8ded-81f6aa2cef9c</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=a5783f8a-34f3-43f4-8ded-81f6aa2cef9c</feedburner:origLink></item>
    <item>
      <title>Improved Mouse Wheel Support for Silverlight 2 Beta 2 ScrollViewer</title>
      <description>&lt;p&gt;
This is an update to &lt;a href="http://www.adamjcooper.com/blog/post/Mouse-Wheel-Scrolling-in-Silverlight-2-Beta-2.aspx" target="_blank"&gt;a previous post&lt;/a&gt;, but everything you need to easily add mouse wheel support to a Silverlight 2 Beta 2 ScrollViewer is listed here.
&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;
Silverlight 2 Beta 2&amp;#39;s ScrollViewer control doesn&amp;#39;t recognize the mouse scroll wheel, and implementing a workaround is difficult for two reasons: 1) the only way to listen for mouse wheel events is via the browser which hosts your Silverlight app, and 2) the ScrollViewer control doesn&amp;#39;t always fire the MouseLeave event when the mouse exits on the side where the scroll bar is, making it extremely difficult to know exactly which ScrollViewer the user is currently hovering over.
&lt;/p&gt;
&lt;p&gt;
Problem #1 has been solved fairly well by &lt;a href="http://www.wintellect.com/cs/blogs/jprosise/archive/2008/03/18/mousewheel-zooms-in-silverlight-2-0.aspx" target="_blank"&gt;Jeff Prosise&lt;/a&gt; and &lt;a href="http://blois.us/blog/2008/03/ive-heard-number-of-people-wondering.html" target="_blank"&gt;Peter Blois&lt;/a&gt;, but since they were interested in using the wheel for deep zoom and not the ScrollViewer, problem #2 was still left to be tackled.
&lt;/p&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;
I&amp;#39;ve created a small static class that you can use to easily &amp;quot;attach&amp;quot; mouse wheel support to your scroll viewers as your application is initializing. You basically set-and-forget each ScrollViewer and instantly get mouse wheel support.
&lt;/p&gt;
&lt;h2&gt;Demos&lt;/h2&gt;
&lt;p&gt;
Here are a couple of demos to show it in action:
&lt;/p&gt;
&lt;h3&gt;Default Behavior: Association by Hover&lt;/h3&gt;
&lt;p&gt;
The default behavior is for the mouse wheel to affect which ever ScrollViewer is most immediately under the cursor at the time of the last mouse movement.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/scrollviewermousewheeldemo/ScrollViewerMouseWheelDemoTestPage.aspx" target="_blank"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelSupportforSilverlight2Beta2Scr_D8F5/image_5.png" border="0" alt="image" width="404" height="280" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;
&lt;a href="http://www.adamjcooper.com/scrollviewermousewheeldemo/ScrollViewerMouseWheelDemoTestPage.aspx" target="_blank"&gt;Click here to run the default (hover) behavior demo...&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;Alternative Behavior: Association by Focus&lt;/h3&gt;
&lt;p&gt;
Alternatively, you can modify one method call to change the default behavior from hover-to-associate to click-to-associate.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/scrollviewermousewheeldemo/ScrollViewerMouseWheelByFocusDemoTestPage.aspx" target="_blank"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelSupportforSilverlight2Beta2Scr_D8F5/image_6.png" border="0" alt="image" width="404" height="281" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;
&lt;a href="http://www.adamjcooper.com/scrollviewermousewheeldemo/ScrollViewerMouseWheelByFocusDemoTestPage.aspx" target="_blank"&gt;Click here to run the focus behavior demo...&lt;/a&gt;
&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;h3&gt;Give Your ScrollViewers a Solid Background&lt;/h3&gt;
&lt;p&gt;
Even if you use my workaround API correctly, a ScrollViewer without a background won&amp;#39;t always get registered with the mouse wheel. So make sure you give your ScrollViewers a non-transparent background, even if it&amp;#39;s the same color as the background of the element behind it. If you don&amp;#39;t, the scroll wheel will only work when the mouse is interacting with non-whitespace in the ScrollViewer, which is generally not what you want.
&lt;/p&gt;
&lt;h3&gt;Initialize the Static Helper Class Exactly Once at the Root of the Application&lt;/h3&gt;
&lt;p&gt;
Your root control needs to call ScrollViewerMouseWheelSupport.Initialize for everything to work correctly, like this:
&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;MouseWheelDemo &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;UserControl&lt;/span&gt;{    &lt;span style="color: blue"&gt;public &lt;/span&gt;MouseWheelDemo()    {        InitializeComponent();        &lt;span style="color: green"&gt;//Initialize the static scroll viewer mouse wheel support class by providing a reference to the root visual.        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.Initialize(rootVisual);        .        .        .
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
Where &lt;strong&gt;rootVisual&lt;/strong&gt; is the root element of your application (usually it&amp;#39;s easiest to just give an instance name to the root element in your XAML and use it here).
&lt;/p&gt;
&lt;p&gt;
If you prefer the associate-by-click model, just call the Initialize method like so:
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.Initialize(rootVisual, &lt;span style="color: #2b91af"&gt;MouseWheelAssociationMode&lt;/span&gt;.OnFocus);
&lt;/pre&gt;
&lt;p&gt;
The important thing to know is that this method should only be called once by the entire application. You don&amp;#39;t need to call it for each control, just for the application itself.
&lt;/p&gt;
&lt;h2&gt;Register Multiple ScrollViewers Correctly&lt;/h2&gt;
&lt;h3&gt;Single ScrollViewer&lt;/h3&gt;
&lt;p&gt;
If you only have one ScrollViewer on the page, all you need to do is use the AddMouseWheelSupport extension method, like so:
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: green"&gt;//Register a single scroll viewer&lt;/span&gt;singleScrollViewer.AddMouseWheelSupport();
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h3&gt;Multiple ScrollViewers&lt;/h3&gt;
&lt;p&gt;
If you have multiple ScrollViewers--including any ScrollViewers that are part of controls such as drop-down menus or combo boxes that you&amp;#39;d like to add mouse wheel support for--then you need to know a few things about the proper order of registration (if you get it wrong, you&amp;#39;ll get strange results).
&lt;/p&gt;
&lt;p&gt;
Internally my implementation keeps track of a tree of all of the ScrollViewers in the app which have been registered for mouse wheel support. I&amp;#39;ve done my best to hide all the details under the hood, but I do require that you follow a particular order of registration: ScrollViewers which contain child ScrollViewers must be registered first before any of their children can be registered.
&lt;/p&gt;
&lt;p&gt;
I&amp;#39;ve overloaded the extension method to make registering multiple ScrollViewers a little bit easier, but ultimately everything can be done with a single method whose signature is:
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ScrollViewer &lt;/span&gt;AddMouseWheelSupport(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ScrollViewer &lt;/span&gt;parentScrollViewer, &lt;span style="color: #2b91af"&gt;ScrollViewer &lt;/span&gt;childScrollViewer, &lt;span style="color: blue"&gt;double &lt;/span&gt;scrollAmount)
&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
Technically you could do everything with just this method. If you were adding a root ScrollViewer that didn&amp;#39;t have a parent at all, you could call this as a simple static method (rather than an extension method) and pass in null for the first argument. But it&amp;#39;s a lot easier to use an overload like this, which also provides a default for the scrollAmount:
&lt;/p&gt;
&lt;pre class="code"&gt;
myScrollViewer.AddMouseWheelSupport();
&lt;/pre&gt;
&lt;p&gt;
Let&amp;#39;s say you have three ScrollViewers and scrollViewer1 contains scrollViewer2 which contains scrollViewer3. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelSupportforSilverlight2Beta2Scr_D8F5/image_thumb6_thumb2_2.png"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelSupportforSilverlight2Beta2Scr_D8F5/image_thumb6_thumb2_thumb.png" border="0" alt="image_thumb6_thumb2" width="706" height="364" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Here&amp;#39;s the long way to wire them up:
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(&lt;span style="color: blue"&gt;null&lt;/span&gt;, scrollViewer1, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(&lt;span style="color: blue"&gt;null&lt;/span&gt;, scrollViewer2, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(&lt;span style="color: blue"&gt;null&lt;/span&gt;, scrollViewer3, 30.0);
&lt;/pre&gt;
&lt;p&gt;
Or, you could tighten things up with these fluid overloads:&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport    &lt;/span&gt;.AddMouseWheelSupport(scrollViewer1)    .AddMouseWheelSupport(scrollViewer2)    .AddMouseWheelSupport(scrollViewer3);
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
Both do exactly the same thing; the second version is just cleaner. It begins by using an overload which passes in null for the parent and then returns scrollViewer1. The next two calls use the returned ScrollViewer as the parent and set up a specified child (scrollViewer2 is added as a child to scrollViewer1, and scrollViewer3 is added as a child to scrollViewer2).
&lt;/p&gt;
&lt;p&gt;
Or, let&amp;#39;s say you have one parent with four children--A, B, C, D--like this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelSupportforSilverlight2Beta2Scr_D8F5/image_thumb3_thumb2_2.png"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelSupportforSilverlight2Beta2Scr_D8F5/image_thumb3_thumb2_thumb.png" border="0" alt="image_thumb3_thumb2" width="710" height="362" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Here&amp;#39;s the long way to add mouse wheel support to all 5 ScrollViewers:
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(&lt;span style="color: blue"&gt;null&lt;/span&gt;, parent, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(parent, childA, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(parent, childB, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(parent, childC, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(parent, childD, 30.0);
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
And here&amp;#39;s the short way:
&lt;/p&gt;
&lt;pre class="code"&gt;
parent.AddMouseWheelSupport();parent.AddMouseWheelSupport(childA);parent.AddMouseWheelSupport(childB);parent.AddMouseWheelSupport(childC);parent.AddMouseWheelSupport(childD);
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
The API allows for variation, but that&amp;#39;s the basic usage.
&lt;/p&gt;
&lt;h2&gt;Limitations&lt;/h2&gt;
&lt;p&gt;
This only works with ScrollViewer. It does not affect any other scrolling control (such as a ListBox).
&lt;/p&gt;
&lt;h2&gt;Download&lt;/h2&gt;
&lt;p&gt;
Here is a zip archive of a Visual Studio 2008 SP1 solution that contains the workaround source code in its own project/assembly (Cooper.Silverlight.Controls) as well as the source for the demos listed above:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/downloads/scrollviewermousewheeldemo.zip" class="linkButton"&gt;Solution with Source Code and Demos (ScrollViewerMouseWheelDemo.zip)&lt;/a&gt;
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/0HKGVEdQIsg/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Improved-Mouse-Wheel-Support-for-Silverlight-2-Beta-2-ScrollViewer.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=30e687ee-d164-4001-97eb-52e7e5106dae</guid>
      <pubDate>Tue, 09 Sep 2008 08:48:00 -1100</pubDate>
      <category>Silverlight</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=30e687ee-d164-4001-97eb-52e7e5106dae</pingback:target>
      <slash:comments>18</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=30e687ee-d164-4001-97eb-52e7e5106dae</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Improved-Mouse-Wheel-Support-for-Silverlight-2-Beta-2-ScrollViewer.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=30e687ee-d164-4001-97eb-52e7e5106dae</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=30e687ee-d164-4001-97eb-52e7e5106dae</feedburner:origLink></item>
    <item>
      <title>Mouse Wheel Scrolling in Silverlight 2 Beta 2</title>
      <description>&lt;h2&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;UPDATE&lt;/font&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;
&lt;font color="#ff0000"&gt;&lt;strong&gt;I&amp;#39;ve put together &lt;/strong&gt;&lt;a href="http://www.adamjcooper.com/blog/post/Improved-Mouse-Wheel-Support-for-Silverlight-2-Beta-2-ScrollViewer.aspx"&gt;&lt;strong&gt;a much improved new version&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; that includes support for associating the mouse wheel by simply hovering over a ScrollViewer, as well as live demos and a more complete download example.&lt;/strong&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font color="#ff0000"&gt;&lt;strong&gt;Consider this post and the download deprecated. Please &lt;/strong&gt;&lt;a href="http://www.adamjcooper.com/blog/post/Improved-Mouse-Wheel-Support-for-Silverlight-2-Beta-2-ScrollViewer.aspx"&gt;&lt;strong&gt;see the new post&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;
So our company decided to go ahead with Silverlight 2 Beta 2 as the platform for our next application. Then one day during the middle of our development cycle we discovered that the ScrollViewer control doesn&amp;#39;t recognize the mouse wheel. Great. For a while we ignored it and were hoping Microsoft would release Silverlight 2 and solve the problem. Well, the Olympics came, and the Olympics went. Still no word on Silverlight 2. My best guess now is an update at PDC 2008 in October. But the unsettling silence from Redmond regarding Silverlight&amp;#39;s future means we may be waiting a while, and I&amp;#39;m tired of waiting.
&lt;/p&gt;
&lt;p&gt;
So, with a big head start from &lt;a href="http://www.wintellect.com/cs/blogs/jprosise/archive/2008/03/18/mousewheel-zooms-in-silverlight-2-0.aspx" target="_blank"&gt;Jeff Prosise&lt;/a&gt; and &lt;a href="http://blois.us/blog/2008/03/ive-heard-number-of-people-wondering.html" target="_blank"&gt;Peter Blois&lt;/a&gt;, I implemented a one-line extension method that adds mouse-wheel scrolling support to any ScrollViewer. All you need to do is call the method when your XAML page is getting setup:
&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;MyXamlPage &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;UserControl&lt;/span&gt;{    &lt;span style="color: blue"&gt;public &lt;/span&gt;MyXamlPage()    {        InitializeComponent();        &lt;span style="color: green"&gt;//Enables mouse wheel scrolling to this ScrollViewer instance        &lt;/span&gt;&lt;strong&gt;scrollViewer.AddMouseWheelSupport();&lt;/strong&gt;    }}
&lt;/pre&gt;
&lt;h2&gt;&lt;font face="Trebuchet MS"&gt;Why Not Extend ScrollViewer?&lt;/font&gt;&lt;/h2&gt;
&lt;p&gt;
Because &lt;strong&gt;ScrollViewer is a sealed class&lt;/strong&gt;. This made coming up with a solution extremely difficult.
&lt;/p&gt;
&lt;h2&gt;&lt;font face="Trebuchet MS"&gt;Behavior: A Focus/Blur Model&lt;/font&gt;&lt;/h2&gt;
&lt;p&gt;
&lt;font color="#ff0000"&gt;&lt;strong&gt;NOTE: The &lt;/strong&gt;&lt;a href="http://www.adamjcooper.com/blog/post/Improved-Mouse-Wheel-Support-for-Silverlight-2-Beta-2-ScrollViewer.aspx"&gt;&lt;strong&gt;new version&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; solves this problem and offers both a hover and focus behavior models.&lt;/strong&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The mouse wheel will only affect a particular ScrollViewer when the ScrollViewer is in &lt;strong&gt;focus&lt;/strong&gt;. What this means is that you&amp;#39;ll need to click on the ScrollViewer&amp;#39;s contents (or tab to it) before the wheel will do any scrolling.
&lt;/p&gt;
&lt;p&gt;
This is not what I wanted. I would have preferred for the mouse wheel to simply affect whatever the top most (as in z-index) ScrollViewer, whichever one happens to be directly under the cursor at the time the wheel turns. Doing this would be cake if it weren&amp;#39;t for a flaw in the ScrollViewer&amp;#39;s MouseLeave event. If MouseEnter and MouseLeave were guaranteed to always fire, you could use a simple stack to keep track of which ScrollViewer is currently top-most by pushing a ScrollViewer whenever mouse rolls in and popping a ScrollViewer whenever the mouse rolls out. Unfortunately, the ScrollViewer in Silverlight 2 Beta 2 only guarantees a MouseLeve event on three sides of the box: the side with the scroll bar doesn&amp;#39;t always fire. As far as I can tell this flaw makes automatically associating the top-most ScrollViewer with the mouse wheel a practical impossibility.
&lt;/p&gt;
&lt;p&gt;
So, for now, we have to rely on the GotFocus and LostFocus events and settle for a model where the user must explicitly click on a ScrollViewer before the mouse wheel can control it. Some might argue this is actually the better model of the two since you don&amp;#39;t get any nasty surprises when scrolling over content that itself contains another scrollable region (don&amp;#39;t you hate it when you&amp;#39;re racing the mouse wheel down a page and then you get &amp;quot;snagged&amp;quot; on some other scrolling region that you don&amp;#39;t want to scroll through?). But that said, I still think the advantages of a MouseEnter/MouseLeave model are better than those of a GotFocus/LostFocus model. If someone sees a straightforward way to modify my solution to do that, please let me know.
&lt;/p&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;h3&gt;Give Your ScrollViewer a Solid Background&lt;/h3&gt;
&lt;p&gt;
Because the ScrollViewer must receive focus before the mouse wheel can affect it, leaving the background empty/transparent is not a good idea. Why? Because when your user tries to click on some empty space in the ScrollViewer attempting to register focus, they&amp;#39;ll be frustrated to find it only works when they click on top of some text, a graphic, or a form input. But if you give the ScrollViewer a non-transparent background brush, your users can click anywhere in the ScrollViewer and Silverlight will fire the GotFocus event just fine.
&lt;/p&gt;
&lt;h3&gt;Register Multiple ScrollViewers Correctly&lt;/h3&gt;
&lt;p&gt;
If you only have one ScrollViewer on the page, just call the AddMouseWheelSupport as I did in the above example.
&lt;/p&gt;
&lt;p&gt;
However, if you have multiple ScrollViewers--including any ScrollViewers that are part of controls such as drop-down menus or combo boxes that you&amp;#39;d like to add mouse wheel support for--then you need to know a few things about the proper order of registration (if you get it wrong, you&amp;#39;ll get strange results).
&lt;/p&gt;
&lt;p&gt;
Internally my implementation keeps track of a tree of all of the ScrollViewers in the app which have been registered for mouse wheel support. I&amp;#39;ve done my best to hide all the details under the hood, but I do require that you follow a particular order of registration: ScrollViewers which contain child ScrollViewers must be registered first before any of their children can be registered.
&lt;/p&gt;
&lt;p&gt;
I&amp;#39;ve overloaded the extension method to make registering multiple ScrollViewers a little bit easier, but ultimately everything can be done with a single method whose signature is:
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ScrollViewer &lt;/span&gt;AddMouseWheelSupport(&lt;span style="color: blue"&gt;this &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ScrollViewer &lt;/span&gt;parentScrollViewer, &lt;span style="color: #2b91af"&gt;ScrollViewer &lt;/span&gt;childScrollViewer, &lt;span style="color: blue"&gt;double &lt;/span&gt;scrollAmount)
&lt;/pre&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
Technically you could do everything with just this method. If you were adding a root ScrollViewer that didn&amp;#39;t have a parent at all, you could call this as a simple static method (rather than an extension method) and pass in null for the first argument. But it&amp;#39;s a lot easier to use an overload like this, which also provides a default for the scrollAmount:
&lt;/p&gt;
&lt;pre class="code"&gt;
myScrollViewer.AddMouseWheelSupport();
&lt;/pre&gt;
&lt;p&gt;
Let&amp;#39;s say you have three ScrollViewers and scrollViewer1 contains scrollViewer2 which contains scrollViewer3. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelScrollinginSilverlight2Beta2_2A37/image_thumb6_2.png"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelScrollinginSilverlight2Beta2_2A37/image_thumb6_thumb.png" border="0" alt="image_thumb6" width="706" height="364" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Here&amp;#39;s the long way to wire them up:
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(&lt;span style="color: blue"&gt;null&lt;/span&gt;, scrollViewer1, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(&lt;span style="color: blue"&gt;null&lt;/span&gt;, scrollViewer2, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(&lt;span style="color: blue"&gt;null&lt;/span&gt;, scrollViewer3, 30.0);
&lt;/pre&gt;
&lt;p&gt;
Or, you could tighten things up with these fluid overloads:&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport    &lt;/span&gt;.AddMouseWheelSupport(scrollViewer1)    .AddMouseWheelSupport(scrollViewer2)    .AddMouseWheelSupport(scrollViewer3);
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
Both do exactly the same thing; the second version is just cleaner. It begins by using an overload which passes in null for the parent and then returns scrollViewer1. The next two calls use the returned ScrollViewer as the parent and set up a specified child (scrollViewer2 is added as a child to scrollViewer1, and scrollViewer3 is added as a child to scrollViewer2).
&lt;/p&gt;
&lt;p&gt;
Or, let&amp;#39;s say you have one parent with four children--A, B, C, D--like this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelScrollinginSilverlight2Beta2_2A37/image_thumb3_2.png"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/MouseWheelScrollinginSilverlight2Beta2_2A37/image_thumb3_thumb.png" border="0" alt="image_thumb3" width="710" height="362" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Here&amp;#39;s the long way to add mouse wheel support to all 5 ScrollViewers:
&lt;/p&gt;
&lt;pre class="code"&gt;
&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(&lt;span style="color: blue"&gt;null&lt;/span&gt;, parent, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(parent, childA, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(parent, childB, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(parent, childC, 30.0);&lt;span style="color: #2b91af"&gt;ScrollViewerMouseWheelSupport&lt;/span&gt;.AddMouseWheelSupport(parent, childD, 30.0);
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
And here&amp;#39;s the short way:
&lt;/p&gt;
&lt;pre class="code"&gt;
parent.AddMouseWheelSupport();parent.AddMouseWheelSupport(childA);parent.AddMouseWheelSupport(childB);parent.AddMouseWheelSupport(childC);parent.AddMouseWheelSupport(childD);
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
The API allows for variation, but that&amp;#39;s the basic usage.
&lt;/p&gt;
&lt;h2&gt;Code Listing and Download&lt;/h2&gt;
&lt;p&gt;
&lt;font color="#ff0000"&gt;&lt;strong&gt;The code listing and download have been removed in favor of the &lt;/strong&gt;&lt;a href="http://www.adamjcooper.com/blog/post/Improved-Mouse-Wheel-Support-for-Silverlight-2-Beta-2-ScrollViewer.aspx"&gt;&lt;strong&gt;newer, improved version&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/font&gt;
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/zM2NNy6OAYc/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Mouse-Wheel-Scrolling-in-Silverlight-2-Beta-2.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=5b2e744a-1f88-462e-9adc-5f933ba8df7f</guid>
      <pubDate>Mon, 08 Sep 2008 19:59:00 -1100</pubDate>
      <category>Silverlight</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=5b2e744a-1f88-462e-9adc-5f933ba8df7f</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=5b2e744a-1f88-462e-9adc-5f933ba8df7f</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Mouse-Wheel-Scrolling-in-Silverlight-2-Beta-2.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=5b2e744a-1f88-462e-9adc-5f933ba8df7f</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=5b2e744a-1f88-462e-9adc-5f933ba8df7f</feedburner:origLink></item>
    <item>
      <title>Getting WCF Services Running on IIS 6</title>
      <description>&lt;p&gt;
Getting WCF services up and running on IIS 6 isn&amp;#39;t hard if you know what to do. Here are the high points: 
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Make sure ASP.NET is installed and registered with IIS on your web server&lt;/li&gt;
	&lt;li&gt;Make sure WCF (.NET Framework 3.0/3.5) is installed&lt;/li&gt;
	&lt;li&gt;Make sure that the .svc extension is mapped to the ASP.NET ISAPI dll in IIS&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
For me, it was point 3 that was the big problem. I found a lot of advice on various forums saying I should run the ServiceModelReg.exe tool to re-register the mapping and then restart IIS, but it never took. continued to receive HTTP 405 errors when trying to access the service, and apparently I&amp;#39;m not the only person who had this problem as evidenced by &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2029550&amp;amp;SiteID=1" target="_blank"&gt;this forum post&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
The solution was simple: &lt;strong&gt;I needed to add a mapping for .svc in IIS 6&lt;/strong&gt;. It&amp;#39;s not hard if you&amp;#39;ve done it before, but if you&amp;#39;re not used to IIS 6&amp;#39;s sometimes illogical user interface you can waste a lot of time poking around with the mouse. So here&amp;#39;s a step-by-step guide. 
&lt;/p&gt;
&lt;h2&gt;How to Add the .svc Mapping to IIS 6&lt;/h2&gt;
&lt;p&gt;
Open Internet Information Services (IIS) Manager: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_2.png"&gt;&lt;img style="border: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_thumb.png" border="0" alt="image" width="801" height="601" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Right-click on the website (or an individual web application) that needs the .svc mapping, then click &lt;strong&gt;Properties&lt;/strong&gt;: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_4.png"&gt;&lt;img style="border: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_thumb_1.png" border="0" alt="image" width="801" height="600" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Go to the &lt;strong&gt;Home Directory&lt;/strong&gt; tab and click the &lt;strong&gt;Configuration&lt;/strong&gt; button: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_6.png"&gt;&lt;img style="border: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_thumb_2.png" border="0" alt="image" width="472" height="458" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Click the &lt;strong&gt;Add...&lt;/strong&gt; button to add a new application extension mapping: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_8.png"&gt;&lt;img style="border: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_thumb_3.png" border="0" alt="image" width="406" height="448" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Set the &lt;strong&gt;Executable&lt;/strong&gt; field to the location of the ASP.NET ISAPI dll, typically &lt;em&gt;&lt;strong&gt;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll&lt;/strong&gt;&lt;/em&gt; 
&lt;/p&gt;
&lt;p&gt;
Set the &lt;strong&gt;Extension&lt;/strong&gt; field to &lt;em&gt;&lt;strong&gt;.svc&lt;/strong&gt;&lt;/em&gt; 
&lt;/p&gt;
&lt;p&gt;
Accept the default values for everything else and click &lt;strong&gt;OK&lt;/strong&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_10.png"&gt;&lt;img style="border: 0px" src="http://adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/GettingYourAS.NETWCFServiceRunningonIIS6_951B/image_thumb_4.png" border="0" alt="image" width="429" height="243" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
And that&amp;#39;s it. Assuming you have ASP.NET and WCF (.NET 3.0/3.5) installed correctly on the server, adding this mapping should allow you to correctly serve up WCF services in your ASP.NET website (URLs that end in .svc). 
&lt;/p&gt;
&lt;p&gt;
(Note that if you&amp;#39;re adding this mapping to a website that has some applications with the mapping already in place, IIS will ask you to confirm if the new value should overwrite the old.) 
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/PRA46ofHXDo/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Getting-Your-ASPNET-WCF-Service-Running-on-IIS-6.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=2371bbcd-7730-4ea9-8d78-e75182c7a9fa</guid>
      <pubDate>Fri, 29 Aug 2008 03:36:00 -1100</pubDate>
      <category>IIS 6</category>
      <category>WCF</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=2371bbcd-7730-4ea9-8d78-e75182c7a9fa</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=2371bbcd-7730-4ea9-8d78-e75182c7a9fa</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Getting-Your-ASPNET-WCF-Service-Running-on-IIS-6.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=2371bbcd-7730-4ea9-8d78-e75182c7a9fa</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=2371bbcd-7730-4ea9-8d78-e75182c7a9fa</feedburner:origLink></item>
    <item>
      <title>How to Quickly Connect and Disconnect from a VPN by Leveraging the Command Line</title>
      <description>&lt;p&gt;
One of the things I dislike about Windows Vista is how many clicks it takes to connect to a VPN, and how I must wait for the connection to be completely established just to dismiss window when it is successful. I do most of my work remotely and connecting and disconnecting to and from a VPN is a part of my daily routine. I finally broke down today and found a faster way to connect and disconnect to and from a VPN.
&lt;/p&gt;
 
&lt;h2&gt;Using the Command Line&lt;/h2&gt; 
&lt;p&gt;
First things first: you can connect to any of your VPNs using the &lt;strong&gt;rasdial &lt;/strong&gt;command from the command line. 
&lt;/p&gt;
 
&lt;p&gt;
Here&amp;#39;s the format to connect:
&lt;/p&gt;
 
&lt;blockquote style="font-family: consolas"&gt;
	 
	&lt;p&gt;
	&lt;em&gt;&lt;strong&gt;rasdial entryname [username [password|*]] [/DOMAIN:domain] [/PHONE:phonenumber] [/CALLBACK:callbacknumber] [/PHONEBOOK:phonebookfile] [/PREFIXSUFFIX] &lt;/strong&gt;&lt;/em&gt;
	&lt;/p&gt;
&lt;/blockquote&gt;
 
&lt;p&gt;
And here&amp;#39;s the format to disconnect:  
&lt;/p&gt;
&lt;blockquote style="font-family: consolas"&gt;
	 
	&lt;p&gt;
	&lt;em&gt;&lt;strong&gt;rasdial [entryname] /DISCONNECT&lt;/strong&gt;&lt;/em&gt;
	&lt;/p&gt;
&lt;/blockquote&gt;
 
&lt;p&gt;
For example, if your VPN is named &amp;quot;My VPN&amp;quot;, your username is &amp;quot;johndoe&amp;quot; and your password is &amp;quot;password123&amp;quot;, you could connect to the VPN from the command line like this:  
&lt;/p&gt;
&lt;blockquote style="font-family: consolas"&gt;
	 
	&lt;p&gt;
	&lt;strong&gt;rasdial &amp;quot;My VPN&amp;quot; johndoe password123&lt;/strong&gt;
	&lt;/p&gt;
&lt;/blockquote&gt;
 
&lt;p&gt;
When you&amp;#39;re finished, you can disconnect like this:  
&lt;/p&gt;
&lt;blockquote style="font-family: consolas"&gt;
	 
	&lt;p&gt;
	&lt;strong&gt;rasdial &amp;quot;My VPN&amp;quot; /DISCONNECT&lt;/strong&gt;
	&lt;/p&gt;
&lt;/blockquote&gt;
 
&lt;h2&gt;Using Shortcuts&lt;/h2&gt; 
&lt;p&gt;
Once you&amp;#39;ve successfully connected and disconnected from the command line, it&amp;#39;s a piece of cake to create a new windows shortcut that you can execute at will anytime you need to connect or disconnect. Just choose a folder were you want to shortcut to live, right-click, click New, click Shortcut, and in the dialog that comes up simply paste your tested command line text into the box that is labeled &amp;quot;Type in the location of the item,&amp;quot; like so:
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/image_2.png"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/image_thumb.png" border="0" alt="image" width="665" height="502" /&gt;&lt;/a&gt; 
&lt;/p&gt;
 
&lt;p&gt;
Click Next, then give this shortcut a name, like &amp;quot;My VPN Connect&amp;quot;:
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/image_6.png"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/image_thumb_2.png" border="0" alt="image" width="662" height="500" /&gt;&lt;/a&gt; 
&lt;/p&gt;
 
&lt;p&gt;
Click Finish, and you&amp;#39;re done. Now you have a dedicated shortcut for connecting to your VPN:
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/image_8.png"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/image_thumb_3.png" border="0" alt="image" width="174" height="64" /&gt;&lt;/a&gt; 
&lt;/p&gt;
 
&lt;p&gt;
Follow the same procedure to create a corresponding &amp;quot;My VPN Disconnect.&amp;quot;
&lt;/p&gt;
 
&lt;h2&gt;Using a Launcher&lt;/h2&gt; 
&lt;p&gt;
I keep all of my VPN Connect/Disconnect shortcuts in a single folder that I&amp;#39;ve cataloged with my launcher (&lt;a href="http://launchy.net/" target="_blank"&gt;Launchy&lt;/a&gt;). Now all I have to do to connect or disconnect from a VPN is hit my launcher hot key, type a few letters of the shortcut and hit enter when I get what I&amp;#39;m after:
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/image_10.png"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/image_thumb_4.png" border="0" alt="image" width="491" height="157" /&gt;&lt;/a&gt; 
&lt;/p&gt;
 
&lt;p&gt;
No more hunting through the Windows Vista &amp;quot;Connect to a Network&amp;quot; list to find my VPN and then waiting for it to connect just so I can close the window that tells me it worked. Now I can connect or disconnect in just a few keystrokes.
&lt;/p&gt;
 
&lt;h2&gt;More Tips...&lt;/h2&gt; 
&lt;p&gt;
If you find information like this helpful, I highly recommend Neal Ford&amp;#39;s new book, &lt;a href="http://www.amazon.com/gp/product/0596519788?ie=UTF8&amp;amp;tag=adjco-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596519788" target="_blank"&gt;The Productive Programmer&lt;/a&gt;. He spends an entire chapter covering useful applications and tricks that you can use to accelerate your work.
&lt;/p&gt;
 
&lt;p&gt;
&lt;a href="http://www.amazon.com/gp/product/0596519788?ie=UTF8&amp;amp;tag=adjco-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596519788"&gt;&lt;img style="border-width: 0px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/HowtoQuicklyConnectandDisconnectfromaVPN_A748/TheProductiveProgrammer-Large_thumb.gif" border="0" alt="TheProductiveProgrammer-Large" width="300" height="395" /&gt;&lt;/a&gt;
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/BoW8wba4VrE/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/How-to-Quickly-Connect-and-Disconnect-from-a-VPN-by-Leveraging-the-Command-Line.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=9a5d5d7e-9148-40e6-94cf-adc3d713ec7f</guid>
      <pubDate>Tue, 05 Aug 2008 04:53:00 -1100</pubDate>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=9a5d5d7e-9148-40e6-94cf-adc3d713ec7f</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=9a5d5d7e-9148-40e6-94cf-adc3d713ec7f</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/How-to-Quickly-Connect-and-Disconnect-from-a-VPN-by-Leveraging-the-Command-Line.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=9a5d5d7e-9148-40e6-94cf-adc3d713ec7f</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=9a5d5d7e-9148-40e6-94cf-adc3d713ec7f</feedburner:origLink></item>
    <item>
      <title>Another Look at FireFox's Keyboard Shortcuts - A Lesson in How to Choose Your Shortcuts Wisely</title>
      <description>&lt;p&gt;
When first learning keyboard shortcuts, I typically look for a English relationship between the letter of the shortcut and the function I need to accomplish. But for some shortcuts, the letter chosen seems to have no connection with a word that&amp;#39;s related to what you&amp;#39;re trying to do. That&amp;#39;s because there are really two types of letter-based shortcuts: 1) shortcuts chosen &lt;em&gt;for their connection with a word&lt;/em&gt;, and 2) shortcuts chosen &lt;em&gt;for their location on the keyboard&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
For example, in Windows we&amp;#39;re used to common shortcuts like Ctrl+&lt;strong&gt;S&lt;/strong&gt; for &lt;strong&gt;S&lt;/strong&gt;ave, Ctrl+&lt;strong&gt;B&lt;/strong&gt; for &lt;strong&gt;B&lt;/strong&gt;old, Ctrl+&lt;strong&gt;I&lt;/strong&gt; for &lt;strong&gt;I&lt;/strong&gt;talic, and so on. But we&amp;#39;re also used to things like Ctrl+&lt;strong&gt;Z&lt;/strong&gt; for Undo, Ctrl+&lt;strong&gt;X&lt;/strong&gt; for Cut, and Ctrl+&lt;strong&gt;V&lt;/strong&gt; for Paste. Why didn&amp;#39;t they choose Ctrl+U for Undo? Because Ctrl+Z is easier to press, and Undo is a function we use a lot. The same is true for Ctrl+V: &amp;#39;V&amp;#39; has nothing to do with the word &amp;quot;Paste,&amp;quot; but the function of pasting is so related to the function of copying, it&amp;#39;s nice to have the copy and paste shortcut keys next to each other. Actually, the keyboard shortcut letters for Cut, Copy, and Paste (X, C, V) seem to have been chosen primarily for their location on the keyboard. The fact that &amp;#39;C&amp;#39; matches Copy and &amp;#39;X&amp;#39; has a linguistic association with Cut is just an added bonus.
&lt;/p&gt;
&lt;p&gt;
FireFox also includes a healthy mix of word-based and location-based Ctrl-key shortcuts. For example, Ctrl+&lt;strong&gt;T&lt;/strong&gt; for a new &lt;strong&gt;T&lt;/strong&gt;ab, Ctrl+&lt;strong&gt;P&lt;/strong&gt; to &lt;strong&gt;P&lt;/strong&gt;rint&lt;strong&gt;, &lt;/strong&gt;Ctrl+&lt;strong&gt;R&lt;/strong&gt; to &lt;strong&gt;R&lt;/strong&gt;eload, etc. But there are also many other keyboard shortcuts that have been chosen strictly for their location on the keyboard. Take a look:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/AnotherLookatFireFoxsKeyboardShortcutsAL_9B2F/HandFriendlyFirefoxKeyboardShortcuts_2.gif"&gt;&lt;img style="border: 0px none ; margin: 0px 0px 0px 10px" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/AnotherLookatFireFoxsKeyboardShortcutsAL_9B2F/HandFriendlyFirefoxKeyboardShortcuts_thumb.gif" border="0" alt="HandFriendlyFirefoxKeyboardShortcuts" width="596" height="287" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Most of these letters have nothing to do with their associated action, but they are very comfortable to use. Notice the grouping of Ctrl+&lt;strong&gt;L&lt;/strong&gt; and Ctrl+&lt;strong&gt;K&lt;/strong&gt;. Like the shortcuts for Cut, Copy, and Paste, getting into the Location Bar and getting into the web search box are common functions and go well together. The addition of Ctrl+&lt;strong&gt;J&lt;/strong&gt; hanging off to the left to open the list of downloads is also appropriate, since it&amp;#39;s also a function that involves navigation (though on the local file system).
&lt;/p&gt;
&lt;p&gt;
Once I discovered the reasoning behind why certain FireFox shortcut keys were chosen, it helped me to start using them more frequently. Location-based shortcut keys aren&amp;#39;t as obvious, but they are a pleasure to use. 
&lt;/p&gt;
&lt;p&gt;
A well-designed application will choose its keyboard shortcuts based on location and ease-of-use while at the same time choosing obvious language-based associations when possible to aid in memorization. Save is a common function, and Ctrl+S is easy to press, so choosing S as the letter of the shortcut makes sense. But when you&amp;#39;re setting up a shortcut for a commonly used application function and the most obvious letter is already taken or is not easy to reach, pick one that&amp;#39;s easy to press and forget about the letter.
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/N5VF_xA_zDU/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Another-Look-at-FireFoxs-Keyboard-Shortcuts-A-Lesson-in-How-to-Choose-Your-Shortcuts-Wisely.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=f632edac-09dc-4b54-9453-9a6cdc29fd1d</guid>
      <pubDate>Sat, 02 Aug 2008 04:05:00 -1100</pubDate>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=f632edac-09dc-4b54-9453-9a6cdc29fd1d</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=f632edac-09dc-4b54-9453-9a6cdc29fd1d</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Another-Look-at-FireFoxs-Keyboard-Shortcuts-A-Lesson-in-How-to-Choose-Your-Shortcuts-Wisely.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=f632edac-09dc-4b54-9453-9a6cdc29fd1d</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=f632edac-09dc-4b54-9453-9a6cdc29fd1d</feedburner:origLink></item>
    <item>
      <title>Ninja-Speed Browsing With FireFox Keyboard Shortcuts</title>
      <description>&lt;p&gt;
FireFox is full of keyboard shortcuts that can dramatically increase your web browsing productivity if you spend a little bit of time learning them.
&lt;/p&gt;
 
&lt;p&gt;
As an example to whet your appetite, consider the following workflow: 
&lt;/p&gt;
 
&lt;ul&gt;
	 
	&lt;li&gt;You need to execute a web search and place the results in a new tab  &lt;/li&gt;
	&lt;li&gt;What you&amp;#39;re looking for is the first result in the list  &lt;/li&gt;
	&lt;li&gt;You click the link &lt;/li&gt;
&lt;/ul&gt;
 
&lt;p&gt;
How do you do this? If your answer is &amp;quot;I would move my hand off of the keyboard, grab my mouse, click the search bar at the top of the browser, move my hand back to the keyboard, type my search, press enter, realize I need to click the first item in the list, move my hand back to the mouse, and finally click the first result in the list,&amp;quot; then you&amp;#39;re browsing the way I did for so long: slow. 
&lt;/p&gt;
 
&lt;p&gt;
Here&amp;#39;s how you would do this in FireFox using the keyboard: 
&lt;/p&gt;
 
&lt;ul&gt;
	 
	&lt;li&gt;&lt;strong&gt;Ctrl + K&lt;/strong&gt; - This moves you to the search box (you can also use Ctrl + E, but I use the pneumonic loo&lt;strong&gt;K&lt;/strong&gt; to remember Ctrl + K as being associated with search).  &lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Type your search&lt;/strong&gt; and &lt;strong&gt;press enter&lt;/strong&gt;.  &lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Press the &amp;#39; key&lt;/strong&gt; - This opens a find tool that only searches for link text, really handy when you want to move the focus to a link without grabbing the mouse.  &lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Type in a few identifying characters of the link you want to &amp;quot;click.&amp;quot;&lt;/strong&gt; For example, if the result in the list you need to click says &amp;quot;How to browse faster,&amp;quot; you might type &amp;quot;browse fas.&amp;quot; If you don&amp;#39;t &amp;quot;hit&amp;quot; the link you&amp;#39;re trying to click the first time, press F3 to go forward to the next link-search result or Shift + F3 to go backward until the link you&amp;#39;re after is highlighted.  &lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Press enter&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;
 
&lt;p&gt;
Try it for yourself. You can get around the web &lt;em&gt;very&lt;/em&gt; quickly this way. 
&lt;/p&gt;
 
&lt;h2&gt;Beginner&amp;#39;s Guide to Keyboard Browsing&lt;/h2&gt; 
&lt;p&gt;
Here are some of FireFox&amp;#39;s keyboard shortcuts. I&amp;#39;ve tried to categorize the keyboard shortcuts by practical use. You should be able to read this list from top to bottom and &amp;quot;discover&amp;quot; how to drive FireFox with the keyboard. In fact, I would encourage you to open a browser and work your way through this list to see just how easy it is to command from the keyboard. 
&lt;/p&gt;
 
&lt;h3&gt;The Fundamentals&lt;/h3&gt; 
&lt;table border="0" cellspacing="0" cellpadding="5" width="536"&gt;
	 
	&lt;tbody&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="304" valign="top"&gt;Select the location (address) bar&lt;/td&gt; 
			&lt;td width="230" valign="top"&gt;&lt;strong&gt;Ctrl + L&lt;/strong&gt; (for &lt;strong&gt;L&lt;/strong&gt;ocation)&lt;br /&gt;
			&lt;em&gt;or &lt;br /&gt;
			&lt;/em&gt;Alt + D&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="303" valign="top"&gt;Open location&lt;/td&gt; 
			&lt;td width="231" valign="top"&gt;&lt;strong&gt;Enter&lt;/strong&gt; while in the location bar&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Open location(or search result) in a new tab&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Alt + Enter &lt;/strong&gt;while in the location bar (or web search box)&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Auto-add &amp;quot;www.&amp;quot; and &amp;quot;.com&amp;quot; to what you&amp;#39;ve typed in the location bar (i.e. type &amp;quot;amazon&amp;quot; and have FireFox automatically convert it to &amp;quot;www.amazon.com&amp;quot;)&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + Enter &lt;/strong&gt;after typing in the location bar&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Auto-add &amp;quot;www.&amp;quot; and &amp;quot;.net&amp;quot; to what you&amp;#39;ve typed in the location bar (i.e. type &amp;quot;silverlight&amp;quot; and have FireFox automatically convert it to &amp;quot;www.silverlight.net&amp;quot;)&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Shift + Enter&lt;/strong&gt; after typing in the location bar&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Auto-add &amp;quot;www.&amp;quot; and &amp;quot;.org&amp;quot; to what you&amp;#39;ve typed in the location bar (i.e. type &amp;quot;blender&amp;quot; and have FireFox automatically convert it to &amp;quot;www.blender.org&amp;quot;)&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + Shift + Enter&lt;/strong&gt; after typing in the location bar&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Scroll within the page&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;Up and down arrows for single line, page up and page down for page&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Click a link&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Press the &amp;#39; key &lt;/strong&gt;to &amp;quot;search&amp;quot; the page for links. Type in part of the link text, ideally a part that is unique on the page. If necessery, use F3 and Shift + F3 to cycle forward/backward through the links on the page which match your search. Once the link is highlighted, &lt;strong&gt;press enter&lt;/strong&gt;.&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Back&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + Left Arrow&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Forward&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + Right Arrow&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Open a selected link in a new tab&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + Enter&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Open a selected link in a new window&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Shift + Enter&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Switch tabs&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + [0-9]&lt;/strong&gt; - You can immediately switch to any of the first 9 tabs you might have open by pressing Ctrl plus a number key (i.e. Ctrl + 3 switches to the third tab from the left).&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Close the current tab&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + W&lt;br /&gt;
			&lt;/strong&gt;&lt;em&gt;or&lt;/em&gt;&lt;br /&gt;
			&lt;strong&gt;Ctrl + F4&lt;/strong&gt;, much like Alt + F4 closes an entire window.&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Open a new tab&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + T&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Open a new window&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + N&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Move to the browser&amp;#39;s web search box&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + K&lt;/strong&gt; (as in loo&lt;strong&gt;K&lt;/strong&gt;)&lt;br /&gt;
			&lt;em&gt;or&lt;br /&gt;
			&lt;/em&gt;Ctrl + E (as in googl&lt;strong&gt;E&lt;/strong&gt; or liv&lt;strong&gt;E&lt;/strong&gt;)&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Switch the current search engine in the search box&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;While in the search box (Ctrl + K), press &lt;strong&gt;Ctrl + Down Arrow &lt;/strong&gt;or &lt;strong&gt;Ctrl + Up Arrow &lt;/strong&gt;to move through the search engine options.&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Bookmark current page&lt;/td&gt; 
			&lt;td width="233" valign="top"&gt;&lt;strong&gt;Ctrl + D&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Selecting text&lt;/td&gt; 
			&lt;td width="233" valign="top"&gt;Press &lt;strong&gt;F7&lt;/strong&gt; to start &amp;quot;Caret Browsing&amp;quot; mode. Basically FireFox puts a caret in the middle of the page much like you would see in a word processor. You can&amp;#39;t change the text, but you can move the caret with the keyboard to navigate the document and highlight text.&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
 
&lt;h3&gt;Shortcuts Developers Should Know&lt;/h3&gt; 
&lt;table border="0" cellspacing="0" cellpadding="5" width="536"&gt;
	 
	&lt;tbody&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="303" valign="top"&gt;View the HTML source of the current page&lt;/td&gt; 
			&lt;td width="231" valign="top"&gt;&lt;strong&gt;Ctrl + U&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Reload the page&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;F5&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Reload the page and force the browser&amp;#39;s cache to be ignored&lt;/td&gt; 
			&lt;td width="232" valign="top"&gt;&lt;strong&gt;Ctrl + F5&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		 
		&lt;tr&gt;
			 
			&lt;td width="302" valign="top"&gt;Display the error console&lt;/td&gt; 
			&lt;td width="233" valign="top"&gt;&lt;strong&gt;Ctrl + Shift + J&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
 
&lt;h3&gt;The Complete List&lt;/h3&gt; 
&lt;p&gt;
You can find the complete list of keyboard shortcuts at Mozilla&amp;#39;s FireFox website: &lt;a href="http://support.mozilla.com/en-US/kb/Keyboard+shortcuts" title="http://support.mozilla.com/en-US/kb/Keyboard+shortcuts"&gt;http://support.mozilla.com/en-US/kb/Keyboard+shortcuts&lt;/a&gt; 
&lt;/p&gt;
 
&lt;p&gt;
If you learn the FireFox keyboard shortcuts, and learn them well, you&amp;#39;ll find your browser experience involves a lot less friction. Don&amp;#39;t be surprised if you still reach for the mouse at first out of habit, but once you learn how to use the keyboard there&amp;#39;s no going back. 
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/xaVR3zc-BkM/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Ninja-Speed-Browsing-With-FireFox-Keyboard-Shortcuts.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=5f8d0039-645d-4449-9f9e-fa034defdfbd</guid>
      <pubDate>Fri, 01 Aug 2008 18:59:00 -1100</pubDate>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=5f8d0039-645d-4449-9f9e-fa034defdfbd</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=5f8d0039-645d-4449-9f9e-fa034defdfbd</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Ninja-Speed-Browsing-With-FireFox-Keyboard-Shortcuts.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=5f8d0039-645d-4449-9f9e-fa034defdfbd</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=5f8d0039-645d-4449-9f9e-fa034defdfbd</feedburner:origLink></item>
    <item>
      <title>Silverlight ListBox SelectedItem/SelectedIndex Visual State Bug Workaround</title>
      <description>&lt;p&gt;
There is a UI bug in Silverlight 2 Beta 2&amp;#39;s ListBox that has become a problem for me recently: When you set the SelectedItem or SelectedIndex property to programatically alter the current selection, the internal state of the ListBox is correctly updated, but the visual representation is not. From the user&amp;#39;s perspective, it appears that nothing has been selected. You can &lt;a href="http://blogs.msdn.com/delay/archive/2008/03/05/lb-sv-faq-examples-notes-tips-and-more-for-silverlight-2-beta-1-s-listbox-and-scrollviewer-controls.aspx" target="_blank"&gt;read more about this bug at Delay&amp;#39;s Blog&lt;/a&gt; (make sure you scroll down to the section titled &amp;quot;ListBox Bugs&amp;quot;).
&lt;/p&gt;
&lt;p&gt;
Delay offers a workaround, but it suffers from a flaw that you don&amp;#39;t want to use in production code: each time his workaround is executed, a new but identical event handler is assigned to the LayoutUpdated event so that the more the workaround is used the larger the event handler list grows and the more redundant code is executed each time. It&amp;#39;s both a memory leak and a potential performance bottleneck. Delay himself acknowledges the problem in the comments of his blog. But his basic idea, which is all he was trying to share, is sound.
&lt;/p&gt;
&lt;p&gt;
So here is an updated version of Delay&amp;#39;s workaround which you should be able to use in production code. Rather than using extension methods which you must explicitly call each time you set SelectedItem or SelectedIndex, this version extends the ListBox class. You can use this class as a replacement for the Silverlight 2 Beta 2 ListBox and the UI will correctly update when you change SelectedItem or SelectedIndex.
&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;namespace &lt;/span&gt;Cooper.Silverlight.Controls
{
    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ListBox &lt;/span&gt;: System.Windows.Controls.&lt;span style="color: #2b91af"&gt;ListBox
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;private bool &lt;/span&gt;_visualSelectionNeedsUpdating;
        &lt;span style="color: blue"&gt;private int &lt;/span&gt;_selectedIndex;

        &lt;span style="color: blue"&gt;public &lt;/span&gt;ListBox()
            : &lt;span style="color: blue"&gt;base&lt;/span&gt;()
        {
            LayoutUpdated += &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;EventHandler&lt;/span&gt;(ListBox_LayoutUpdated);
        }

        &lt;span style="color: blue"&gt;private void &lt;/span&gt;ListBox_LayoutUpdated(&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;(_visualSelectionNeedsUpdating)
            {
                &lt;span style="color: green"&gt;//Toggle value to force change
                &lt;/span&gt;&lt;span style="color: blue"&gt;base&lt;/span&gt;.SelectedIndex = -1;
                &lt;span style="color: blue"&gt;base&lt;/span&gt;.SelectedIndex = _selectedIndex;
                
                VisualSelectionNeedsUpdating = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
            }
        }

        &lt;span style="color: blue"&gt;private bool &lt;/span&gt;VisualSelectionNeedsUpdating
        {
            &lt;span style="color: blue"&gt;get
            &lt;/span&gt;{
                &lt;span style="color: blue"&gt;return &lt;/span&gt;_visualSelectionNeedsUpdating;
            }
            &lt;span style="color: blue"&gt;set
            &lt;/span&gt;{
                _visualSelectionNeedsUpdating = &lt;span style="color: blue"&gt;value&lt;/span&gt;;

                &lt;span style="color: blue"&gt;if &lt;/span&gt;(_visualSelectionNeedsUpdating)
                    _selectedIndex = SelectedIndex;
            }
        }
        
        &lt;span style="color: blue"&gt;public new int &lt;/span&gt;SelectedIndex
        {
            &lt;span style="color: blue"&gt;get
            &lt;/span&gt;{
                &lt;span style="color: blue"&gt;return base&lt;/span&gt;.SelectedIndex;
            }
            &lt;span style="color: blue"&gt;set
            &lt;/span&gt;{
                &lt;span style="color: blue"&gt;base&lt;/span&gt;.SelectedIndex = &lt;span style="color: blue"&gt;value&lt;/span&gt;;

                VisualSelectionNeedsUpdating = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
            }
        }

        &lt;span style="color: blue"&gt;public new object &lt;/span&gt;SelectedItem
        {
            &lt;span style="color: blue"&gt;get
            &lt;/span&gt;{
                &lt;span style="color: blue"&gt;return base&lt;/span&gt;.SelectedItem;
            }
            &lt;span style="color: blue"&gt;set
            &lt;/span&gt;{
                &lt;span style="color: blue"&gt;base&lt;/span&gt;.SelectedItem = &lt;span style="color: blue"&gt;value&lt;/span&gt;;

                VisualSelectionNeedsUpdating = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
            }
        }
    }
}
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;
This solution does not address the ListBoxItem class&amp;#39;s IsSelected property, but for my needs it is acceptable until RTM.
&lt;/p&gt;
&lt;p&gt;
Thanks for showing us the way, Delay.
&lt;/p&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/jVRa9uWBlvg/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Silverlight-ListBox-SelectedItemSelectedIndex-Visual-State-Bug-Workaround.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=fef7cf68-d24b-4f13-96fc-ca53f8a4bf0e</guid>
      <pubDate>Fri, 01 Aug 2008 07:19:00 -1100</pubDate>
      <category>Silverlight</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=fef7cf68-d24b-4f13-96fc-ca53f8a4bf0e</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=fef7cf68-d24b-4f13-96fc-ca53f8a4bf0e</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Silverlight-ListBox-SelectedItemSelectedIndex-Visual-State-Bug-Workaround.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=fef7cf68-d24b-4f13-96fc-ca53f8a4bf0e</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=fef7cf68-d24b-4f13-96fc-ca53f8a4bf0e</feedburner:origLink></item>
    <item>
      <title>Snippets for Boilerplate Code When Overriding Equality and Hash Code</title>
      <description>&lt;p&gt;Overriding Equals and GetHashCode is easy, but implementing them correctly is not. As Jonathan Allen says in his excellent article &lt;a href="http://www.infoq.com/articles/Equality-Overloading-DotNET"&gt;&lt;em&gt;A Detailed look at Overriding the Equality Operator&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, &lt;/em&gt;"It is surprisingly easy to make a mistake when overriding the equality operator. Not only does the equality operator bring along with it a lot of baggage, there is a lot of flawed guidance out there, even on the MSDN website. So we are going to try to clear the air by presenting a systematic breakdown of both a reference type and a value type that supports equality." Jonathan then goes on to provide guidance and code examples when overriding Equals or GetHashCode in a class or struct.&lt;/p&gt; &lt;p&gt;Using Jonathan's code examples as a starting point, I've created a couple of Visual Studio snippets, one for class and one for struct, to blast out all of the boilerplate code associated with overriding equality and hash code, allowing you to focus on implementing what's important.&lt;/p&gt; &lt;p&gt;Here's a 30-second demo to show you what it does:&lt;/p&gt; &lt;p&gt;&lt;a href="Screencasts/EqualitySnippet/EqualitySnippet.htm" target="_blank"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="484" alt="Title" src="http://www.adamjcooper.com/blog/image.axd?picture=WindowsLiveWriter/SnippetsforBoilerplateCodeWhenOverriding_110CE/Title_3.png" width="644" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;There are two snippets, one for class and one for struct, as outlined in Allen's original article. You can them here:&lt;/p&gt; &lt;p&gt;&lt;a class="linkButton" href="http://adamjcooper.com/downloads/EqualityAndHashCodeSnippets.zip"&gt;&lt;strong&gt;Equality and Hash Code Boilerplate Snippets for Class and Struct in C# (ZIP file)&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Just unzip the file and use the Code Snippets Manager in Visual Studio to add these snippets to your environment (for Visual Studio 2008, click Tools... Code Snippets Manager... or Ctrl + K, Ctrl + B).&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/SQmq9WIZLVQ/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Snippets-for-Boilerplate-Code-When-Overriding-Equality-and-Hash-Code.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=bea1dd26-e582-4265-834c-f1e46f479027</guid>
      <pubDate>Thu, 31 Jul 2008 12:33:41 -1100</pubDate>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=bea1dd26-e582-4265-834c-f1e46f479027</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=bea1dd26-e582-4265-834c-f1e46f479027</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Snippets-for-Boilerplate-Code-When-Overriding-Equality-and-Hash-Code.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=bea1dd26-e582-4265-834c-f1e46f479027</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=bea1dd26-e582-4265-834c-f1e46f479027</feedburner:origLink></item>
    <item>
      <title>The Quest for Quick-and-Easy Immutable Value Objects in C#</title>
      <description>&lt;h2&gt;Definition of Terms&lt;/h2&gt;
&lt;p&gt;
In the following discussion I will use the term &lt;em&gt;Value Object &lt;/em&gt;to refer to an object which:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;expresses only a value, or set of related values &lt;/li&gt;
	&lt;li&gt;has no identity &lt;/li&gt;
	&lt;li&gt;is typically immutable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This is a standard description of a &lt;em&gt;Value Object&lt;/em&gt; as given by Domain Driven Design (see &lt;a href="http://www.domaindrivendesign.org/discussion/messageboardarchive/ValueObjects.html"&gt;the Value Object definition at domaindrivendesign.org&lt;/a&gt;, or see Evans, &lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FDomain-Driven-Design-Tackling-Complexity-Software%2Fdp%2F0321125215%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1212515284%26sr%3D8-1&amp;amp;tag=adjco-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325"&gt;Domain Driven Design&lt;/a&gt;&lt;img style="margin: 0px; border-style: none! important" src="http://www.assoc-amazon.com/e/ir?t=adjco-20&amp;amp;l=ur2&amp;amp;o=1" border="0" alt="" width="1" height="1" /&gt; p. 97ff; cf. Fowler, &lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FEnterprise-Application-Architecture-Addison-Wesley-Signature%2Fdp%2F0321127420%2F&amp;amp;tag=adjco-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325"&gt;PoEAA&lt;/a&gt;&lt;img style="margin: 0px; border-style: none! important" src="http://www.assoc-amazon.com/e/ir?t=adjco-20&amp;amp;l=ur2&amp;amp;o=1" border="0" alt="" width="1" height="1" /&gt;, front cover and p. 486ff). I will use the term &lt;a href="http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx"&gt;value type&lt;/a&gt; to refer to something more specific: any .NET type which derives from System.ValueType. In C#, this means structs, enums, and most of your built-in types (excluding string). &lt;strong&gt;A &lt;em&gt;Value Object&lt;/em&gt; is a concept or pattern while a value type is a concrete part of the .NET framework. In .NET, a &lt;em&gt;Value Object&lt;/em&gt; could be implemented using either a value type (struct) or a reference type (class).&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Great, now on to the real stuff...
&lt;/p&gt;
&lt;h2&gt;Aren&amp;#39;t Structs Enough?&lt;/h2&gt;
&lt;p&gt;
Martin Fowler in &lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FEnterprise-Application-Architecture-Addison-Wesley-Signature%2Fdp%2F0321127420%2F&amp;amp;tag=adjco-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325"&gt;PoEAA&lt;/a&gt; has this to say about Value Objects in .NET:
&lt;/p&gt;
&lt;blockquote&gt;
	.NET has a first-class treatment of &lt;em&gt;Value Object&lt;/em&gt;. In C# an object is marked as a &lt;em&gt;Value Object&lt;/em&gt; by declaring it as a struct instead as a class [sic]. The environment then treats it with value semantics.
&lt;/blockquote&gt;
&lt;p&gt;
While it&amp;#39;s true that structs do offer built-in value-based equality and hash code, structs have some important limitations you should be aware of before you consider them the absolute solution for all your Value Object implementation needs:
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Structs do not allow inheritance. &lt;/strong&gt;If you need to create a new &lt;em&gt;Value Object&lt;/em&gt; that extends some base object, structs won&amp;#39;t allow you to do it. This is not an uncommon situation for me: I may have an Address &lt;em&gt;Value Object&lt;/em&gt; that serves as a base international address, and then derive a country-specific address, such as USAddress, from it. I can&amp;#39;t do this with structs. &lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Structs cannot guarantee construction to a valid state. &lt;/strong&gt;Structs always include a default, parameterless constructor which initializes every field to its default value (such as null or 0). What this means is that, even if you provide a constructor that takes parameters to fully initialize all of the Value Object&amp;#39;s internal fields, there is no guarantee that a caller won&amp;#39;t bypass it and use the default constructor instead. Consider an Address &lt;em&gt;Value Object&lt;/em&gt; implemented as a struct that expects it&amp;#39;s fields to be populated before it can be used; there&amp;#39;s nothing stopping someone from simply passing a new Address() to a method in your domain model that expects a correctly-initialized Address which then chokes on a bunch of null data. &lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Structs do not offer built-in immutability (and neither to classes). &lt;/strong&gt;This really isn&amp;#39;t a criticism of structs as much as a clarification of Mr. Fowler&amp;#39;s advice. Usually, your &lt;em&gt;Value Objects&lt;/em&gt; should be immutable. There are exceptions to this (see Evans, Domain Driven Design, p. 101, side column), but generally speaking you want immutability by default. For this reason, I don&amp;#39;t consider a struct to be a &amp;quot;first-class treatment&amp;quot; of &lt;em&gt;Value Object&lt;/em&gt; implementation. It&amp;#39;s as close as you get, but just understand that if you want true immutability, you have to do all of the same grunt-work as you would with a class: readonly fields, get-only properties, and an appropriate constructor to initialize the object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Luca Bolognese offers &lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx"&gt;even more reasons why structs aren&amp;#39;t the ideal solution for implementing Value Objects&lt;/a&gt;, but to me the lack of inheritance and construction are the two most significant. 
&lt;/p&gt;
&lt;h2&gt;Structs vs. Classes: Lots of Typing Either Way You Slice It&lt;/h2&gt;
&lt;p&gt;
The truth is, neither structs nor classes offer quick-and-easy implementation of immutable &lt;em&gt;Value Objects. &lt;/em&gt;They each have their own advantages and disadvantages, but they also both share some similar shortcomings that you&amp;#39;ll have to face regardless of which one you use. To illustrate this, here is a comparison of structs and classes with regards to their suitability for Value Object implementation. I&amp;#39;ve colored aspects of each in &lt;strong&gt;&lt;font color="#ff0000"&gt;red&lt;/font&gt; &lt;/strong&gt;if it makes implementing a &lt;em&gt;Value Object &lt;/em&gt;more difficult, and in &lt;font color="#008000"&gt;green &lt;/font&gt;if it makes it easier:
&lt;/p&gt;
&lt;table border="0" cellspacing="0" cellpadding="0" width="600"&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td width="298" valign="top" style="padding: 0.5em"&gt;&lt;strong&gt;struct&lt;/strong&gt;&lt;/td&gt;
			&lt;td width="300" valign="top" style="padding: 0.5em"&gt;&lt;strong&gt;class&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td width="298" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;value type (stack)&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
			&lt;td width="300" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;reference type (heap)&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td width="298" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;cannot be null&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
			&lt;td width="300" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;can be null&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td width="298" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;does not allow inheritance&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
			&lt;td width="300" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#008000"&gt;allows inheritance&lt;/font&gt;&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td width="298" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;always includes a default constructor&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
			&lt;td width="300" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;can require a specific constructor&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td width="298" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#008000"&gt;automatic implementation of Equals and GetHashCode based on value&lt;/font&gt;&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
			&lt;td width="300" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Equals and GetHashCode must be overridden for value-based equality&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td width="298" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;must override == and != operators&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
			&lt;td width="300" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;must override == and != operators&lt;/strong&gt;&lt;/font&gt;&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td width="298" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;immutable properties require a lot of typing to implement: &lt;/strong&gt;&lt;/font&gt;
				&lt;ul&gt;
					&lt;li&gt;&lt;font color="#ff0000"&gt;a private, readonly field&lt;/font&gt; &lt;/li&gt;
					&lt;li&gt;&lt;font color="#ff0000"&gt;a public get-only property&lt;/font&gt; &lt;/li&gt;
					&lt;li&gt;&lt;font color="#ff0000"&gt;a corresponding constructor for initialization&lt;/font&gt;&lt;/li&gt;
				&lt;/ul&gt;
				&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
			&lt;td width="300" valign="top"&gt;
			&lt;ul&gt;
				&lt;li&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;immutable properties require a lot of typing to implement: &lt;/strong&gt;&lt;/font&gt;
				&lt;ul&gt;
					&lt;li&gt;&lt;font color="#ff0000"&gt;a private, readonly field&lt;/font&gt; &lt;/li&gt;
					&lt;li&gt;&lt;font color="#ff0000"&gt;a public get-only property&lt;/font&gt; &lt;/li&gt;
					&lt;li&gt;&lt;font color="#ff0000"&gt;a corresponding constructor for initialization&lt;/font&gt;&lt;/li&gt;
				&lt;/ul&gt;
				&lt;/li&gt;
			&lt;/ul&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
So if you use a struct, you gain automatic equality and hash code implementation (though &lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx"&gt;it requires boxing&lt;/a&gt;), but you lose inheritance and absolute control of construction. If you use a class, you gain inheritance and and construction control, but then you&amp;#39;re faced with having to manually implement value-based equality and hash code. But either way you go, there&amp;#39;s a lot of repetitive typing required.
&lt;/p&gt;
&lt;p&gt;
For example, let&amp;#39;s say we wanted to define simple Value Object called &lt;strong&gt;PersonName&lt;/strong&gt; that had two string properties: &lt;strong&gt;FirstName&lt;/strong&gt; and &lt;strong&gt;LastName&lt;/strong&gt;. A minimal class-based implementation in C# might look like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
    
    public class PersonName
    {
        private readonly string _firstName;
        private readonly string _lastName;

        public PersonName(string firstName, string lastName)
        {
            _firstName = firstName;
            _lastName = lastName;
        }

        public string FirstName
        {
            get { return _firstName; }
        }

        public string LastName
        {
            get { return _lastName; }
        }

        public PersonName NewFirstName(string newFirstName)
        {
            return new PersonName(newFirstName, LastName);
        }

        public PersonName NewLastName(string newLastName)
        {
            return new PersonName(FirstName, newLastName);
        }

        #region Equality and Hash Code

        public override bool Equals(object obj)
        {
            var temp = obj as PersonName;

            if (!object.ReferenceEquals(temp, null))
                return this.Equals(temp);

            return false;
        }

        public static bool operator ==(PersonName left, PersonName right)
        {
            return object.Equals(left, right);
        }

        public static bool operator !=(PersonName left, PersonName right)
        {
            return !(left == right);
        }

        public bool Equals(PersonName other)
        {
            if (object.ReferenceEquals(other, null))
                return false;
            else if (object.ReferenceEquals(other, this))
                return true;

            return (this.FirstName == other.FirstName &amp;amp;&amp;amp; this.LastName == other.LastName);
        }

        public override int GetHashCode()
        {
            int hashCode = 0;

            hashCode = (hashCode * 37) + (FirstName == null ? 0 : FirstName.GetHashCode());
            hashCode = (hashCode * 37) + (LastName == null ? 0 : LastName.GetHashCode());

            return hashCode;
        }

        #endregion
    }
&lt;/pre&gt;
&lt;p&gt;
A struct-based implementation (if we&amp;#39;re comfortable with the nature of a struct) is a little better, but not much:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
    
    public struct PersonName
    {
        private readonly string _firstName;
        private readonly string _lastName;

        public PersonName(string firstName, string lastName)
        {
            _firstName = firstName;
            _lastName = lastName;
        }

        public string FirstName
        {
            get { return _firstName; }
        }

        public string LastName
        {
            get { return _lastName; }
        }

        public PersonName NewFirstName(string newFirstName)
        {
            return new PersonName(newFirstName, LastName);
        }

        public PersonName NewLastName(string newLastName)
        {
            return new PersonName(FirstName, newLastName);
        }

        #region Equality Operators

        public static bool operator ==(PersonName left, PersonName right)
        {
            return object.Equals(left, right);
        }

        public static bool operator !=(PersonName left, PersonName right)
        {
            return !(left == right);
        }

        #endregion
    }
&lt;/pre&gt;
&lt;p&gt;
All of that just to get an immutable &lt;em&gt;Value Object &lt;/em&gt;with two properties. Either way you go, class or struct, it&amp;#39;s still a lot of noise.
&lt;/p&gt;
&lt;h2&gt;So What Do We Need?&lt;/h2&gt;
&lt;p&gt;
What we need is an easy way to quickly implement an immutable &lt;em&gt;Value Object&lt;/em&gt;. We should simply have to specify the name of our &lt;em&gt;Value Object&lt;/em&gt;, the names and types of each of its properties, and all of the boilerplate stuff should be done for us: equality, hash code, a standard constructor for our fields, and optionally some helper methods to create new value objects by specifying a new value for a property (like NewFirstName and NewLastName). 
&lt;/p&gt;
&lt;p&gt;
This is a simplification of the problem, though, because in practice there&amp;#39;s a lot of little stuff that often needs tweaking. For example, you may need to tweak the Equals or GetHashCode method (say to ignore the case of some of your string-based properties), you may need to do something a lot more complex in your constructor than merely assign values to fields, or you may need to call a base constructor and pass in certain pre-defined values, etc. Ideally, we should have some way of specifying the basic outline of a value object--it&amp;#39;s name and properties--have the boilerplate stuff generated for us, but still have the option of stepping in and hand-tuning anything that needs it.
&lt;/p&gt;
&lt;h2&gt;Luca Bolognese&amp;#39;s Approach&lt;/h2&gt;
&lt;p&gt;
Luca Bolognese has &lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;blogged about much the same thing&lt;/a&gt; as I have above, and his quest for quick-and-easy immutable &lt;em&gt;Value Objects &lt;/em&gt;in C# led him to &lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;creating a library of objects that model functional programming concepts which he borrowed from F#&lt;/a&gt;! I actually spent quite a bit of time with Luca&amp;#39;s idea, but in the end decided that his library-approach didn&amp;#39;t provide the level of fine-grained control I was after. Nevertheless, I learned a lot from Luca and came away with my own version of his library that I&amp;#39;ll definitely be using in the future.
&lt;/p&gt;
&lt;h2&gt;My Quest&lt;/h2&gt;
&lt;p&gt;
I&amp;#39;ve spent a lot of time over the past month in pursuit of an easy way to implement &lt;em&gt;Value Objects &lt;/em&gt;in C#. My quest for the &lt;em&gt;Value Object &lt;/em&gt;Holy Grail has led me from snippets, to macros, to code generating classes configured by XML and harnessed by text templates in Visual Studio. I&amp;#39;ll be blogging about each of them individually in future posts.
&lt;/p&gt;
&lt;h2&gt;Suggestions for the C# Team&lt;/h2&gt;
&lt;p&gt;
It would be nice if we had built-in language support for immutable &lt;em&gt;Value Objects&lt;/em&gt;. 
&lt;/p&gt;
&lt;p&gt;
A step in the right direction would be to allow readonly as a modifier to property setters. With this, we could reduce the standard immutable property code to a simple public string FirstName { get; readonly set; }. While I&amp;#39;ve wanted this feature for a while, more is needed to complete the picture: we need the compiler to help us with equality and hash code support.
&lt;/p&gt;
&lt;p&gt;
What if there were just one or two new keywords which we could use to designate to the C# compiler
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;that we want equality and hash code automatically implemented for a class, and &lt;/li&gt;
	&lt;li&gt;which fields/properties/methods should be used for the equality and hash code computation. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Perhaps something along the lines of:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
    //The keyword &amp;quot;valueobject&amp;quot; indicates that Equals(object), Equals(PersonName), ==, !=, 
    //and GetHashCode should all be automatically generated by the compiler based on the use
    //of &amp;quot;valueitem&amp;quot; (see below).
    public valueobject class PersonName
    {
        //The keyword &amp;quot;valueitem&amp;quot; indicates that this property
        //should be used when calculating equality and hash code
        public valueitem string FirstName { get; readonly set; };

        //Here this property would *not* be considered for equality/hash code.
        //Instead, we&amp;#39;ll use a custom, private property (below) so that our equality
        //and hash code use a modified version.
        public string LastName { get; readonly set; };

        //Constructor implementation is still done as usual to give us complete control.
        //Note, though, the use of the readonly property setters.
        public PersonName(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }

        //Rather than use LastName directly, we instruct the compiler to use this property
        //as part of the equality/hash code computation, allowing us to ignore the case 
        //of the last name.
        private valueitem string LastNameValueItem { get { return LastName.ToLower(); } }
    }
&lt;/pre&gt;
&lt;p&gt;
Then, we could do something like this:
&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;
	PersonName adamCooper1 = new PersonName(&amp;quot;Adam&amp;quot;, &amp;quot;Cooper&amp;quot;);
	PersonName adamCooper2 = new PersonName(&amp;quot;Adam&amp;quot;, &amp;quot;COOPER&amp;quot;);
	PersonName johnDoe = new PersonName(&amp;quot;John&amp;quot;, &amp;quot;Doe&amp;quot;);
	PersonName adamCooperIncorrectFirstNameCase = new PersonName(&amp;quot;adam&amp;quot;, &amp;quot;Cooper&amp;quot;);

	//Writes &amp;quot;false&amp;quot; since these two objects clearly have different values
	Console.WriteLine(adamCooper1 == johnDoe);

	//Writes &amp;quot;true&amp;quot; since our object ignores last name case
	Console.WriteLine(adamCooper1 == adamCooper2);

	//Writes &amp;quot;false&amp;quot; since our object requires first names to be identical in case
	Console.WriteLine(adamCooper1 == adamCooperIncorrectFirstNameCase);
&lt;/pre&gt;
&lt;p&gt;
This is a short example, but you can easily see how powerful just a couple of new keywords and the ability to create readonly property setters would be. I&amp;#39;d love to hear what other folks think about this idea, both inside and outside Microsoft.
&lt;/p&gt;
&lt;p&gt;
The most glaring problem I see is how to &amp;quot;automatically&amp;quot; implement GetHashCode, since the compiler would need to know how to combine a bunch of separate hash codes into a new hash code. I&amp;#39;ll leave this to better minds to work out, but it would be nice if there was some way to specify how a class should concatenate two hash codes and have the compiler use that or default to a known-good implementation.
&lt;/p&gt;
&lt;p&gt;
But whether the syntax looks like this or something completely different, it&amp;#39;s hard to argue that built-in immutable &lt;em&gt;Value Object &lt;/em&gt;support wouldn&amp;#39;t be a good thing, particularly with the rise of distributed and parallel computing.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;h2&gt;Relevant Resources&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Jonathan Allen&amp;#39;s &lt;/strong&gt;&lt;a href="http://www.infoq.com/articles/Equality-Overloading-DotNET"&gt;&lt;strong&gt;&amp;quot;A Detailed look at Overriding the Equality Operator&amp;quot;&lt;/strong&gt;&lt;/a&gt; - This is an excellent article demonstrating how to implement equality and hash code for both classes and structs in C#. If you need to implement Equals, ==, !=, or GetHashCode by hand and aren&amp;#39;t sure what you&amp;#39;re doing, make sure you read Jonathan&amp;#39;s article first. &lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Luca Bolognese&amp;#39;s Series on Creating Immutable Value Objects in C#&lt;/strong&gt; - You&amp;#39;ll want to find other resources for the specifics of implementing equality and hash code, but Luca&amp;#39;s thoughts on the subject of &lt;em&gt;Value Object &lt;/em&gt;implementation in C# are still relevant. 
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;Part I - Using a class&lt;/a&gt; &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/06/creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.aspx"&gt;Part II - Making the class better&lt;/a&gt; &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx"&gt;Part III - Using a struct&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Luca Bolognese&amp;#39;s Series on a C# Library to Write Functional Code &lt;/strong&gt;- Luca&amp;#39;s &lt;em&gt;Value Object&lt;/em&gt; series above segued into a new series on functional objects in C# when he had the idea to use an immutable Record class as a base for his &lt;em&gt;Value Objects&lt;/em&gt;. 
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;Part I - Background&lt;/a&gt; &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;Part II - Tuples&lt;/a&gt; &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;Part III - Records&lt;/a&gt; &lt;/li&gt;
		&lt;li&gt;Part IV - Type Unions (planned) &lt;/li&gt;
		&lt;li&gt;Part V - Match (planned)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Eric Evans, &lt;em&gt;&lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FDomain-Driven-Design-Tackling-Complexity-Software%2Fdp%2F0321125215%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1212515284%26sr%3D8-1&amp;amp;tag=adjco-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325"&gt;Domain Driven Design&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; &lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Martin Fowler, &lt;em&gt;&lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FEnterprise-Application-Architecture-Addison-Wesley-Signature%2Fdp%2F0321127420%2F&amp;amp;tag=adjco-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325"&gt;Patterns of Enterprise Application Architecture&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/Ml-P2iRMRcc/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/The-Quest-for-Quick-and-Easy-Immutable-Value-Objects-in-C.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=495bb1f7-cfa7-4793-8354-897b432f21a7</guid>
      <pubDate>Tue, 03 Jun 2008 09:57:00 -1100</pubDate>
      <category>C#</category>
      <category>Domain Driven Design</category>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=495bb1f7-cfa7-4793-8354-897b432f21a7</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=495bb1f7-cfa7-4793-8354-897b432f21a7</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/The-Quest-for-Quick-and-Easy-Immutable-Value-Objects-in-C.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=495bb1f7-cfa7-4793-8354-897b432f21a7</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=495bb1f7-cfa7-4793-8354-897b432f21a7</feedburner:origLink></item>
    <item>
      <title>Microsoft's T4: A Free Alternative to CodeSmith</title>
      <description>&lt;p&gt;I've long been a fan of &lt;a href="http://www.codesmithtools.com"&gt;CodeSmith&lt;/a&gt;, an easy-to-use templating engine for creating code of any kind, though I've been a fan from the sidelines, never having purchased a license. My code generation needs are simply too infrequent to justify myself or my company purchasing a commercial code generator. As a result, I've resorted to creating ugly Console projects to generate code on the rare occasions I don't want to do it by hand.&lt;/p&gt; &lt;p&gt;Not anymore.&lt;/p&gt; &lt;p&gt;Microsoft has quietly included a new template-based code generation tool in Visual Studio 2008 called the Text Template Transformation Toolkit, a typical Microsoft-mouthful product name which is often shortened to T4. Officially part of Microsoft's DSL Tools project, T4 is actually a tool that any developer can leverage whether they're working with DSL tools or not. You won't find T4 advertised anywhere inside Visual Studio, but if you create a text file in your project with the extension ".tt" you'll see the T4 magic start to kick in: an associated code file is nested under the new ".tt" file, and Visual Studio understands the ".tt" file as an ASP.NET-like "text template" which it uses to generate the associated code file for your project. You can then develop repetitive code via the template, get feedback on whether the template compiles or not, and watch your associated code file become part of the build process.&lt;/p&gt; &lt;p&gt;Out-of-the-box editing of text templates is pretty poor though: there's no IntelliSense, and there's no syntax highlighting, which is most-likely why Microsoft has made this a "hidden" feature. The good news is there is &lt;a href="http://www.t4editor.net/"&gt;a free T4 editor available from Clarius Consulting&lt;/a&gt; that eases some of the pain. Though it does not (yet) add IntelliSense support, it does add some much-needed code-block coloring so you can easily distinguish between what is template code and what is generated code. If you want to take T4 for a spin, do yourself a favor and go &lt;a href="http://www.t4editor.net/downloads.html"&gt;download the Claruis T4 Editor&lt;/a&gt; first.&lt;/p&gt; &lt;h2&gt;Getting Started&lt;/h2&gt; &lt;p&gt;Oleg Sych has written extensively about T4 and he has a great introductory article available on his blog:&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/" href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/"&gt;http://www.olegsych.com/2007/12/text-template-transformation-toolkit/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you want to learn about T4, &lt;a href="http://www.olegsych.com/"&gt;Oleg's blog&lt;/a&gt; is one of the best places to go.&lt;/p&gt; &lt;h2&gt;Limitations and Advice&lt;/h2&gt; &lt;p&gt;Here are a few issues I've encountered when using text templates:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;C# extension method syntax is not recognized. &lt;/strong&gt;You can still call extension methods, but you will need to call them as a normal static method from the class in which they are defined. For example, if you have a class called StringExtensions that defines an extension method called TrimToNull(), instead of calling myString.TrimToNull(), you'll have to call the static method directly: StringExtensions.TrimToNull(myString).  &lt;li&gt;&lt;strong&gt;Referencing your own assemblies to use within your template code takes just a little work. &lt;/strong&gt;You either need to provide the full path to your assembly using a template assembly directive, or you need to add this path to your project's reference paths in the project properties dialog. Oleg explains more about this here: &lt;a title="http://www.olegsych.com/2008/02/t4-assembly-directive/" href="http://www.olegsych.com/2008/02/t4-assembly-directive/"&gt;http://www.olegsych.com/2008/02/t4-assembly-directive/&lt;/a&gt;  &lt;li&gt;&lt;strong&gt;Don't make your template code depend on the assembly it is generating code for.&lt;/strong&gt; This type of circular dependency is just begging for trouble. I foolishly headed down this route since I was generating code for a commonly-used utility library and I wanted to leverage that same library in my templates. If you really need to use some functionality from the assembly you're generating code for in your templates, either refactor the assembly into separate assemblies so there is no more circular dependency or save a recent build of the assembly into a different location and use that build exclusively for your templates.  &lt;li&gt;&lt;strong&gt;No IntelliSense&lt;/strong&gt;. This is just part of life if you're going to use T4 right now. You can always keep an extra .cs or .vb file open for those times you want IntelliSense, and then copy and paste your code into the template. It's not the best, but it sure beats writing a Console project to generate code.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;If Microsoft continues to improve T4 with a real editor that includes syntax highlighting, IntelliSense, and full support for C# and VB.NET language features such as extension methods, we'll have a real winner.&lt;/p&gt;</description>
      <link>http://feedproxy.google.com/~r/adamjcoopercom/blog/~3/XKjxQ5Bx9is/post.aspx</link>
      <author>adam.nospam@nospam.adamjcooper.com (adamjcooper)</author>
      <comments>http://adamjcooper.com/blog/post/Microsofts-T4-A-Free-Alternative-to-CodeSmith.aspx#comment</comments>
      <guid isPermaLink="false">http://adamjcooper.com/blog/post.aspx?id=964ca773-fcc9-4e73-b724-28f1cb92533d</guid>
      <pubDate>Tue, 03 Jun 2008 08:47:53 -1100</pubDate>
      <dc:publisher>adamjcooper</dc:publisher>
      <pingback:server>http://adamjcooper.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://adamjcooper.com/blog/post.aspx?id=964ca773-fcc9-4e73-b724-28f1cb92533d</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://adamjcooper.com/blog/trackback.axd?id=964ca773-fcc9-4e73-b724-28f1cb92533d</trackback:ping>
      <wfw:comment>http://adamjcooper.com/blog/post/Microsofts-T4-A-Free-Alternative-to-CodeSmith.aspx#comment</wfw:comment>
      <wfw:commentRss>http://adamjcooper.com/blog/syndication.axd?post=964ca773-fcc9-4e73-b724-28f1cb92533d</wfw:commentRss>
    <feedburner:origLink>http://adamjcooper.com/blog/post.aspx?id=964ca773-fcc9-4e73-b724-28f1cb92533d</feedburner:origLink></item>
  </channel>
</rss>
