<?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:dc="http://purl.org/dc/elements/1.1/" 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:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" version="2.0">
    <channel>
        <title>Matt Hidinger</title>
        <link>http://www.matthidinger.com/Default.aspx</link>
        <description>On Error GoTo Blog</description>
        <language>en-US</language>
        <copyright>Matt Hidinger</copyright>
        <generator>Subtext Version 2.1.0.5</generator>
        <image>
            <title>Matt Hidinger</title>
            <url>http://www.matthidinger.com/images/RSS2Image.gif</url>
            <link>http://www.matthidinger.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/mhidinger" type="application/rss+xml" /><item>
            <title>DoddleImport on CodePlex</title>
            <link>http://www.matthidinger.com/archive/2009/02/28/doddleimport-on-codeplex.aspx</link>
            <description>&lt;p&gt;Well I am heading out to Myrtle Beach tonight at 4am, so I spent today finishing up some cleanup so I could release DoddleImport on CodePlex. It should be pretty feature complete and ready for use, and as always, please let me know if it helps you out!&lt;/p&gt;  &lt;h3&gt;Objective &lt;/h3&gt;  &lt;p&gt;Flexible importing of data via a fluid and fully extensible API to easily add support for new Import Sources and Import Destinations.&lt;/p&gt;  &lt;p&gt;I will update the documentation and provide some better examples when I get back. Here you can see a quick example of me importing some Excel data into a SharePoint list. As you can see it supports a variety of validation including missing fields and data type conversion problems.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/ContentImages/DoddleImportonCodePlex_14E69/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/ContentImages/DoddleImportonCodePlex_14E69/image_thumb.png" width="532" height="432" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.matthidinger.com/ContentImages/DoddleImportonCodePlex_14E69/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/ContentImages/DoddleImportonCodePlex_14E69/image_thumb_3.png" width="891" height="198" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Key Components &lt;/h3&gt;  &lt;p&gt;Importing relies on 2 distinct (and entirely extensible) mechanisms:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;IImportSource&lt;/b&gt; - The import framework requires a set of row/field data provided via an IImportSource &lt;/li&gt;    &lt;li&gt;&lt;b&gt;IImportDestination&lt;/b&gt; - The import framework requires a destination to write the data to via an IImportDestination &lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;Note: Most "importable" classes implement both IImportSource as well as IImportDestination, as such, can be used as a source of import rows and a destination to import into &lt;/blockquote&gt;  &lt;h3&gt;Import Sources and Destinations &lt;/h3&gt; DoddleImport ships with some basic Import Sources, but just like all other Doddle Projects, you can easily create your own by implementing a simple interface.   &lt;ul&gt;   &lt;li&gt;&lt;b&gt;ImportableCollection&lt;/b&gt; - provides importing to and from a generic list &lt;/li&gt;    &lt;li&gt;&lt;b&gt;ImportableDictionary&lt;/b&gt; - provides importing to and from a basic dictionary &lt;/li&gt;    &lt;li&gt;&lt;b&gt;ImportableSPList&lt;/b&gt; - provides importing to and from a SharePoint List &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Spreadsheet&lt;/b&gt; - provides importing from an Excel Spreadsheet &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Usage&lt;/h3&gt;  &lt;pre class="brush: c#"&gt;// Basic import from one type of in-memory collection to another
ImportableDictionary source = new ImportableDictionary();
source.Fields.Add("ProductID", typeof(int));
source.Fields.Add("ProductName", typeof(string));

IDictionary row1 = source.AddRow();
row1["ProductID"] = 1;
row1["ProductName"] = "My Product";

List&lt;product&gt; products = new List&amp;lt;Product&amp;gt;();
IImportDestination destination = new ImportableCollection&amp;lt;Product&amp;gt;(products);

Importer importer = new Importer();
importer.Import(source, destination);&lt;/product&gt;&lt;/pre&gt;

&lt;pre class="brush: c#"&gt;// More realistic example, importing an Excel Spreadsheet into a SharePoint list
Stream uploadedFile = fileUpload.PostedFile.InputStream;
Spreadsheet spreadsheet = new Spreadsheet(uploadedFile);

SPList myList = Web.Lists["My List"];
IImportDestination destination = new ImportableSPList(myList);

Importer importer = new Importer();
importer.Import(spreadsheet, destination);&lt;/pre&gt;

&lt;h3&gt;Validation &lt;/h3&gt;

&lt;p&gt;DoddleImport will provide automatic validation of your Import Source against the specified destination. This ensures that the entire import contents will be successfully imported as well as provide helpful error messages to your user so they can easily correct errors.&lt;/p&gt;

&lt;h4&gt;Validation Rules &lt;/h4&gt;
The validation mechanism works by automatically evaluating rules against each row being imported. This is handled through the IValidationRule interface. 

&lt;ul&gt;
  &lt;li&gt;The default rules with DoddleImport are as follows: 
    &lt;ul&gt;
      &lt;li&gt;&lt;b&gt;RequiredFieldsRule&lt;/b&gt; - validates a row to make sure that data was provided for all required fields &lt;/li&gt;

      &lt;li&gt;&lt;b&gt;MissingHeadersRule&lt;/b&gt; - validates that the source contains all required fields that the destination expects &lt;/li&gt;

      &lt;li&gt;&lt;b&gt;DataTypeValidationRule&lt;/b&gt; - valdiates data type mis-match errors &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Configuration &lt;/h3&gt;

&lt;p&gt;If you want to change some of th default behavior of DoddleImport then using your application configuration file is the best place to start.&lt;/p&gt;

&lt;p&gt;To use configuration, be sure to register the &amp;lt;section&amp;gt; node between &amp;lt;configSections&amp;gt; in your app.Config or web.Config&lt;/p&gt;

&lt;p&gt;From there, you can add or remove validation rules that will be automatically applied to every import. You are also able to customize the default validation messages. Below is a quick sample of some of the changes that can be made. &lt;/p&gt;

&lt;pre class="brush: xml"&gt;&amp;lt;configuration&amp;gt;
  &amp;lt;configSections&amp;gt;
    &amp;lt;section name="doddleImport" 
          type="Doddle.Import.Configuration.ImportSection, Doddle.Import, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6f5f0fd458d019c9" /&amp;gt;
  &amp;lt;/configSections&amp;gt;
  &amp;lt;doddleImport&amp;gt;
    &amp;lt;validation&amp;gt;
      &amp;lt;rules&amp;gt;
        &amp;lt;remove name="MissingHeadersRule" /&amp;gt;
        &amp;lt;add name="MyCustomRule" type="MyName.Importing.CustomValidationRule, MyName.Importing" /&amp;gt;
      &amp;lt;/rules&amp;gt;
      &amp;lt;messages&amp;gt;
        &amp;lt;remove rule="RequiredFieldsRule" /&amp;gt;
        &amp;lt;add rule="RequiredFieldsRule" message="Unable to locate field '{0}'"/&amp;gt;
      &amp;lt;/messages&amp;gt;
    &amp;lt;/validation&amp;gt;
  &amp;lt;/doddleImport&amp;gt;
&amp;lt;/configuration&amp;gt;&lt;/pre&gt;

&lt;p&gt;That's all for now, check back for updates on this and some other projects. 
  &lt;br /&gt;&lt;/p&gt;

&lt;h3&gt;Get the Source and Try it out!&lt;/h3&gt;

&lt;br /&gt;&lt;a href="http://codeplex.com/doddleimport" target="_blank"&gt;Check it out at CodePlex&lt;/a&gt;

&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;
  &lt;/p&gt;&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:dfc63c95-16da-4d4a-9eba-d46f1febfd9a" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Doddle" rel="tag"&gt;Doddle&lt;/a&gt;,&lt;a href="http://technorati.com/tags/SharePoint" rel="tag"&gt;SharePoint&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/25.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2009/02/28/doddleimport-on-codeplex.aspx</guid>
            <pubDate>Sun, 01 Mar 2009 05:47:10 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/25.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2009/02/28/doddleimport-on-codeplex.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/25.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/25.aspx</trackback:ping>
        </item>
        <item>
            <title>WCSF ObjectContainerDataSource with LINQ to SQL</title>
            <link>http://www.matthidinger.com/archive/2009/02/19/wcsf-objectcontainerdatasource-with-linq-to-sql.aspx</link>
            <description>&lt;p&gt;A project I am now working on is using the &lt;a href="http://www.codeplex.com/websf" target="_blank"&gt;Web Client Software Factory&lt;/a&gt; (WCSF) from the &lt;a href="http://msdn.microsoft.com/practices" target="_blank"&gt;patterns &amp;amp; practices&lt;/a&gt; team. It is basically an elaborate MVP-based framework that currently sits on top of ASP.NET Webforms. &lt;/p&gt;  &lt;p&gt;One of the components it ships with is the &lt;strong&gt;ObjectContainerDataSource&lt;/strong&gt; which is a lot like the ObjectDataSource that ASP.NET provides. I admittedly have little experience with either of these controls, since I am not a huge fan of declarative data binding in larger applications. It does however offer better integration with the MVP pattern, simplifying the “bubbling” of DataSource events up to the Presenter to handle them. The Presenter is of course where all of the logic for the view and its services belongs.&lt;/p&gt;  &lt;p&gt;At first everything was working great: selects, server-side paging, server-side sorting, even inserting. But when I tried some Updates and Deletes with the GridView and the ObjectContainerDataSource I was encountering a frustrating exception I hadn’t seen before.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;i&gt;Row not found or changed.&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The exception was being thrown on the dataContext.SubmitChanges(). After some quick digging I found that this error is due to our Timestamp column which is used by the LinqDataContext for optimistic concurrency. Before the Data Source fires its Updated event, it re-creates an instance of the object and populates the properties with the values in the data control using reflection. However, the ObjectContainterDataSource was not setting the Timestamp property when it was re-constructing the object for updating. This was causing the LinqDataContext to throw the “Row not Found” exception because it could not find a row WHERE ContractorId = 1 AND Timestamp = NULL. I needed some way to persist the Timestamp property within the DataSource so it would re-populate it on the Updated event. &lt;/p&gt;  &lt;pre class="brush: sql; highlight: 5"&gt;exec sp_executesql N'UPDATE [dbo].[Contractors] 
SET [ContractorName] = @p2 WHERE ([ContractorId] = @p0) AND ([Timestamp] = @p1) 

@p0=1,
@p1=NULL,
@p2='My Updated Contractor'&lt;/pre&gt;

&lt;p&gt;The solution I found, was to include the Timestamp column in the DataKeyNames property. This ensured that the data source would correctly populate the property even though it did not appear as a column in my GridView.&lt;/p&gt;

&lt;pre class="brush: xhtml; highlight: [3]"&gt;&amp;lt;asp:GridView ID="ContractorGrid" runat="server" 
    AutoGenerateEditButton="true" AutoGenerateDeleteButton="true"
    DataSourceID="ContractorDataSource" DataKeyNames="ContractorId, Timestamp"
    PageSize="5" AllowPaging="true" AllowSorting="true" AutoGenerateColumns="false"&amp;gt;&lt;/pre&gt;

&lt;p&gt;This may be a well-known problem with LINQ to SQL and the DataSources, but as I mentioned I don’t use them that much for declarative data binding. Either way, hopefully this saves someone frustration down the road.
  &lt;br /&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2c0d99d3-67c1-4ae8-b62d-18aea32d576a" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/WCSF" rel="tag"&gt;WCSF&lt;/a&gt;,&lt;a href="http://technorati.com/tags/LINQ+to+SQL" rel="tag"&gt;LINQ to SQL&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/21.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2009/02/19/wcsf-objectcontainerdatasource-with-linq-to-sql.aspx</guid>
            <pubDate>Thu, 19 Feb 2009 20:49:06 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/21.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2009/02/19/wcsf-objectcontainerdatasource-with-linq-to-sql.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/21.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/21.aspx</trackback:ping>
        </item>
        <item>
            <title>ASP.NET MVC Recursive TreeView Helper</title>
            <category>jQuery</category>
            <category>ASPNET MVC</category>
            <link>http://www.matthidinger.com/archive/2009/02/08/asp.net-mvc-recursive-treeview-helper.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;Update 2/10/2009: I have updated the helper code a little bit to include an ID parameter as well as to inject the jQuery treeview script code automatically. Please modify to your desire, or make sure to include the jQuery TreeView plugin script to your page before running.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The following helper will make it easy to create a tree view from a recursive self-referencing table. Below you are seeing a tree of “Locations” where each Location can contain X number of child locations.&lt;/p&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;p&gt; &lt;a title="http://bassistance.de/jquery-plugins/jquery-plugin-treeview/" target="_blank" href="http://bassistance.de/jquery-plugins/jquery-plugin-treeview/"&gt;jQuery TreeView Plugin&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;br /&gt;
Rendered Tree&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCRecursiveTreeViewHelper_B445/image.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="159" height="299" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCRecursiveTreeViewHelper_B445/image_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;Table Definition&lt;/h3&gt;
&lt;p&gt;The table itself is extremely simple, each Location has a ParentLocationId which is a relationship to the same table. If the ParentLocationId is null then it is a root location.&lt;/p&gt;
&lt;p&gt; &lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCRecursiveTreeViewHelper_B445/image_3.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="345" height="337" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCRecursiveTreeViewHelper_B445/image_thumb_3.png" /&gt;&lt;/a&gt; &lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCRecursiveTreeViewHelper_B445/image_4.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="399" height="125" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCRecursiveTreeViewHelper_B445/image_thumb_4.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;&lt;br /&gt;
Usage &lt;br /&gt;
&lt;/h3&gt;
&lt;p&gt;Simple &lt;/p&gt;
&lt;pre class="brush: c#"&gt;&amp;lt;%= Html.TreeView("locations", 
    Model.Locations, 
    l =&amp;gt; l.ChildrenLocations, 
    l =&amp;gt; l.Name) %&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Wrapping a div around each list item&lt;/p&gt;
&lt;pre class="brush: c#"&gt;&amp;lt;%= Html.TreeView("dropTree", 
    Model.Locations, 
    l =&amp;gt; l.ChildrenLocations, 
    l =&amp;gt; "&amp;lt;div class='dropZone'&amp;gt;" + l.Name + "&amp;lt;div&amp;gt;")
&lt;/pre&gt;
&lt;p&gt;Making each list item an ActionLink&lt;/p&gt;
&lt;pre class="brush: c#"&gt;&amp;lt;%= Html.TreeView("dropTree", 
    Model.Locations, 
    l =&amp;gt; l.ChildrenLocations, 
    l =&amp;gt; Html.ActionLink("MyController", "MyAction", l.Name, new { id = l.Name })
&lt;/pre&gt;
&lt;h3&gt;The Code&lt;/h3&gt;
&lt;pre class="brush: c#"&gt;public static class TreeViewHtmlHelper
{
    /// &amp;lt;summary&amp;gt;
    /// Create a TreeView of nodes starting from a root element
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="treeId"&amp;gt;The ID that will be used when the ul is created&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="rootItems"&amp;gt;The root nodes to create&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="childrenProperty"&amp;gt;A lambda expression that returns the children nodes&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="itemContent"&amp;gt;A lambda expression defining the content in each tree node&amp;lt;/param&amp;gt;
    public static string TreeView&amp;lt;T&amp;gt;(this HtmlHelper html, string treeId, IEnumerable&amp;lt;T&amp;gt; rootItems, Func&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; childrenProperty, Func&amp;lt;T, string&amp;gt; itemContent)
    {
        return html.TreeView(treeId, rootItems, childrenProperty, itemContent, true, null);
    }

    /// &amp;lt;summary&amp;gt;
    /// Create a TreeView of nodes starting from a root element
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="treeId"&amp;gt;The ID that will be used when the ul is created&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="rootItems"&amp;gt;The root nodes to create&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="childrenProperty"&amp;gt;A lambda expression that returns the children nodes&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="itemContent"&amp;gt;A lambda expression defining the content in each tree node&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="includeJavaScript"&amp;gt;If true, output will automatically render the JavaScript to turn the ul into the treeview&amp;lt;/param&amp;gt;    
    public static string TreeView&amp;lt;T&amp;gt;(this HtmlHelper html, string treeId, IEnumerable&amp;lt;T&amp;gt; rootItems, Func&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; childrenProperty, Func&amp;lt;T, string&amp;gt; itemContent, bool includeJavaScript)
    {
        return html.TreeView(treeId, rootItems, childrenProperty, itemContent, includeJavaScript, null);
    }

    /// &amp;lt;summary&amp;gt;
    /// Create a TreeView of nodes starting from a root element
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="treeId"&amp;gt;The ID that will be used when the ul is created&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="rootItems"&amp;gt;The root nodes to create&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="childrenProperty"&amp;gt;A lambda expression that returns the children nodes&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="itemContent"&amp;gt;A lambda expression defining the content in each tree node&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="includeJavaScript"&amp;gt;If true, output will automatically render the JavaScript to turn the ul into the treeview&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="emptyContent"&amp;gt;Content to be rendered when the tree is empty&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="includeJavaScript"&amp;gt;If true, output will automatically into the JavaScript to turn the ul into the treeview&amp;lt;/param&amp;gt;    
    public static string TreeView&amp;lt;T&amp;gt;(this HtmlHelper html, string treeId, IEnumerable&amp;lt;T&amp;gt; rootItems, Func&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; childrenProperty, Func&amp;lt;T, string&amp;gt; itemContent, bool includeJavaScript, string emptyContent)
    {
        StringBuilder sb = new StringBuilder();

        sb.AppendFormat("&amp;lt;ul id='{0}'&amp;gt;\r\n", treeId);

        if(rootItems.Count() == 0)
        {
            sb.AppendFormat("&amp;lt;li&amp;gt;{0}&amp;lt;/li&amp;gt;", emptyContent);
        }

        foreach (T item in rootItems)
        {
            RenderLi(sb, item, itemContent);
            AppendChildren(sb, item, childrenProperty, itemContent);
        }

        sb.AppendLine("&amp;lt;/ul&amp;gt;");

        if (includeJavaScript)
        {
            sb.AppendFormat(
                @"&amp;lt;script type='text/javascript'&amp;gt;
                    $(document).ready(function() {{
                        $('#{0}').treeview({{ animated: 'fast' }});
                    }});
                &amp;lt;/script&amp;gt;", treeId);
        }

        return sb.ToString();
    }

    private static void AppendChildren&amp;lt;T&amp;gt;(StringBuilder sb, T root, Func&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&amp;gt; childrenProperty, Func&amp;lt;T, string&amp;gt; itemContent)
    {
        var children = childrenProperty(root);
        if(children.Count() == 0)
        {
            sb.AppendLine("&amp;lt;/li&amp;gt;");
            return;
        }

        sb.AppendLine("\r\n&amp;lt;ul&amp;gt;");
        foreach (T item in children)
        {
            RenderLi(sb, item, itemContent);
            AppendChildren(sb, item, childrenProperty, itemContent);
        }

        sb.AppendLine("&amp;lt;/ul&amp;gt;&amp;lt;/li&amp;gt;");
    }

    private static void RenderLi&amp;lt;T&amp;gt;(StringBuilder sb, T item, Func&amp;lt;T, string&amp;gt; itemContent)
    {
        sb.AppendFormat("&amp;lt;li&amp;gt;{0}", itemContent(item));            
    }
}

&lt;/pre&gt;
&lt;div style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:87bf7f76-d6a6-49b4-b816-21114c5be587" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/ASPNET+MVC"&gt;ASPNET MVC&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/jQuery"&gt;jQuery&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/15.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2009/02/08/asp.net-mvc-recursive-treeview-helper.aspx</guid>
            <pubDate>Sun, 08 Feb 2009 12:57:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/15.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2009/02/08/asp.net-mvc-recursive-treeview-helper.aspx#feedback</comments>
            <slash:comments>18</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/15.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/15.aspx</trackback:ping>
        </item>
        <item>
            <title>jQuery UI 1.6rc6 tabs bug with IE6/7</title>
            <category>JavaScript</category>
            <category>Web Standards</category>
            <category>jQuery</category>
            <link>http://www.matthidinger.com/archive/2009/02/07/jquery-ui-1.6rc6-tabs-bug-with-ie67.aspx</link>
            <description>&lt;p&gt;I encountered a rather frustrating problem with jQuery UI tabs this week. The problem occurs when trying to tabify some content after using jQuery’s $().load method to load the tabs HTML via an ajax request.&lt;/p&gt;
&lt;p&gt;The following code works perfectly in all browsers except IE6 and IE7 (It works fine in IE8 as well), as can be seen in the screenshot below.&lt;/p&gt;
&lt;pre class="brush: js"&gt;$('#deviceDetailsWrapper').load('/device/details/294', null, function() {
    $('#tabs').tabs();
});
&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/jQueryUI1.6rc6tabsbugwithIE67_12D90/image.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="551" height="243" src="http://blog2.matthidinger.com/ContentImages/jQueryUI1.6rc6tabsbugwithIE67_12D90/image_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;However, here is what renders in IE6/7. For some reason, the jQuery tabs are triggering a GET request of the current URL and loading the content into the tab itself. Below you are actually seeing the entire page loaded inside the tab. I discovered this by inspecting the DOM tree within the tab in Firebug, as well as loading up Fiddler and watching the tab call an entirely separate GET request to the current URL as soon as the tabs were loaded. Strange behavior to me, since I am not entirely familiar with the jQuery tabs.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/jQueryUI1.6rc6tabsbugwithIE67_12D90/image_3.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="579" height="425" src="http://blog2.matthidinger.com/ContentImages/jQueryUI1.6rc6tabsbugwithIE67_12D90/image_thumb_3.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;The Solution&lt;/h3&gt;
&lt;p&gt;The only thing I discovered was different regarding the .tabs() DOM manipulation in the different browsers was the ID of the tab – instead of being the #tab-id that I named it, the element was being assigned the full URL+#id to the container. So “#tab1” was becoming “http://localhost/device#tab1” – which I believe was triggering the tabs to behave in their “ajax” mode, which is a built-in feature of the jQuery tabs.&lt;/p&gt;
&lt;p&gt;The solution I found was opening up jquery.ui.all.js and locating the following code:&lt;/p&gt;
&lt;pre class="brush: js"&gt;this.$tabs.each(function(i, a) {
var href = $(a).attr('href');

// inline tab
if (fragmentId.test(href))
    self.$panels = self.$panels.add(self._sanitizeSelector(href));
&lt;/pre&gt;

Replace it with the following: 

&lt;pre class="brush: js"&gt;
this.$tabs.each(function(i, a) {
var href = $(a).attr('href');
            
// Fix tab IDs in IE6/7
href = href.substring(href.indexOf("#"));

// inline tab
if (fragmentId.test(href))
    self.$panels = self.$panels.add(self._sanitizeSelector(href)); 
&lt;/pre&gt;
&lt;p&gt;Hopefully this helps someone in their googling of this problem. I will be logging this as a bug with the jQuery developers.&lt;/p&gt;
&lt;div style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:78c01e1c-bb37-4e37-946f-1cd5008cfe76" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/javascript"&gt;javascript&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/jQuery"&gt;jQuery&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/web+standards"&gt;web standards&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/14.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2009/02/07/jquery-ui-1.6rc6-tabs-bug-with-ie67.aspx</guid>
            <pubDate>Sat, 07 Feb 2009 12:53:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/14.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2009/02/07/jquery-ui-1.6rc6-tabs-bug-with-ie67.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/14.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/14.aspx</trackback:ping>
        </item>
        <item>
            <title>LINQ Audit Trail v2 - DoddleAudit</title>
            <category>LINQ</category>
            <category>LINQ to SQL</category>
            <category>Doddle</category>
            <link>http://www.matthidinger.com/archive/2009/01/12/linq-audit-trail-v2.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://www.matthidinger.com/archive/2008/05/08/linq-to-sql-audit-trail.aspx"&gt;A couple months ago&lt;/a&gt; I wrote a basic set of extension methods to handle automatic auditing in LINQ to SQL. Well I have received a large number of emails regarding this particular project so I have decided to focus on cleaning up my v2 API and releasing it on CodePlex. There was a lot of room for improvement from version 1 and today I am going to post the all new LINQ Audit Trail code. This new version is significantly enhanced in the previous version.&lt;/p&gt;  &lt;h3&gt;Objective&lt;/h3&gt;  &lt;blockquote&gt;Automatic auditing of all inserts/updates/deletes for any table in your database with a single line of code, including:    &lt;p /&gt;    &lt;ul&gt;     &lt;li&gt;What table was modified? &lt;/li&gt;      &lt;li&gt;What fields changed? &lt;/li&gt;      &lt;li&gt;Who made the change? &lt;/li&gt;      &lt;li&gt;When did it occur? &lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;h3&gt;   &lt;br /&gt;Usage&lt;/h3&gt;  &lt;p&gt;Simply define your audit definitions at any time before calling SubmitChanges(); &lt;/p&gt;  &lt;pre class="brush: c#"&gt;this.Products.Audit();
this.Categories.Audit();
this.Orders.Audit().AuditAssociation(o =&amp;gt; o.Order_Details);
this.Contacts.Audit().AuditAssociation(c =&amp;gt; c.Addresses).AuditAssociation(c =&amp;gt; c.PhoneNumbers);&lt;/pre&gt;

&lt;br /&gt;

&lt;h3&gt;Updates and Download&lt;/h3&gt;

&lt;p&gt;Please see the CodePlex project for updates and new releases. &lt;strong&gt;&lt;a href="http://www.codeplex.com/DoddleAudit"&gt;DoddleAudit&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;br /&gt;

&lt;h3&gt;New Features and Fixes in V2&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;A significantly refined API for defining which tables to audit, including automatic primary key lookups. &lt;/li&gt;

  &lt;li&gt;Inserted records will have their primary keys correctly stored in the audit table now. &lt;/li&gt;

  &lt;li&gt;Built-in support for auditing across relationships. 
    &lt;ul&gt;
      &lt;li&gt;E.g., assume you want to audit a Contacts table which has a 1-to-many relationship to the Addresses table, thus allowing any number of Addresses to each Contact. Well ideally you want to show these Address audits on your ContactDetails.aspx, which is exactly what you can see in the screenshot below.  &lt;br /&gt;&lt;a href="http://www.matthidinger.com/ContentImages/LINQAuditTrailv2_B491/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.matthidinger.com/ContentImages/LINQAuditTrailv2_B491/image_thumb.png" width="535" height="508" /&gt;&lt;/a&gt; 

        &lt;br /&gt;

        &lt;br /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;li&gt;Ability to define custom “audit property resolvers” to override the default auditing mechanism for properties that you specify. 
  &lt;ul&gt;
    &lt;li&gt;For example, notice in the above screenshot that “Address Type” has a value of “1” since that is how the data is stored in the table. This number does little good for the end user, so in V2 it is now possible to customize specific properties as needed. I will explain more details about this soon. Below I am overriding the default auditing of the Product.CategoryID property by querying the category by looking up the CategoryID, returning the Category.CategoryName, and renaming the audit field to “Category” since “CategoryID” is no longer accurate. &lt;/li&gt;
  &lt;/ul&gt;

  &lt;pre class="brush: c#"&gt;public class ProductAuditResolver : AuditPropertyResolver&lt;product&gt;
{
    protected override void CustomizeProperties()
    {
        CustomizeProperty(p =&amp;gt; p.CategoryID, categoryId =&amp;gt; GetCategoryByID(cid).CategoryName, "Category");
    }
}	
   &lt;/product&gt;&lt;/pre&gt;

  &lt;p /&gt;

  &lt;h3&gt;
    &lt;br /&gt;&lt;/h3&gt;

  &lt;h3&gt;Instructions&lt;/h3&gt;

  &lt;ol&gt;
    &lt;li&gt;&lt;a href="http://www.codeplex.com/doddleaudit" target="_blank"&gt;Download the latest release from CodePlex&lt;/a&gt;, the source code and compiled DLL are available, and add reference to &lt;strong&gt;Doddle.Linq.Audit.dll&lt;/strong&gt; in your project that contains your LINQ to SQL DBML &lt;/li&gt;

    &lt;li&gt;At a minimum you will need to add 2 tables to your database (and your DBML) to store the audit records. Please see the schema below and add these tables to your database. 
      &lt;ul&gt;
        &lt;li&gt;NOTE: Keep in mind this database schema is entirely customizable. I chose to use two tables to store all of my audits, but you could very easily change this logic to use a separate table for each entity or whatever storage schema you choose.   &lt;br /&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/LINQAuditTrailv2_B491/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/LINQAuditTrailv2_B491/image_thumb_3.png" width="709" height="274" /&gt;&lt;/a&gt; 

          &lt;br /&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;

    &lt;li&gt;Open your DBML and click in the designer surface. In the property pane you will need to change the &lt;strong&gt;Base Class&lt;/strong&gt; property of your generated DataContext to be &lt;strong&gt;Doddle.Linq.Audit.LinqToSql.AuditableDataContext  &lt;br /&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/LINQAuditTrailv2_B491/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/LINQAuditTrailv2_B491/image_thumb_4.png" width="618" height="243" /&gt;&lt;/a&gt; 

        &lt;br /&gt;

        &lt;br /&gt;&lt;/strong&gt;&lt;/li&gt;

    &lt;li&gt;Lastly you will need to create a partial DataContext class to wire up the auditing infrastructure to match your database schema. Add a new Class file to your project and insert the following code. Customize if necessary to match your auditing schema. 
      &lt;br /&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;pre class="brush: c#"&gt;public partial class NorthwindEntitiesDataContext
{
    protected override void InsertAuditRecordToDatabase(EntityAuditRecord record)
    {
        AuditRecord audit = new AuditRecord();
        audit.Action = (byte)record.Action;
        audit.AuditDate = DateTime.Now;
        audit.AssociationTable = record.AssociationTable;
        audit.AssociationTableKey = record.AssociationTableKey;
        audit.EntityTable = record.EntityTable;
        audit.EntityTableKey = record.EntityTableKey;

        audit.UserName = HttpContext.Current.User.Identity.Name;

        foreach (ModifiedEntityProperty av in record.ModifiedProperties)
        {
            AuditRecordModifiedField field = new AuditRecordModifiedField();
            field.MemberName = av.MemberName;
            field.OldValue = av.OldValue;
            field.NewValue = av.NewValue;

            audit.AuditRecordModifiedFields.Add(field);
        }

        this.AuditRecords.InsertOnSubmit(audit);
    }

    protected override void DefaultAuditDefinitions()
    {
        this.Products.Audit();
        this.Categories.Audit().AuditAssociation(c =&amp;gt; c.Products);
    }
}&lt;/pre&gt;
    &lt;/li&gt;
  &lt;/ol&gt;

  &lt;h3&gt;Known Issues&lt;/h3&gt;

  &lt;ol&gt;
    &lt;li&gt;I have not finished the support for the Entity Framework implementation of the auditing yet. If anyone more experienced with EF is out there downloading this source please let me know if you want to help complete it. 
      &lt;br /&gt;&lt;/li&gt;
  &lt;/ol&gt;

  &lt;p&gt;Hopefully that is enough to get anyone started with the code. I am certainly looking for feedback for any suggestions, problems, or improvements. After some more unit testing and perhaps some slight refinements to the API I will remove the “beta” moniker.&lt;/p&gt;

  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:0e930095-434d-4e67-a764-90f4af23f0d9" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/LINQ" rel="tag"&gt;LINQ&lt;/a&gt;,&lt;a href="http://technorati.com/tags/LINQ+to+SQL" rel="tag"&gt;LINQ to SQL&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Doddle" rel="tag"&gt;Doddle&lt;/a&gt;&lt;/div&gt;

  &lt;p /&gt;
&lt;/li&gt;&lt;img src="http://www.matthidinger.com/aggbug/13.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2009/01/12/linq-audit-trail-v2.aspx</guid>
            <pubDate>Mon, 12 Jan 2009 12:50:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/13.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2009/01/12/linq-audit-trail-v2.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/13.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/13.aspx</trackback:ping>
        </item>
        <item>
            <title>Fixing Web Application Projects with automated TFS Builds</title>
            <category>ASP.NET</category>
            <category>TFS</category>
            <category>CI</category>
            <link>http://www.matthidinger.com/archive/2008/11/09/fixing-web-application-projects-with-automated-tfs-builds.aspx</link>
            <description>&lt;p&gt;This weekend I started playing with Automated Builds in TFS 2008. Over the next few weeks I am going to setup automated builds for my various projects so I can start running automated integration testing and automated staging releases at certain intervals (nightly, weekly, etc). Unfortunately I hit a snag when I tried building one of my solutions that contained a Web Application Project.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/FixingWebApplicationProjectswithautomate_B396/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/FixingWebApplicationProjectswithautomate_B396/image_thumb.png" width="474" height="247" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;After some digging around, I eventually opened up the “Release.txt” log file which can be found in the deployment directory, I found the following error:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;error MSB4019: The imported project "C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the &amp;lt;Import&amp;gt; declaration is correct, and that the file exists on disk.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now I am no where near an expert on MSBuild or the delicacies of .csproj files, so I did my best to poke around in there and see what might be going on. For those unaware, every .csproj file is actually just an XML file with various details about your actual project. In order to view/edit the project definition you can simply right-click on the project and select “Unload Project.” Once it has been unloaded, you can right-click again and select “Edit YourProject.csproj”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/FixingWebApplicationProjectswithautomate_B396/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/FixingWebApplicationProjectswithautomate_B396/image_thumb_3.png" width="117" height="245" /&gt;&lt;/a&gt;  &lt;a href="http://blog2.matthidinger.com/ContentImages/FixingWebApplicationProjectswithautomate_B396/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/FixingWebApplicationProjectswithautomate_B396/image_thumb_4.png" width="244" height="147" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Once open, a search for the &amp;lt;Import&amp;gt; tag revealed the exact line causing the problem.&lt;/p&gt;    &lt;pre class="brush: xml"&gt;
&amp;lt;Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" /&amp;gt;
&lt;/pre&gt;

&lt;p&gt;It would appear the Visual Studio 2008 will install all necessary MSBuild targets into the v9.0 directory – which is exactly what brings us to our problem. My Build Server does not have Visual Studio installed, it is just a basic Server 2008 box with .NET 3.5 and nothing fancy (aside from all the TFS gear). The problem is that these v9.0 targets were not available on my build machine, so I found 2 completely different solutions that ended up resolving my issue.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Solution 1 – Add Conditional Imports (Not Recommended)&lt;/h3&gt;

&lt;p&gt;A google search of the actual MSBuild error brought me to a single post by &lt;a href="http://stevenharman.net/blog/archive/0001/01/01/multi-targeting-vs2005-and-vs2008-web-application-projects-a-gotcha.aspx"&gt;Steven Harman&lt;/a&gt; which seemed helpful but I was skeptical because it was related to multi-targeting and problems with a machine running both VS 2008 and VS 2005. I decided to try it out by editing my csproj to the following:&lt;/p&gt;

&lt;p&gt;I replaced the original &amp;lt;Import&amp;gt; declaration to the following&lt;/p&gt;

&lt;pre class="brush: xml"&gt;
&amp;lt;ImportCondition="'$(Solutions.VSVersion)' == '8.0'" Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" /&amp;gt;

&amp;lt;ImportCondition="'$(Solutions.VSVersion)' == '9.0'" Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" /&amp;gt;
&lt;/pre&gt;

&lt;p&gt;With this change in place, I re-ran by TFS Build and it worked successfully. Unfortunately, this is extremely tedious to manually edit all of my .csproj files to facilitate automated builds. &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Solution 2 – Copy the v9.0 Targets to Build Machine (Recommended)&lt;/h3&gt;

&lt;p&gt;Once I started really thinking about the error, another solution seemed very clear and simple – just provide my build server with the target files. This solution ends up being much simpler and does not require editing any csproj files:&lt;/p&gt;

&lt;p&gt;On your development machine, copy everything in “C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0”  to the same folder on your build machine. This will provide your build machine with the correct target files required by your projects. I have only tested the Web Application projects but I see no reason that everything else would not work properly. Please let me know if anyone runs into issues with this.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/FixingWebApplicationProjectswithautomate_B396/image_5.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/FixingWebApplicationProjectswithautomate_B396/image_thumb_5.png" width="695" height="386" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7de6d328-ebfc-403f-8e09-4ca073c5b0d5" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/ASPNET" rel="tag"&gt;ASPNET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/TFS" rel="tag"&gt;TFS&lt;/a&gt;,&lt;a href="http://technorati.com/tags/CI" rel="tag"&gt;CI&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ASPNET+MVC" rel="tag"&gt;ASPNET MVC&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/12.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/11/09/fixing-web-application-projects-with-automated-tfs-builds.aspx</guid>
            <pubDate>Sun, 09 Nov 2008 12:45:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/12.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/11/09/fixing-web-application-projects-with-automated-tfs-builds.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/12.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/12.aspx</trackback:ping>
        </item>
        <item>
            <title>Increase AddIn Performance with MAF and WPF using LoaderOptimization</title>
            <category>WPF</category>
            <category>MAF</category>
            <link>http://www.matthidinger.com/archive/2008/10/12/increase-addin-performance-with-maf-and-wpf-using-loaderoptimization.aspx</link>
            <description>&lt;p&gt;As mentioned in my &lt;a href="http://blog2.matthidinger.com/archive/2008/10/12/managed-addin-framework-system.addin-with-wpf.aspx"&gt;previous article&lt;/a&gt;, the &lt;a href="http://www.codeplex.com/clraddins"&gt;Managed AddIn Framework&lt;/a&gt; supports AppDomain isolation out of the box. This can come in very handy as long as you understand what is really happening under the covers. I am not going to cover all the details of AppDomain isolation and assembly loading within the CLR, but there are plenty of great resources about such things on MSDN. All you need to know for this article is that every .NET assembly much be loaded into memory within an AppDomain, and unless you specifically share assemblies across these domains (as explained below) then they will be loaded into memory for every AppDomain you create. This is particularly important for WPF AddIns, because the WPF assemblies consume a rather generous portion of memory, and since your AddIns are each loaded into their own AppDomain, this means that the WPF assemblies must &lt;em&gt;also&lt;/em&gt; be loaded into each of these AppDomains. If you are not careful, your application could begin to consume large amounts of memory without you even noticing.&lt;/p&gt;  &lt;p&gt;To solve this, you can place an attribute on the Main method of any .NET executable, explicitly stating that you want the CLR to share any assemblies that it can. There are certain rules for an assembly to be shareable, one of which is that it must have a strong name and be placed in the GAC – obviously this is not a problem for the .NET framework assemblies, WPF in our case.&lt;/p&gt;  &lt;p&gt;When you create a new WPF Project the project template will create an App.xaml for you. Since WPF does a little magic behind the scenes, there is no way to access the Main method of your application. In this case, you simply delete the App.xaml and create a new Application.cs class with the following code:&lt;/p&gt;  &lt;pre class="brush: c#; highlight: [12];"&gt;

public class Application : System.Windows.Application
{
    public Application()
    {
        StartupUri = new Uri("Window1.xaml", UriKind.Relative);
    }
    
    public static Application App;

    [System.STAThreadAttribute()]
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.LoaderOptimization(LoaderOptimization.MultiDomainHost)]
    public static void Main()
    {
        // Add attribute above this method
        Application app = new Application();
        App = app;
        app.Run();
    }
}
&lt;/pre&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:34b2da25-476c-4537-b194-f29e24cf66a1" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;,&lt;a href="http://technorati.com/tags/MAF" rel="tag"&gt;MAF&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/11.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/10/12/increase-addin-performance-with-maf-and-wpf-using-loaderoptimization.aspx</guid>
            <pubDate>Sun, 12 Oct 2008 11:39:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/11.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/10/12/increase-addin-performance-with-maf-and-wpf-using-loaderoptimization.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/11.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/11.aspx</trackback:ping>
        </item>
        <item>
            <title>Managed AddIn Framework (System.AddIn) with WPF</title>
            <category>MAF</category>
            <category>WPF</category>
            <link>http://www.matthidinger.com/archive/2008/10/12/managed-addin-framework-system.addin-with-wpf.aspx</link>
            <description>&lt;p&gt;Disclaimer: This post is mainly for my own reference. Quite honestly, the Managed AddIn Framework (henceforth known as MAF), is a rather complex beast, and I simply cannot remember all the steps necessary to utilize it properly without a small reference guide. This post will cover the complete step-by-step tutorial of every action that a developer must perform to utilize the AddIn framework. It will not be a complete overview of what MAF is or how all the parts tie together. I will do my best to cover these things, but I have also included some very helpful reference material that will cover these topics better than I ever could.&lt;/p&gt;  &lt;h3&gt;Before continuing&lt;/h3&gt;  &lt;p&gt;This post does not cover all the intricacies and overall design of the Managed AddIn framework. While it will in fact walk you through a step-by-step creation of a WPF app that supports AddIns, it will not fully explain what the various MAF pipeline projects are used for (or the pipeline itself for that matter). It would be in your best interest to watch this excellent screencast from Daniel Roth first.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/DanielMoth/Managed-AddIn-Framework/"&gt;Daniel Roth 18 min screencast&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="http://msdn.microsoft.com/en-us/library/bb384200.aspx" href="http://msdn.microsoft.com/en-us/library/bb384200.aspx"&gt;Excellent MSDN coverage of MAF&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;What is it?&lt;/h3&gt;  &lt;p&gt;MAF is the (much overdue, in my opinion) plugin/addin framework for .NET applications. It allows application developers to expose very simple extensibility points that allows third party developers to enhance your product. Common examples are creating an email client and relying on AddIns for services like Spell Checking, Virus Scanning, etc. Whether plugins are a core part of your application or merely a small feature, the Managed AddIn Framework should be employed to your advantage from here on out.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: System.AddIn is a .NET 3.5 assembly, and as such means that you must target .NETFX 3.5 to utilize it.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb.png" width="446" height="129" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;MAF consists of the following assemblies&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;System.AddIn &lt;/li&gt;    &lt;li&gt;System.AddIn.Contract &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;MAF gives your application the following benefits (at the expense of extra complexity and a steeper learning curve)&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Discovery&lt;/strong&gt; – Find addins at runtime &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Activation&lt;/strong&gt; – Load an addin at runtime &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Versioning&lt;/strong&gt; - Backwards/forward compatibility &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Isolation&lt;/strong&gt; – Load addins into separate AppDomains/Processes so they cannot crash they whole app, among other reasons &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Lifetime&lt;/strong&gt; &lt;strong&gt;Management&lt;/strong&gt; – MAF will handle addin lifetimes and memory/AppDomain management &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Sandboxing&lt;/strong&gt; – Load addins with specific permission sets like “Internet” &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Unloading&lt;/strong&gt; – Unload an addin without worrying about tedious AppDomain management &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Our goal&lt;/h3&gt;  &lt;p&gt;By the end of this article you should be able to produce something like below. I know it doesn’t look like much, but it’s tackling a very specific scenario for a hobby project I am working on currently. The goal is to create a host WPF app that allows me (or third parties) to write addins for the host that will render custom WPF UI and allow interaction with the rest of the application.&lt;/p&gt;  &lt;p&gt;Below we have a very basic WPF window with a TabControl. The cool thing about this application is that the TabControl is databound to an AddIn collection -- the tabs themselves as well as the tab content are entirely rendered at runtime from an AddIn via the Managed AddIn framework.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_3.png" width="305" height="306" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Step 1 – Define Contact Interface and utilize Pipeline Builder&lt;/h3&gt;  &lt;p&gt;The first thing you need to be (painfully) aware of, is the project/directory structure that the MAF Pipeline requires. There is some flexibility here but not a whole lot of wiggle room. Thankfully, the only project I have to concern myself with is the Contract assembly (CouchPotato.AddIn.Contract below). With a proper directory structure in place you can use a tool that the MAF team released called &lt;a href="http://www.codeplex.com/clraddins/Release/ProjectReleases.aspx?ReleaseId=9222"&gt;Pipeline Builder&lt;/a&gt; to generate the necessary MAF projects for you automatically. The arrows below indicate which projects were generated by Pipeline Builder – &lt;strong&gt;it is important to understand that the only project/code I actually wrote in this entire solution is the ICouchPotatoAddInContract.cs.&lt;/strong&gt; Please see the screencast above or the resources below for more details on Pipeline Builder.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_4.png" width="619" height="241" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Ok let’s get started. The following instructions will create the optimal directory/project structure for a MAF-based application.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Prepare the directory structure for your MAF application by creating a parent folder in your Visual Studio 2008\Projects folder (or wherever you choose). I named my folder “CouchPotato” &lt;/li&gt;    &lt;li&gt;Next, create a new Class Library project for your AddIn contact, I chose CouchPotato.AddIn.Contract. Create this project inside your parent folder from Step 1.      &lt;ul&gt;       &lt;li&gt;Add reference to System.AddIn and System.AddIn.Contract &lt;/li&gt;        &lt;li&gt;Hopefully you have installed Pipeline Builder by now, so you should add reference to “C:\Program Files\Microsoft\Visual Studio Pipeline Builder\PipelineHints.dll”          &lt;ul&gt;           &lt;li&gt;&lt;em&gt;This assembly does not need to be deployed with your application. It is only used by the Pipeline Builder during debugging&lt;/em&gt; &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Create your contract interface, I chose the following &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;    &lt;pre class="brush: c#"&gt;
[AddInContract]
public interface ICouchPotatoAddInContract : IContract
{
    string Name { get; }
    string Description { get; }
    void Initialize();
    INativeHandleContract HomeScreen { get; }
}
&lt;/pre&gt;

&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;ul&gt;
  &lt;ul&gt;
    &lt;li&gt;For now, don’t worry about INativeHandleContract. This is an interface that the MAF team added to support much better UI passing between isolation boundaries (AppDomains). This interface allows an AddIn to very easily pass direct UI elements to the host application, which is very important for my application. &lt;/li&gt;

    &lt;li&gt;Notice that MAF requires two rules for your AddIn Contracts: first you must derive from the &lt;strong&gt;IContact&lt;/strong&gt; interface from System.AddIn.Contract assembly, as well as add the &lt;strong&gt;[AddInContract]&lt;/strong&gt; attribute also from the same assembly. &lt;/li&gt;

    &lt;li&gt;Next, I chose to specify some naming ‘hints’ to the Pipeline builder. These hints tell the Pipeline Builder utility what to name the 4 assemblies that it will be generating for me. Click here to view &lt;a href="http://www.codeplex.com/clraddins/Wiki/View.aspx?title=Using%20PipelineHints%20to%20Customize%20Output&amp;amp;referringTitle=Pipeline%20Builder"&gt;all available Pipeline Hints&lt;/a&gt; &lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;pre class="brush: c#"&gt;
[assembly: PipelineHints.SegmentAssemblyName(PipelineHints.PipelineSegment.HostView, "CouchPotato.AddIn.HostView")]
[assembly: PipelineHints.SegmentAssemblyName(PipelineHints.PipelineSegment.AddInView, "CouchPotato.AddIn.AddInView")]
[assembly: PipelineHints.SegmentAssemblyName(PipelineHints.PipelineSegment.HostSideAdapter, "CouchPotato.AddIn.HostSideAdapters")]
[assembly: PipelineHints.SegmentAssemblyName(PipelineHints.PipelineSegment.AddInSideAdapter, "CouchPotato.AddIn.AddInSideAdapters")]
&lt;/pre&gt;

&lt;ul&gt;
  &lt;ul&gt;
    &lt;li&gt;We are almost done, but before we build this project we need to change to output path from the default “/bin/Debug” to “../output/Contracts”. For further explanation on this please see the &lt;a href="http://channel9.msdn.com/posts/DanielMoth/Managed-AddIn-Framework/"&gt;excellent screencast by Daniel Moth&lt;/a&gt;. &lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_5.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_5.png" width="633" height="124" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
  &lt;ul&gt;
    &lt;li&gt;Ok we are ready to build, go ahead and &lt;strong&gt;build your project&lt;/strong&gt;. 

      &lt;ul&gt;
        &lt;li&gt;&lt;em&gt;This step is important because the Pipeline builder does not examine your source code to generate the dependent assemblies, only the compiled code via reflection.&lt;/em&gt; &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;

    &lt;li&gt;Launch the Pipeline Builder from the Tools menu. Default settings should be fine if you have been following along. Pressing OK should generate 4 new projects to your solution, as seen above. &lt;/li&gt;

    &lt;li&gt;&lt;em&gt;Note: &lt;/em&gt;I believe this is a bug I ran into with the Pipeline Builder CTP, but in my case I was forced to rename the generated Assembly Name/Default Namespace after the first generation as seen below. Take a look at your projects and verify these settings. Once you change them the first time you will not have to do it again, even if you use Pipeline builder again (and you will). &lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_6.png" width="767" height="124" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt; &lt;/h3&gt;

&lt;h3&gt;Step 2 – Create our Host WPF Application&lt;/h3&gt;

&lt;p&gt;Now that our AddIn Pipeline is complete let’s create the host application. &lt;/p&gt;

&lt;p /&gt;

&lt;p&gt;Open a new instance of Visual Studio and create a new WPF Project, create it inside the same parent folder that we used for our Contracts project. &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add reference to System.AddIn &lt;/li&gt;

  &lt;li&gt;Add reference to your HostView assembly that can be found by browsing to “../output/CouchPotato.AddIn.HostView.dll” &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;Important: &lt;/em&gt;Make sure you set &lt;strong&gt;CopyLocal=false&lt;/strong&gt; for your HostView assembly &lt;/li&gt;
&lt;/ul&gt;

&lt;p /&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_7.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_7.png" width="775" height="467" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Finally, change your build output path to the root output directory &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_8.png" width="635" height="129" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I have created a very simple WPF Window with a TabControl. As you can see I am taking advantage of the ContentPresenter control to handle rending of the AddIn control for me. This is a great trick &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="brush: xml"&gt;
&amp;lt;TabControl x:Name="PluginContainer" TabStripPlacement="Bottom"&amp;gt;
    &amp;lt;TabControl.ItemTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;StackPanel&amp;gt;
                &amp;lt;TextBlock Text="{Binding Name}" /&amp;gt;
            &amp;lt;/StackPanel&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/TabControl.ItemTemplate&amp;gt;
    &amp;lt;TabControl.ContentTemplate&amp;gt;
        &amp;lt;DataTemplate&amp;gt;
            &amp;lt;Grid&amp;gt;
                &amp;lt;ContentPresenter Content="{Binding HomeScreen}" /&amp;gt;
            &amp;lt;/Grid&amp;gt;
        &amp;lt;/DataTemplate&amp;gt;
    &amp;lt;/TabControl.ContentTemplate&amp;gt;
&amp;lt;/TabControl&amp;gt;
&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;That is the last of our host configuration. Last thing we need to do is Update our AddInStore and load some AddIns &lt;em&gt;(unfortunately, we don’t have any yet, please see Step 3 :)&lt;/em&gt;  &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="brush: c#"&gt;
public Window1()
{
    InitializeComponent();

    AddInStore.Update(PipelineStoreLocation.ApplicationBase);
    Collection&amp;lt;AddInToken&amp;gt; addinTokens = AddInStore.FindAddIns(typeof(ICouchPotatoAddIn), PipelineStoreLocation.ApplicationBase);

    ObservableCollection&amp;lt;ICouchPotatoAddIn&amp;gt; addins = new ObservableCollection&amp;lt;ICouchPotatoAddIn&amp;gt;();
    foreach (AddInToken addinToken in addinTokens)
    {
        ICouchPotatoAddIn addin = addinToken.Activate&amp;lt;ICouchPotatoAddIn&amp;gt;(AddInSecurityLevel.Internet);
        addins.Add(addin);
    }
    
    PluginContainer.ItemsSource = addins;
}
&lt;/pre&gt;


&lt;h3&gt; &lt;/h3&gt;

&lt;h3&gt;Step 3 – Create our first AddIn&lt;/h3&gt;

&lt;p&gt;For this last step we are going to create a fake PhotoGallery AddIn.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Open a new instance of Visual Studio and create a new Class Library project, create it inside the same parent folder that we used for our Contracts project. 
    &lt;ul&gt;
      &lt;li&gt;Add reference System.AddIn &lt;/li&gt;

      &lt;li&gt;If this is a WPF Addin, add reference PresentationFramework for FrameworkElement &lt;/li&gt;

      &lt;li&gt;Add reference to your AddInView assembly that can be found by browsing to “../output/AddInViews/AddInView.dll” &lt;/li&gt;

      &lt;li&gt;&lt;em&gt;Important: &lt;/em&gt;Make sure you set &lt;strong&gt;CopyLocal=false&lt;/strong&gt; for your &lt;strong&gt;AddInView&lt;/strong&gt; assembly &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_9.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_9.png" width="785" height="456" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Set the AddIn output to a &lt;strong&gt;specific directory within the output/AddIns folder&lt;/strong&gt;, for example: &lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;..\output\AddIns\&lt;strong&gt;&lt;em&gt;PhotoGalleryAddIn&lt;/em&gt;&lt;/strong&gt; &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_10.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_10.png" width="622" height="130" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Now that configuration is complete let’s create our UserControl that will represent the UI for the AddIn. Simply right-click on the project and Add New Item, select WPF User Control, add any UI that you choose. &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="brush: xml"&gt;
&amp;lt;UserControl x:Class="CouchPotato.PhotoGalleryAddIn.PhotoGalleryControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300"&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;TextBlock Text="Happy Photos!" /&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/UserControl&amp;gt;
&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Lastly, create a the WeatherAddIn.cs file &lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Implement the ICouchPotatoAddIn interface &lt;/li&gt;

      &lt;li&gt;Add the [AddIn] attribute to describe the AddIn. &lt;/li&gt;

      &lt;li&gt;As you can see below, the Pipeline Builder has turned the INativeHandleContract interface into a FrameworkElement for us! This is very handy, as it will allow seamless calls from UI elements across AppDomains without us knowing anything about it! All we have to do is return any FrameworkElement to satisfy the contract, in this case, a WPF UserControl does in fact derive from FrameworkElement, as does just about anything in the WPF visual namespace. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="brush: c#"&gt;
[AddIn("Photo Gallery", Version = "1.0.0.0")]
public class PhotoGalleryAddin : ICouchPotatoAddIn
{
    private readonly PhotoGalleryControl _control;

    public PhotoGalleryAddin()
    {
        _control = new PhotoGalleryControl();
    }

    public string Name
    {
        get { return "Photo Gallery"; }
    }

    public string Description
    {
        get { return "View all your photos"; }
    }

    public void Initialize()
    {
    }

    public FrameworkElement HomeScreen
    {
        get { return _control; }
    }
}
&lt;/pre&gt;

&lt;h3&gt;Run it!&lt;/h3&gt;

&lt;p&gt;With any luck, hopefully you are able to run your host application and find the AddIn you created. There are a lot of working parts when you use the Managed AddIn Framework, and as such, there are many points of failure. As you can see there is a slight learning curve to utilize MAF but hopefully after this article and the Daniel Moth screencasts you should be pretty comfortable with the framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_11.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ManagedAddInFrameworkSystem.AddInwithWPF_B14E/image_thumb_11.png" width="713" height="551" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a title="http://channel9.msdn.com/posts/DanielMoth/Managed-AddIn-Framework/" href="http://channel9.msdn.com/posts/DanielMoth/Managed-AddIn-Framework/"&gt;Excellent Daniel Moth screencast on MAF&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a title="http://www.codeplex.com/clraddins" href="http://www.codeplex.com/clraddins"&gt;Managed AddIn Framework at CodePlex&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a title="http://www.codeplex.com/clraddins/Release/ProjectReleases.aspx?ReleaseId=9222" href="http://www.codeplex.com/clraddins/Release/ProjectReleases.aspx?ReleaseId=9222"&gt;Pipline Builder&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ddd9789c-b045-4d6d-a88a-d99e0e4214d6" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/MAF" rel="tag"&gt;MAF&lt;/a&gt;,&lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/10.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/10/12/managed-addin-framework-system.addin-with-wpf.aspx</guid>
            <pubDate>Sun, 12 Oct 2008 11:36:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/10.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/10/12/managed-addin-framework-system.addin-with-wpf.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/10.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/10.aspx</trackback:ping>
        </item>
        <item>
            <title>Code Snippets with Snippet Designer and ReSharper Live Templates</title>
            <category>Tools</category>
            <category>Visual Studio</category>
            <category>ReSharper</category>
            <link>http://www.matthidinger.com/archive/2008/10/02/code-snippets-with-snippet-designer-and-resharper-live-templates.aspx</link>
            <description>&lt;h3&gt;Just what exactly are these snippets?&lt;/h3&gt;  &lt;p&gt;I believe that snippets are an underused feature built into Visual Studio. This post is my attempt at comparing the two tools I have used for snippet creation, and hoping to make more developers out there aware of just how easy they are to create and use in your existing projects. I am by no means an expert with either of these tools, but I think that is the point: &lt;em&gt;they take a few minutes to create and can be reused for immediate time savers.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Much to my surprise there exists a significant number of .NET developers that are not taking advantage of code snippets, built-in or otherwise. No doubt you have all seen them in intellisense before: they appear with a partially-jagged piece of paper as seen below. When selected, they expand into a template of code that has select editable variables. A number of predefined code-snippets ship with Visual Studio, many of which I use regularly, including ctor, prop, exception, try, etc.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb.png" width="313" height="219" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The “prop” snippet “expands” into the following code:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_3.png" width="292" height="27" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So the big question is how can we create our own snippets? Let’s take a real-world example and find out.&lt;/p&gt;  &lt;h3&gt;Snipper Designer (free Visual Studio Plugin)&lt;/h3&gt;  &lt;p&gt;A few weeks ago a project was released on CodePlex called Snipper Designer. &lt;a href="http://www.codeplex.com/SnippetDesigner"&gt;Snippet Designer&lt;/a&gt;&lt;strong /&gt; is a plugin for Visual Studio that was previously used internally by Microsoft and has since been released for all of us to enjoy. After downloading the MSI, it istalled in no time and I was on my way to creating a basic snippet I wish I had created long ago. &lt;/p&gt;  &lt;p&gt;To start off I took some Configuration Property code that I had already written as the starting point for my snippet. Anyone who has done extensive configuration with the System.Configuration assembly should be very familiar with this code: it is a property declaration for automatic strongly-typed reading and writing to an XML attribute in your app.config. There are a number of similar code snippets I will be creating for various Configuration-related tasks, and I hope to update this post with my complete list of Configuration snippets shortly.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_4.png" width="715" height="222" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As you can see, the Snipper Designer has added a context menu item to export highlighted code as a snippet. In doing so, the code below was produced in my Snippet Designer:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_5.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_5.png" width="845" height="173" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;From here all I had to do was decide which “variables” would be available in my snippet. This is identifiable by the twin dollar signs ($) at the beginning and end of the variable. Finally, I assigned the snippet a shortcut, which is how we will invoke the snippet expansion in a code file. The shortcut I chose was “configProp.”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_6.png" width="243" height="243" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Our final bit of customization lies in a property pane below the snippet code. From here I can define tooltips to help other developers who may be using my snippets, as well as set default values and expected data types associated with a variable. As you can see, I specified that the isRequired variable should be a Boolean that defaults to true. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_7.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_7.png" width="1069" height="194" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;   &lt;br /&gt;ReSharper Live Templates&lt;/h3&gt;  &lt;p&gt;Many of you will probably be familiar with the Visual Studio plugin &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt;. ReSharper has quickly become a favorite of mine over the last year or so, and I feel as though I have only scratched the surface of it’s productivity potential. One of said features is their own snippet framework (which they have named Live Templates). ReSharper Live Templates are slightly more powerful than the aforementioned Snippet Designer. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_8.png" width="785" height="229" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As you can clearly see, the ReSharper snippet code is almost identical to Snippet Designer. This is a great thing. In fact, I copy-pasted my Snippet Designer code into ReSharper and it instantly recognized it, so the two are very interoperable in that regard. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_9.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_9.png" width="629" height="197" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The variable definition pane is where ReSharper really shines. It has significantly more customization over Snippet Designer, given it’s very nice macro support. I have certainly not experimented with all of these predefined macro’s but they seem like they would be great features for advanced and more intelligent snippet scenarios. I hope to play with them a bit more in the near future. Above you will notice that I have used the “Constant value” macro to specify defaults for the isRequired and DataType variable, which are “true” and “string”, respectively..&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_10.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_10.png" width="383" height="589" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So what exactly did the last few minutes do for us? Well for me, any time in the future where I need to define a new Configuration Property in code, I will no longer by force into vastly error-prone copy-pasting. Instead, I simply trigger my snippet by it’s predefined shortcut. In my case, I chose “configProp.”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_11.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_11.png" width="271" height="212" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;When selected, it expands into this simple code block, which allows me to [tab] through the 5 variables and be on my way. And if you happen to think this won’t save you much time, then I would challenge the fact that you have probably not copy-pasted a significant number of these configuration properties before. As I mentioned in the beginning, I will be creating an army of these snippets, ranging from not only my Configuration-related ones, but repeatable tasks like ViewState-backed property wrappers, etc.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_12.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/CodeSnippetswithSnippetDesignerandReShar_AE89/image_thumb_12.png" width="702" height="109" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Download&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.codeplex.com/SnippetDesigner"&gt;Snippet Designer&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4068c50c-239d-43d9-9139-f53a928416e0" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Visual+Studio" rel="tag"&gt;Visual Studio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ReSharper" rel="tag"&gt;ReSharper&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/9.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/10/02/code-snippets-with-snippet-designer-and-resharper-live-templates.aspx</guid>
            <pubDate>Thu, 02 Oct 2008 11:24:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/9.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/10/02/code-snippets-with-snippet-designer-and-resharper-live-templates.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/9.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/9.aspx</trackback:ping>
        </item>
        <item>
            <title>Synergy - 3 Desktops, 1 Keyboard</title>
            <category>Tools</category>
            <link>http://www.matthidinger.com/archive/2008/06/17/synergy-3-desktops-1-keyboard.aspx</link>
            <description>&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/Synergy3Desktops1Keyboard_AC32/image_3.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://blog2.matthidinger.com/ContentImages/Synergy3Desktops1Keyboard_AC32/image_thumb_3.png" width="390" height="299" /&gt;&lt;/a&gt; I recently noticed a colleague of mine using a hardware KVM to share his desktop keyboard and mouse with his laptop. He had a standard hardware KVM with basic PS/2 inputs and could toggle between the PCs by pressing Scroll Lock twice. Pretty typical setup for many people who have multiple PCs, and it wasn't more than a few years ago that I was doing that same.&lt;/p&gt;  &lt;p&gt;Enter &lt;a href="http://synergy2.sourceforge.net/" target="_blank"&gt;Synergy&lt;/a&gt;. Synergy is actually lot more than a basic KVM. &lt;strong&gt;It makes multiple computers behave exactly as though they were a single PC with dual-monitors.&lt;/strong&gt; You simply move your mouse to the edge of one monitor and it instantly jumps to the next one -- even though they are entirely different computers. &lt;/p&gt;  &lt;p&gt;Synergy also lets you share your clipboard between all connected PCs, and it can even sync screensavers so they all start and stop together. But probably the best feature for some, is that Synergy works on Linux, Windows, and Mac! If you notice the screenshot to the right, I have a Fedora box on the far left. Oh, and did I mention it's open source and totally free?&lt;/p&gt;  &lt;p&gt;From the web site:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Synergy lets you easily share a single mouse and keyboard between multiple computers with different operating systems, each with its own display, without special hardware. It's intended for users with multiple computers on their desk since each system uses its own monitor(s). &lt;/p&gt;    &lt;p&gt;Redirecting the mouse and keyboard is as simple as moving the mouse off the edge of your screen. Synergy also merges the clipboards of all the systems into one, allowing cut-and-paste between systems. Furthermore, it synchronizes screen savers so they all start and stop together and, if screen locking is enabled, only one screen requires a password to unlock them all. &lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://www.matthidinger.com/aggbug/8.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/06/17/synergy-3-desktops-1-keyboard.aspx</guid>
            <pubDate>Tue, 17 Jun 2008 11:14:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/8.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/06/17/synergy-3-desktops-1-keyboard.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/8.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/8.aspx</trackback:ping>
        </item>
        <item>
            <title>LINQ to SQL Audit Trail</title>
            <category>LINQ</category>
            <category>C#</category>
            <category>LINQ to SQL</category>
            <category>Doddle</category>
            <link>http://www.matthidinger.com/archive/2008/05/08/linq-to-sql-audit-trail.aspx</link>
            <description>&lt;h2 style="color: #800000"&gt;&lt;font color="#ff0000"&gt;UPDATE: This post is outdated and has significantly enhanced with a new version. Please see &lt;/font&gt;&lt;a href="http://blog.matthidinger.com/2009/01/12/LINQ+Audit+Trail+V2.aspx"&gt;&lt;font color="#ff0000"&gt;LINQ Audit Trail V2&lt;/font&gt;&lt;/a&gt; &lt;/h2&gt;  &lt;p&gt;In a project I am currently working on, we had a fairly common requirement of recording an Audit Trail of any data changes. The requirements were typical, provide a running log of any changes in the database, including:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;What table was modified? &lt;/li&gt;    &lt;li&gt;What fields changed? &lt;/li&gt;    &lt;li&gt;Who made the change? &lt;/li&gt;    &lt;li&gt;When did it occur? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Naturally, there are many ways to tackle this problem. In the past I have either relied on writing database Triggers for the tables, or wrote the Auditing logic right into the stored procedure that was doing the modification. But this time, since the project is utilizing LINQ to SQL, I had a more ambitious idea in mind. &lt;/p&gt;  &lt;h3&gt;The Goal&lt;/h3&gt;  &lt;p&gt;Create a flexible, and automated Auditing solution that would allow my team to add Audit tracking to any table in our database, with only a single line of C# code. &lt;/p&gt;  &lt;p&gt;The code I ended up with did in fact meet my goal -- which would add Auditing to the Products table and Categories table -- can be seen below.    &lt;br /&gt;As long as you call the Audit&amp;lt;&amp;gt; method before calling SubmitChanges() then any INSERTED/UPDATED/DELETED entities will be properly Audited automatically.     &lt;br /&gt;The first parameter in the method, is telling the Auditing code how to identity which property is the Primary Key of the table.&lt;/p&gt;  &lt;pre class="brush: c#"&gt;

public partial class NorthwindDataContext
{
    public override void SubmitChanges(ConflictMode failureMode)
    {
        this.Audit&amp;lt;Product&amp;gt;(p =&amp;gt; p.ProductID, "Product modified ");
        this.Audit&amp;lt;Category&amp;gt;(c =&amp;gt; c.CategoryID, "Category modified"); 
        base.SubmitChanges(failureMode);
    }
}

&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;TIP: If you are interested in learning how this code was created, then please feel free to read the rest of this article. If however, you are only interested in the finished product and using the code in your projects, then head down to the bottom :)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&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;Step 1 - Database Tables&lt;/h3&gt;

&lt;p&gt;Given my requirements I derived the following database schema. For my purposes, these tables did the trick, but of course your requirements may differ slightly so you may tweak as you wish.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;strong&gt;Audits&lt;/strong&gt; table is used to track any change. Most of the columns should be self-explanatory. The Action is what CUD event occurred (Insert, Update, or Delete). The rest of the columns record who made the change, when, what table, and the Primary Key of the modified record. &lt;/li&gt;

  &lt;li&gt;The &lt;strong&gt;AuditValues&lt;/strong&gt; table is used to track each modified column in the table being audited: the Old (Original), and the New (Current) value. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_thumb.png" width="439" height="585" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;Step 2 - The DBML&lt;/h3&gt;

&lt;p&gt;Now that we have our new tables, we will update our LINQ to SQL Entity classes. I am going to be using Northwind for this example.&lt;/p&gt;

&lt;p&gt; &lt;a href="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_thumb_3.png" width="484" height="845" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;Step 3 - The Public Audit Extension Method&lt;/h3&gt;

&lt;p&gt;First we need to create a public method that client code will use to begin Auditing a table.&lt;/p&gt;

&lt;pre class="brush: c#"&gt;
/// &amp;lt;summary&amp;gt;
/// This method will enlist a LINQ to SQL Entity for automatic Auditing
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="TEntity"&amp;gt;The Entity class you want to audit changes on&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name="tableKeySelector"&amp;gt;A Lambda expression that will return the Primary Key of the Entity&amp;lt;/param&amp;gt;
/// &amp;lt;param name="title"&amp;gt;The text that will be logged in the audit table&amp;lt;/param&amp;gt;
public static void Audit&amp;lt;TEntity&amp;gt;(this DataContext db, Func&amp;lt;TEntity, int&amp;gt; tableKeySelector, string title) where TEntity : class
&lt;/pre&gt;

&lt;p&gt;This is our public entry point for Auditing a table. This method might look a little bit intimidating to those unfamiliar with generic classes and generic delegates. Let's dissect this method to make it a little more palatable.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The first thing you should be aware of, is that this is an Extenstion method to the DataContext class. This is clear when you notice the "this" keyword in the first parameter. That means that this method will be available on any DataContext in our project (assuming of course, that you import the namespace the extension class resides in). &lt;/li&gt;

  &lt;li&gt;The second thing that might look strange is the Func&amp;lt;T1, T2&amp;gt; generic parameter. This is actually a Generic Delegate that exists in the System.Core assembly that ships with 3.5.  The 5 Func&amp;lt;T1, T2, T3, T4, TResult&amp;gt; overloads are used to designate a method that operates on 1 or more inputs (T1 through T4) and returns a TResult. Func's can be seen all over the LINQ namespace and you will get probably pretty familiar with them once you being extending and using LINQ. Typically, they will define the signature for a Lambda expression (which is a new C# shorthand for defining an expression or anonymous method call). In this particular Func&amp;lt;&amp;gt; parameter, I am expecting a method (a Lambda expression, typically), that accepts a TEntity for input, and returns an int. This is required because we need to know how to find the Primary Key property of an Entity. &lt;/li&gt;

  &lt;li&gt;The third unique syntax in this method is the "where" keyword. This is telling the generic method that any TEntity that is passed to this method will be a reference type. This is required because LINQ to SQL can only map reference types. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Step 4 - Auditing LINQ to SQL Entity Inheritance&lt;/h3&gt;

&lt;p&gt;I ran into something unexpected when I began testing the auditing code I wrote: Auditing my Entities that used inheritance. In case you didn't know, LINQ to SQL supports a type of relational inheritance known as Table-Per-Class Hierarchy. This means that every custom field for the derived entity classes are stored in the same table in the database. This article will not go into this subject any further, but please see &lt;a title="http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/10/01/linq-to-sql-inheritance.aspx" href="http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/10/01/linq-to-sql-inheritance.aspx" target="_blank"&gt;Guy Burnstein's Inheritance Article&lt;/a&gt; on the subject of LINQ to SQL inheritance. The following images are courtesy of him, and only for demonstration's sake -- these entities will not be in my sample code.&lt;/p&gt;

&lt;p&gt;&lt;img border="0" alt="Linq to SQL Inheritance" src="http://blogs.microsoft.co.il/blogs/bursteg/WindowsLiveWriter/LinqtoSQLInheritance_7597/Person_0f4a4940-612f-4ad6-9969-9d7eb8cdea18.jpg" width="357" height="457" /&gt;&lt;img border="0" alt="Linq to SQL Inheritance" src="http://blogs.microsoft.co.il/blogs/bursteg/WindowsLiveWriter/LinqtoSQLInheritance_7597/TablePerClassHierarchy_bb6bd854-6f96-44bb-9737-52680ec4f532.jpg" width="297" height="315" /&gt;&lt;/p&gt;

&lt;p&gt;Naturally, I assumed that I could use the following code to Audit entities that supported inheritance just like regular Entities:&lt;/p&gt;

&lt;pre class="brush: c#"&gt;
this.Audit&amp;lt;SalesPerson&amp;gt;(sp =&amp;gt; sp.PersonID, "SalesPerson changed");
this.Audit&amp;lt;Contact&amp;gt;(c =&amp;gt; c.PersonID, "Contact changed");
&lt;/pre&gt;

&lt;p&gt;Unfortunately for me, I was wrong. The Auditing code that I wrote relies on dataContext.GetTable&amp;lt;TEntity&amp;gt; to obtain a reference to the table being audited -- however, when I tried doing dataContext.GetTable&amp;lt;SalesPerson&amp;gt; I received an unpleasant exception stating that a derived entity cannot be used with the GetTable method -- instead, the exception actually suggested that I try dataContext.GetTable&amp;lt;Person&amp;gt;(), which did indeed work.&lt;/p&gt;

&lt;p&gt;So due to this unexpected exception, I had to add an overload to the Audit method that supported two types, a TBaseEntity, and a TSubEntity.&lt;/p&gt;

&lt;pre class="brush: c#"&gt;
this.Audit&amp;lt;Contact, SalesPerson&amp;gt;(sp =&amp;gt; sp.PersonID, "SalesPerson changed");
&lt;/pre&gt;

&lt;p&gt;The method signature for this method is listed below. You will notice an additional Generic Constraint added, defining that TSubEntity must in fact derive from TBaseEntity.&lt;/p&gt;
&lt;pre class="brush: c#"&gt;
/// &amp;lt;summary&amp;gt;
/// This method will enlist a LINQ to SQL Entity for automatic Auditing
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;typeparam name="TBaseEntity"&amp;gt;The Base Entity class you want to audit changes on&amp;lt;/typeparam&amp;gt;
/// &amp;lt;typeparam name="TSubEntity"&amp;gt;The Derived Entity class, for use in LINQ to SQL inheritance&amp;lt;/typeparam&amp;gt;
/// &amp;lt;param name="tableKeySelector"&amp;gt;A Lambda expression that will return the Primary Key of the Entity&amp;lt;/param&amp;gt;
/// &amp;lt;param name="title"&amp;gt;The text that will be logged in the audit table&amp;lt;/param&amp;gt;
public static void Audit&amp;lt;TBaseEntity, TSubEntity&amp;gt;(this DataContext db, Func&amp;lt;TSubEntity, int&amp;gt; tableKeySelector, string title)
       where TBaseEntity : class
       where TSubEntity : TBaseEntity
&lt;/pre&gt;

&lt;h3&gt;Step 5 - Auditing Inserted Records&lt;/h3&gt;

&lt;p&gt;The heart and soul of my auditing code relies on the DataContext's Object Tracking Service. You see, the LINQ to SQL DataContext is of course responsible for tracking entity changes. This is a necessary service so that it is able to queue up every insert, update, and delete -- patiently waiting for a call to dataContext.SubmitChanges(), at which point the context runs through every necessary SQL command to INSERT, UPDATE, and DELETE records in the database.&lt;/p&gt;

&lt;p&gt;Thankfully, the DataContext exposes a GetChangeSet() method, which will allow us to peek into its pending database calls.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_thumb_4.png" width="377" height="159" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;pre class="brush: c#"&gt;
private static void AuditInserts&amp;lt;TEntity, TSubEntity&amp;gt;(DataContext db, Func&amp;lt;TSubEntity, int&amp;gt; tableKeySelector, string title)
    where TEntity : class
    where TSubEntity : TEntity
{
    var inserts = db.GetChangeSet().Inserts.OfType&amp;lt;TSubEntity&amp;gt;();
&lt;/pre&gt;

&lt;p&gt;Here we can see a perfect example of LINQ to Objects. The GetChangeSet().Inserts property return a List&amp;lt;Object&amp;gt;, but that doesn't do us much good, because we are only interested in the Entities we want to audit. Therefore, we can use the new OfType&amp;lt;&amp;gt; extension method to only pull back the entities we are concerned with.&lt;/p&gt;

&lt;p&gt;Next, we need to obtain a reference to the Table&amp;lt;&amp;gt; that our Entity belongs to.&lt;/p&gt;

&lt;pre class="brush: c#"&gt;
Table&amp;lt;TEntity&amp;gt; table = db.GetTable&amp;lt;TEntity&amp;gt;();
&lt;/pre&gt;

&lt;p&gt;Then we need to get all the public properties that our Entity has.&lt;/p&gt;


&lt;pre class="brush: c#"&gt;
PropertyInfo[] props = typeof(TSubEntity).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy);
&lt;/pre&gt;

&lt;p&gt;I have also created a quick helper-method that will create the row in the Audit table for us&lt;/p&gt;

&lt;pre class="brush: c#"&gt;
private static Audit CreateAudit&amp;lt;TEntity&amp;gt;(string title, Table&amp;lt;TEntity&amp;gt; table, int key) where TEntity : class
{
    Audit audit = new Audit();
    audit.TableName = table.ToString();
    audit.TableKey = key;
    audit.UserName = CurrentUser;
    audit.AuditDate = DateTime.Now;
    return audit;
}
&lt;/pre&gt;

&lt;p&gt;The rest of the code is simply looping through all of the Entities in the ChangeSet. &lt;/p&gt;

&lt;pre class="brush: c#"&gt;
foreach (TSubEntity item in inserts)
{
    // Get the Primary Key for our table by Invoking the tableKeySelector delegate on the current TSubEntity item
    int key = tableKeySelector.Invoke(item);

    // Create the Audit
    Audit audit = CreateAudit&amp;lt;TEntity&amp;gt;(title, table, key);
    audit.Title = title + " added";
    audit.Action = "Insert";

    // Loop through every property in our inserted entity
    foreach (PropertyInfo pi in props)
    {
        // This code checks to see if the property is a LINQ to SQL column. You may change this if you need.
        if (pi.HasAttribute(typeof(ColumnAttribute)))
        {
            // I chose to ignore any Id columns in the auditing, again, you may change this
            if (pi.Name.EndsWith("Id"))
                continue;

            // Creat the AuditValue row and add it to our current Audit
            AuditValue values = new AuditValue();
            values.MemberName = pi.Name;
            values.NewValue = GetPropertyValue(pi, item);

            audit.AuditValues.Add(values);
        }
    }

    // Insert the Audit to the database
    db.InsertAudit(audit);
}
&lt;/pre&gt;

&lt;h3&gt;Step 6 - Audit Deletes&lt;/h3&gt;

&lt;p&gt;Very few things change from the Insert code here.&lt;/p&gt;
&lt;pre class="brush: c#"&gt;
var deletes = db.GetChangeSet().Deletes.OfType&amp;lt;TSubEntity&amp;gt;();
&lt;/pre&gt;
&lt;p&gt;I also set the OldValue property instead of the NewValue property when creating the AuditValues entity.&lt;/p&gt;

&lt;pre class="brush: c#"&gt;
AuditValue values = new AuditValue();
values.MemberName = pi.Name;
values.OldValue = GetPropertyValue(pi, item);
&lt;/pre&gt;

&lt;h3&gt;Step 7 - Audit Updates&lt;/h3&gt;

&lt;p&gt;Auditing updates is greatly simplified again thanks to our hard-working DataContext. Every Table&amp;lt;T&amp;gt; class has a GetModifiedMembers method that can be invoked on any entity. This method will only return properties which were CHANGED. This is exactly what I need because I did not want to record any values that stayed the same, especially for tables with a large number of columns.&lt;/p&gt;

&lt;pre class="brush: c#"&gt;
ModifiedMemberInfo[] mmi = table.GetModifiedMembers(item);
foreach (TSubEntity item in updates)
{
    int key = tableKey.Invoke(item);

    Audit audit = CreateAudit&amp;lt;TEntity&amp;gt;(title, table, key);
    audit.Title = title + " updated";
    audit.Action = "Update";

    ModifiedMemberInfo[] mmi = table.GetModifiedMembers(item);

    foreach (ModifiedMemberInfo mi in mmi)
    {
        AuditValue values = new AuditValue();
        values.MemberName = mi.Member.Name;

        values.OldValue = GetPropertyValue(mi.OriginalValue);
        values.NewValue = GetPropertyValue(mi.CurrentValue);

        audit.AuditValues.Add(values);
    }

    db.InsertAudit(audit);
}
&lt;/pre&gt;

&lt;h3&gt;The Finished Results&lt;/h3&gt;

&lt;p&gt;I wrote a very quick demo app for this article. You can see below a GridView of the Audits table rows. We can see what we changed, when, by whom, etc. If you select one of the Audits, a DetailsView will display all of the Changed Values that took place during the Audit.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_5.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_thumb_5.png" width="694" height="211" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_thumb_6.png" width="736" height="257" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_7.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/LINQtoSQLAuditTrail_7DCD/image_thumb_7.png" width="727" height="498" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;Get the Code!&lt;/h3&gt;

&lt;p&gt;If you stuck around for that whole article then I am impressed! If however, you just want to view, experiment with, and use the code, then I provide it here for your use. I have also included the sample Northwind Project so you can play with the demo yourself.&lt;/p&gt;

&lt;p&gt;To download the latest version of this project please see the CodePlex Project: &lt;a href="http://www.codeplex.com/DoddleAudit" target="_blank"&gt;DoddleAudit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading, and please let me know if you end up using this code or have any cool features or optimizations that you have added or would like to see added! 
  &lt;br /&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3ac26440-e383-4f7a-9dbf-876ef1b13bc1" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/LINQ+to+SQL" rel="tag"&gt;LINQ to SQL&lt;/a&gt;,&lt;a href="http://technorati.com/tags/LINQ" rel="tag"&gt;LINQ&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Doddle" rel="tag"&gt;Doddle&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/7.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/05/08/linq-to-sql-audit-trail.aspx</guid>
            <pubDate>Thu, 08 May 2008 11:10:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/7.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/05/08/linq-to-sql-audit-trail.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/7.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/7.aspx</trackback:ping>
        </item>
        <item>
            <title>IE6 Underscore Hack</title>
            <category>Web Standards</category>
            <category>CSS</category>
            <link>http://www.matthidinger.com/archive/2008/05/07/ie6-underscore-hack.aspx</link>
            <description>&lt;p&gt;So as you can see I've been playing with ASP.NET MVC in my free time lately. But as it turns out I learned something totally unrelated to MVC while I was editing the default stylesheet that MVC Preview 2 ships with.&lt;/p&gt;
&lt;pre class="brush: css"&gt;#mainContent
{
    padding: 30px 30px 15px 30px;
    background-color: #FFF;
    border-bottom: 3px groove #4b6f92;
    margin-bottom: 30px;
    _height: 1px; /* only IE6 applies CSS properties starting with an underscrore */
}
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;I can't believe I never knew about this. I have read 3 CSS books in the past few years and don't recall ever reading about this hack. So while it isn't the end-all solution to fixing CSS bugs in IE6, I think it should come in pretty handy in the future now that I know it exists.&lt;/p&gt;
&lt;p&gt;I found this URL to &lt;a title="http://www.wellstyled.com/css-underscore-hack.html" target="_blank" href="http://www.wellstyled.com/css-underscore-hack.html"&gt;WellStyled&lt;/a&gt; which describes the hack in more detail. Here are some cool usage examples of this hack:&lt;/p&gt;
&lt;pre class="brush: css"&gt;#box 
{ 
    min-height: 300px; 
    height: auto; 
    _height: 300px; 
}
#menu 
{ 
    position: fixed; 
    _position: absolute; 
}
&lt;/pre&gt;

&lt;div style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:841dc355-39ad-4514-922c-24858f5af35a" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/CSS"&gt;CSS&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/web+standards"&gt;web standards&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/6.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/05/07/ie6-underscore-hack.aspx</guid>
            <pubDate>Wed, 07 May 2008 11:01:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/6.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/05/07/ie6-underscore-hack.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/6.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/6.aspx</trackback:ping>
        </item>
        <item>
            <title>Entity Framework Comparison Frustration: Explained</title>
            <category>C#</category>
            <category>LINQ</category>
            <category>Entity Framework</category>
            <link>http://www.matthidinger.com/archive/2008/02/26/entity-framework-comparison-frustration-explained.aspx</link>
            <description>&lt;p&gt;This post is a follow-up to an article I wrote a few weeks ago, &lt;a target="_blank" href="http://blog.matthidinger.com/2008/02/01/ADONETEntityFrameworkComparisonFrustration.aspx"&gt;ADO.NET Entity Framework Comparison Frustration&lt;/a&gt;. As a quick re-cap, I was simply trying to filter a list of users with a LINQ query expression by comparing custom classes, not primitive types.&lt;/p&gt;
&lt;pre class="brush: c#"&gt;TorvusEntities entities = new TorvusEntities(); 

// Pull my Account Entity from the database
Account matt = entities.Accounts.First(a =&amp;gt; a.AccountId == 10);

// Attempt to get all Teams by a Team Owner
var teams = from t in entities.Teams
                 where t.Owner == matt
                 select t;
&lt;/pre&gt;
&lt;p&gt;However, an exception was thrown. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Unable to create a constant value of type 'Closure type'. Only primitive types (for instance Int32, String and Guid) are supported in this context.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So I left it at that. The Entity Framework could only handle comparison on primitive types, which makes sense of course, since the expression needs to be converted into the underlying data storage language (T-SQL in this case). I was simply hoping that they would provide a more object-oriented way of translating the comparison I hoped to express by some other means. E.g., overriding Object.Equals() or the == operator, implementing a certain interface on my entities, something that felt OO to me.&lt;/p&gt;
&lt;p&gt;Today however, I found my answer. Embarrassingly enough, it was &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb738686.aspx"&gt;in the MSDN docs all along&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A comparison expression checks whether a constant value, property value, or method result is equal, not equal, greater than, or less than another value. If a particular comparison is not valid for LINQ to Entities, an exception will be thrown. [Specifically, the exception I wrote above.] All comparisons, both implicit and explicit, require that all components are comparable in the data store. Comparison expressions are often used in &lt;strong&gt;Where&lt;/strong&gt; clauses for restricting the query results. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And here it is, the confirmation I wanted (albeit not the answer I was hoping for):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LINQ to Entities does not support using a user class as a constant. However, a property reference on a user class is considered a constant, and will be converted to a command tree constant expression and executed on the data store.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh, another thing worth mentioning, method returns don't count as so-called constant expressions, and will thrown an exception when attempted.&lt;/p&gt;
&lt;pre class="brush: c#"&gt;public class MyBusinessObject
{
    public int GetId()
    {
        return 5;
    }
}

public class Test
{
    public Test()
    {
        using (TorvusEntities context = new TorvusEntities())
        {
            MyBusinessObject myBo = new MyBusinessObject();
            var accounts = from a in context.Accounts
                           where a.AccountId == myBo.GetId()
                           select a;

            // Exception will be thrown at run-time,
            // methods do not count as Constant expressions
        }
    }
}
&lt;/pre&gt;
&lt;div style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:283bb60c-493f-48e3-97d4-2b34e173e875" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/Entity+Framework"&gt;Entity Framework&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/LINQ"&gt;LINQ&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/5.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/02/26/entity-framework-comparison-frustration-explained.aspx</guid>
            <pubDate>Tue, 26 Feb 2008 11:59:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/5.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/02/26/entity-framework-comparison-frustration-explained.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/5.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/5.aspx</trackback:ping>
        </item>
        <item>
            <title>Styles up Top, Scripts on Bottom</title>
            <category>ASP.NET</category>
            <category>JavaScript</category>
            <category>Web Standards</category>
            <link>http://www.matthidinger.com/archive/2008/02/25/styles-up-top-scripts-on-bottom.aspx</link>
            <description>&lt;p&gt;Today I just stumbled onto some interesting information regarding placements of script blocks and CSS links. According to some extensive testing performed at Yahoo!, they have published a list of &lt;a title="http://developer.yahoo.com/performance/rules.html" target="_blank" href="http://developer.yahoo.com/performance/rules.html"&gt;Best Practices for Speeding Up Your Web Site&lt;/a&gt;. Many of these rules came as no surprise, for example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;While researching performance at Yahoo!, we discovered that moving stylesheets to the document HEAD makes pages load faster. This is because putting stylesheets in the HEAD allows the page to render progressively. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;However, one rule caught my attention:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Rule 5 described how stylesheets near the bottom of the page prohibit progressive rendering, and how moving them to the document HEAD eliminates the problem. Scripts (external JavaScript files) pose a similar problem, but the solution is just the opposite: it's better to move scripts from the top to as low in the page as possible. One reason is to enable progressive rendering, but another is to achieve greater download parallelization. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So sure I thought, maybe it will provide better performance, but when creating internet-facing web sites I am a firm believer in standards and compliance. I admit I don't run my markup through an XHTML validator as much as I should, but I was always under the impression that for valid XHTML, &amp;lt;script&amp;gt; blocks and includes belong in the &amp;lt;head&amp;gt; element. Nay, according to the working &lt;a target="_blank" href="http://www.w3.org/TR/2003/WD-xhtml2-20030506/mod-scripting.html#edef_scripting_script"&gt;W3C XHTML Draft&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;a href="http://www.w3.org/mod-scripting.html#edef_scripting_script"&gt;script&lt;/a&gt; element places a script within a document. This element may appear any number of times in the &lt;a href="http://www.w3.org/mod-structure.html#edef_structure_head"&gt;head&lt;/a&gt; or &lt;a href="http://www.w3.org/mod-structure.html#edef_structure_body"&gt;body&lt;/a&gt; of an XHTML document.&lt;/p&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;div style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4980c230-fa20-4baf-9dae-1782451fdf1a" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/javascript"&gt;javascript&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/web+standards"&gt;web standards&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/aspnet"&gt;aspnet&lt;/a&gt;&lt;a rel="tag" href="http://technorati.com/tags/css"&gt;css&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/4.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/02/25/styles-up-top-scripts-on-bottom.aspx</guid>
            <pubDate>Mon, 25 Feb 2008 11:52:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/4.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/02/25/styles-up-top-scripts-on-bottom.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/4.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/4.aspx</trackback:ping>
        </item>
        <item>
            <title>ASP.NET Debugging Tip</title>
            <category>ASP.NET</category>
            <category>Visual Studio</category>
            <link>http://www.matthidinger.com/archive/2008/02/25/asp.net-debugging-tip.aspx</link>
            <description>&lt;p&gt;Honestly, I'm not sure if this setting is new to Visual Studio 2008 or not, but I just stumbled onto it. Typically when I'm debugging an ASP.NET application I test one page at a time, by right-clicking on the aspx and selecting &lt;strong&gt;View in Browser&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt; &lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETDebuggingTip_A3DC/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETDebuggingTip_A3DC/image_thumb.png" width="230" height="279" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I prefer this method because I can keep the browser open at all times during development and not have to compile the whole site to quickly test something simple like markup changes. The caveat to this however, is that the Visual Studio debugger is not attached to the cassini process, so I cannot hit any break points I have set. For scenarios when I need to debug and step through code, I press the Debug button, wait for the site to compile and spawn a new browser window, and then I manually navigate to the page I want to debug. Sure this isn't a very big deal, but it would be more convenient to use the browser window I already have open, which is usually already on the page I want to test.&lt;/p&gt;  &lt;p&gt;So I found this setting in the Web Application Properties for my site. Now when I enter debug mode, Visual Studio won't spawn a browser, it will simply wait for me to hit Refresh on the browser I already have open. It's a pretty minor change, but I find it to be very convenient.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETDebuggingTip_A3DC/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETDebuggingTip_A3DC/image_thumb_3.png" width="799" height="418" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d2d05082-95c8-45b5-b8f1-a1445083f3c5" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Visual+Studio" rel="tag"&gt;Visual Studio&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ASPNET" rel="tag"&gt;ASPNET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ASPNET+MVC" rel="tag"&gt;ASPNET MVC&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/3.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/02/25/asp.net-debugging-tip.aspx</guid>
            <pubDate>Mon, 25 Feb 2008 11:38:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/3.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/02/25/asp.net-debugging-tip.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/3.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/3.aspx</trackback:ping>
        </item>
        <item>
            <title>ASP.NET MVC UserControls Start to Finish</title>
            <category>ASPNET MVC</category>
            <link>http://www.matthidinger.com/archive/2008/02/21/asp.net-mvc-usercontrols-start-to-finish.aspx</link>
            <description>&lt;p&gt;The ASP.NET MVC framework ships with a number of Visual Studio project and item templates to ease our development tasks. One of these templates is a UserControl built specifically for the MVC framework. We are going to walkthrough building a re-usable Header control that can be added to the top of related pages (in this specific case, this Control will be added to all Account pages). If you want to get technical, I suppose this may be a good candidate for the new Nested Master Page support in Visual Studio 2008. But for our purposes, this will do just fine.&lt;/p&gt;  &lt;p&gt;Our end-result will be a control that looks like this, and can be added very easily to our View Pages to provide a consistent navigation element.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb.png" width="828" height="56" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Create the Control&lt;/h3&gt;  &lt;p&gt;First let's add a new &lt;strong&gt;MVC View User Control&lt;/strong&gt; control to our Views folder in the solution.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_3.png" width="644" height="397" /&gt;&lt;/a&gt; &lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_4.png" width="257" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Once our control is added, we need to make a few very small changes to the CodeBehind file. The MVC framework provides us the flexibility to use a strongly-typed generic version of the &lt;strong&gt;ViewUserControl&lt;/strong&gt; class, much like the &lt;strong&gt;ViewPage&lt;/strong&gt; class. The difference between &lt;strong&gt;ViewUserControl&lt;/strong&gt; and &lt;strong&gt;ViewUserControl&amp;lt;T&amp;gt; &lt;/strong&gt;is that in the generic version you explicitly define the Type of &lt;strong&gt;ViewData&lt;/strong&gt; you will be passing to your UserControl. If you choose to use the non-generic version the &lt;strong&gt;ViewData &lt;/strong&gt;property will be a simple dictionary of objects, instead of strongly-typed properties. &lt;/p&gt;  &lt;p&gt;Lets go ahead and tell our UserControl we will be passing it an instance of the &lt;strong&gt;AccountViewData&lt;/strong&gt; class I created. I also added a simple automatic property called &lt;strong&gt;SelectedItem&lt;/strong&gt; that we will use to specify which menu item should be "selected." We will use this property in a future post.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_5.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_5.png" width="499" height="215" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_6.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_6.png" width="688" height="126" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So here's the markup for our control. You'll notice that was can access the &lt;strong&gt;ViewData&lt;/strong&gt; property the same way we access it from a Page instance. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_7.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_7.png" width="877" height="331" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;But where does the ViewData come from?&lt;/h3&gt;  &lt;p&gt;Well, let me first say, I am not an expert on this subject yet. Here is what I know.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It Just Works if you have a &lt;strong&gt;ViewUserControl&amp;lt;T&amp;gt;&lt;/strong&gt; and a &lt;strong&gt;ViewPage&amp;lt;T&amp;gt; &lt;/strong&gt;&lt;em&gt;where T is the same type for both!&lt;/em&gt;       &lt;ul&gt;       &lt;li&gt;For example, if you have ProfilePage&amp;lt;&lt;em&gt;AccountViewData&lt;/em&gt;&amp;gt;, TeamPage&amp;lt;&lt;em&gt;AccountViewData&lt;/em&gt;&amp;gt;, FriendsPage&amp;lt;&lt;em&gt;AccountViewData&lt;/em&gt;&amp;gt;, your ViewUserControl&amp;lt;&lt;em&gt;AccountViewData&lt;/em&gt;&amp;gt; will have its ViewData property automatically populated by the MVC framework! This might not always be ideal however, as it essentially couples your user control to the page(s), as well as gives the control access to ALL data that the page has. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;An MVC UserControl also exposes a public &lt;strong&gt;ViewDataKey&lt;/strong&gt; property that the page can use to specify a subset of its ViewData that it should forward to the Control. I'll try and elaborate more on this later. &lt;/li&gt;    &lt;li&gt;The MVCToolkit currently has an overloaded Html.RenderUserControl() method that allows you to specify custom ViewData, as well as assign any properties to the control. This is the method I will be using for the Header control in this walkthrough. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I will possibly post more on this subject once I have more time and experiment with it.&lt;/p&gt;  &lt;h3&gt;Let's Add the Control to our Page&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_8.png" width="523" height="20" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Our first page to use the control will be the Account Profile page. It will be using the generic version of ViewPage, and will be accepting an instance of type &lt;strong&gt;AccountProfileViewData&lt;/strong&gt;, which is defined for your reference above. Something worth noting: I am experimenting with standard inheritance in my ViewData containers. The thought process is simple, AccountViewData will expose the properties that are common to all of my Account-related pages, where the individual Pages themselves will typically have a derived Account__Page__ViewData class to add any additional data. The careful observer may have noticed that my UserControl is accepting the parent type AccountViewData, whereas my Profile page is actually rendering using data from the derived AccountProfileViewData. This will come in handy later.&lt;/p&gt;  &lt;h4&gt;   &lt;br /&gt;Method 1 - Drag the UserControl onto the designer surface&lt;/h4&gt;  &lt;p&gt;This is the method we typically used in WebForms development. &lt;em&gt;Be alert though, Visual Studio will add a &amp;lt;form runat="server"&amp;gt; when you do this. This should be removed, the UserControl will still function.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_9.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_9.png" width="533" height="26" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;One difference here, as mentioned a moment ago. An MVC UserControl allows us to specify a ViewDataKey. I won't be using this method right now, but I found &lt;a href="http://blog.matthidinger.com/ct.ashx?id=befbb634-7388-496a-afca-114bfd97fa29&amp;amp;url=http%3a%2f%2fdotnetaddict.dotnetdevelopersjournal.com%2faspnet_devseries_3.htm" target="_blank"&gt;&lt;strong&gt;a good article&lt;/strong&gt;&lt;/a&gt; on the subject here.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_10.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_10.png" width="470" height="193" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Take a look at the Controller Action below. We are creating an instance of AccountProfileViewData, which derives from AccountViewData, and passing it to the RenderView method. This makes perfect sense, since our ProfilePage&amp;lt;AccountProfileViewData&amp;gt; expects this! But what about our Header&amp;lt;AccountViewData&amp;gt; control that is expecting AccountViewData? Simply enough, the MVC framework takes care of it for us! Because of standard IS-A OO relationship, our AccountProfileViewData object IS-A AccountViewData object. Our UserControl works just fine with this! Perfect, our User Control only has access to the data it needs, the Page has access to all the data it needs, and everyone is happy.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_11.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_11.png" width="561" height="348" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h5&gt;Method 2 - Html.RenderUserControl&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_12.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCUserControlsStarttoFinish_B993/image_thumb_12.png" width="915" height="29" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This is simply another method for adding a UserControl to your page. That &lt;strong&gt;null &lt;/strong&gt;parameter you see in there allows you to pass in any controlData that the control expects. So your page would be responsible for sending it the proper data the control requires. I used null this time because the MVC framework passed my data for me because of the inheritance hierarchy I used. (See above). Also note, you can assign any number of Properties that the UserControl expects using anonymous-type syntax.&lt;/p&gt;  &lt;p&gt;I apologize this post was all over the place. If anyone reading this has any questions by all means let me know and I will elaborate further.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:56f10c5d-4a64-4388-ba41-d8ff97513386" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/ASPNET+MVC" rel="tag"&gt;ASPNET MVC&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/17.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/02/21/asp.net-mvc-usercontrols-start-to-finish.aspx</guid>
            <pubDate>Thu, 21 Feb 2008 13:11:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/17.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/02/21/asp.net-mvc-usercontrols-start-to-finish.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/17.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/17.aspx</trackback:ping>
        </item>
        <item>
            <title>ASP.NET MVC Conditional Render Helper</title>
            <category>ASPNET MVC</category>
            <link>http://www.matthidinger.com/archive/2008/02/20/asp.net-mvc-conditional-render-helper.aspx</link>
            <description>&lt;p&gt;Many of us have probably encountered the need for this on various projects. The scenario is simple, we have optional fields that a user may or may not enter values for, and we would like to hide them from display if they were not filled in.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="482" height="231" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The above screenshot could use some cleaning up. Ideally those fields that contain no data should be hidden from the rendered HTML. Our first attempt might look something like below, but hopefully, after 1 or 2 copy pastes any developer will realize this should be handled differently. Who among us has run into maintaining code looking like this? &lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_3.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="646" height="149" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_thumb_3.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Ok let's go back to the drawing board. The MVCToolkit comes with many extension methods for the HtmlHelper class that ships with the ASP.NET MVC framework. The Html object is accessible to every MVC Page, and will prove invaluable for generating inputs like  RadioButtonLists, DropDownLists, Submit buttons, etc. Let's see how it will look if we add a ConditionalRender extension to the HtmlHelper class. Our ideal code will look something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_4.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="672" height="188" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_thumb_4.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;That looks pretty good, but we need a mechanism to tell the ConditionalRender helper how to format the returned HTML. To do this, we can add a string variable to define the format we want returned and pass it to the helper, as shown below:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_5.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="727" height="237" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_thumb_5.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Excellent, as we can see below, the fields the user entered are displayed nicely for us, while the fields that were left empty are not rendered to our output HTML at all.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_6.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="image" border="0" alt="image" width="501" height="132" src="http://blog2.matthidinger.com/ContentImages/ASP.NETMVCConditionalRenderHelper_B818/image_thumb_6.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Here is the code the extension method. Just be sure to &amp;lt;add namespace="MattHidinger.Extensions"&amp;gt; to your web.config, so that the extension method will be imported to all of your Pages.&lt;/p&gt;

&lt;pre class="brush: c#"&gt;
namespace MattHidinger.Extensions
{
    public static class HtmlExtensions
    {
        public static string ConditionalRender(this HtmlHelper helper, object input, string label, string format)
        {
            if (input == null)
                return string.Empty;
 
            return string.Format(format, label, input.ToString());
        }
    }
}
&lt;/pre&gt;

&lt;div style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:02e9b0dc-4f97-4ea3-8295-a60064e14bed" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/ASPNET+MVC"&gt;ASPNET MVC&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/16.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/02/20/asp.net-mvc-conditional-render-helper.aspx</guid>
            <pubDate>Wed, 20 Feb 2008 13:05:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/16.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/02/20/asp.net-mvc-conditional-render-helper.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/16.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/16.aspx</trackback:ping>
        </item>
        <item>
            <title>ADO.NET Entity Framework Comparison Frustration</title>
            <category>Entity Framework</category>
            <link>http://www.matthidinger.com/archive/2008/02/01/ado.net-entity-framework-comparison-frustration.aspx</link>
            <description>&lt;p&gt;Today I began playing with the &lt;a target="_blank" href="http://blog.matthidinger.com/ct.ashx?id=1d3e122e-345a-4975-801d-526a15480442&amp;amp;url=http%3a%2f%2fmsdn2.microsoft.com%2fen-us%2flibrary%2faa697427(VS.80).aspx"&gt;ADO.NET Entity Framework&lt;/a&gt;. This framework looks very promising and I plan on experimenting with it heavily this weekend, so expect some more ADOe articles over the next few weeks.&lt;/p&gt;
&lt;p class="Update"&gt;[Update: I discovered more about this subject while reading in-depth the MSDN articles on the ADO.NET Entity Framework. I have updated my conclusions at &lt;a href="http://blog.matthidinger.com/ct.ashx?id=1d3e122e-345a-4975-801d-526a15480442&amp;amp;url=http%3a%2f%2fblog.matthidinger.com%2f2008%2f02%2f26%2fEntityFrameworkComparisonFrustrationExplained.aspx"&gt;Entity Framework Comparison Frustration: Explained&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Without going into too much detail, ADOe is very similar to LINQ to SQL. It is essentially a more advanced OR/M that is built into the .NET framework and integrated heavily with Visual Studio designer support, complete with a few snap-in panes for visually mapping your database schema to your CLR objects. I found this post on MSDN &lt;a target="_blank" href="http://blog.matthidinger.com/ct.ashx?id=1d3e122e-345a-4975-801d-526a15480442&amp;amp;url=http%3a%2f%2fforums.microsoft.com%2fMSDN%2fShowPost.aspx%3fPostID%3d1935713%26SiteID%3d1"&gt;explaining the major differences&lt;/a&gt; between LINQ to SQL and the ADO.NET Entity Framework.&lt;/p&gt;
&lt;p&gt;Later I will go into much more detail about ADOe in general, but for now I wanted to bring up a problem I ran into tonight. My database schema is simple, I have a table called Teams, and a table called Accounts. Each Team has an OwnerId which relates to the AccountId of the Account table -- every Team must have an owner. Lets try and get all Teams for a specific Account... &lt;/p&gt;
&lt;pre class="brush: c#"&gt;TorvusEntities entities = new TorvusEntities();

// Pull my Account Entity from the database
Account matt = entities.Accounts.First(a =&amp;gt; a.AccountId == 10);
 
// Attempt to get all Teams by a Team Owner
var teams = from t in entities.Teams
            where t.Owner == matt
            select t;
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://blog.matthidinger.com/ct.ashx?id=1d3e122e-345a-4975-801d-526a15480442&amp;amp;url=http%3a%2f%2f11011.net%2fsoftware%2fvspaste"&gt;&lt;/a&gt;Looks pretty simple right? The driving force behind ADOe is of course to abstract away data access, so that any .NET developer can read and understand the query intention even if he had never seen T-SQL before in his life. Well, apparently my query isn't acceptable. I am getting an exception:&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4&gt;&lt;em&gt;Unable to create a constant value of type 'Closure type'. Only primitive types (for instance Int32, String and Guid) are supported in this context.&lt;/em&gt;&lt;/h4&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hmm, ok that's unfortunate. Google is turning up nothing interesting. Apparently the Entity framework can only query primitive types. So naturally I tried to compare the AccountId property instead of a direct instance-to-instance comparison -- something that, IMHO, looks more like T-SQL than C#.&lt;/p&gt;
&lt;pre class="brush: c#"&gt;// This works, by comparing the AccountId (int) column
var teams = from t in entities.Teams
             where t.Owner.AccountId == matt.AccountId
             select t;
&lt;/pre&gt;
&lt;p&gt;So I started thinking, maybe ADOe just needs to know how to compare two instances, let's override some operators&lt;/p&gt;
&lt;pre class="brush: c#"&gt;public partial class Account
 {
     public static bool operator ==(Account a, Account b)
     {
         return a.AccountId == b.AccountId;
     }
 }
&lt;/pre&gt;
&lt;p&gt;Damn, same exception. Well I'm going to admit that this could very possibly be an error on my part, after all it's 2 AM and I only installed ADOe Beta 3 a few hours ago... I'll update if I discover anything.&lt;/p&gt;
&lt;div style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cd89144d-ac16-426c-a94c-b24b278d7a79" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a rel="tag" href="http://technorati.com/tags/Entity+Framework"&gt;Entity Framework&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.matthidinger.com/aggbug/18.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matt Hidinger</dc:creator>
            <guid>http://www.matthidinger.com/archive/2008/02/01/ado.net-entity-framework-comparison-frustration.aspx</guid>
            <pubDate>Fri, 01 Feb 2008 13:16:00 GMT</pubDate>
            <wfw:comment>http://www.matthidinger.com/comments/18.aspx</wfw:comment>
            <comments>http://www.matthidinger.com/archive/2008/02/01/ado.net-entity-framework-comparison-frustration.aspx#feedback</comments>
            <wfw:commentRss>http://www.matthidinger.com/comments/commentRss/18.aspx</wfw:commentRss>
            <trackback:ping>http://www.matthidinger.com/services/trackbacks/18.aspx</trackback:ping>
        </item>
    </channel>
</rss>
