<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;Ak8EQX84eCp7ImA9WhRbEks.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979</id><updated>2012-02-03T11:33:20.130Z</updated><category term="List.aspx" /><category term="white-space: nowrap" /><category term="Custom Filter" /><category term="ListActionPath" /><category term="Y/N Field" /><category term="Database Based Permissions" /><category term="Default Sort Column" /><category term="ItemTemplate" /><category term="Regular Expressions" /><category term="Linq join" /><category term="Model" /><category term="DetailsView" /><category term="France" /><category term="DomainDataSource" /><category term="Web Application Project" /><category term="Searching" /><category term="Roles" /><category term="Conversion" /><category term="Job" /><category term="Live Writer" /><category term="LayoutTemplate" /><category term="DynamicField" /><category term="FileImage_Edit" /><category term="css" /><category term="FromView" /><category term="Conditional" /><category term="IQueryable" /><category term="Session variables" /><category term="Grouping" /><category term="SP1 Release" /><category term="Extension Methods" /><category term="Linq to SQL" /><category term="ReadOnlyAttribute" /><category term="ITemplate" /><category term="PDF to Image" /><category term="Required Field" /><category term="History" /><category term="DynamicData" /><category term="Preview 4" /><category term="Events" /><category term="Preview" /><category term="File Upload" /><category term="DynamicControl" /><category term="Dynamic Data Futures" /><category term="Hierarchical" /><category term="GridView Pager Size" /><category term="DataContext" /><category term="DynamicHyperLink" /><category term="LightSwitch" /><category term="Watermark" /><category term="TypeDescriptor" /><category term="jQuery" /><category term="I'm Back" /><category term="Rollover" /><category term="Compound Properties" /><category term="Row Highlighting" /><category term="ITemplate class" /><category term="GridView" /><category term="ObjectContext" /><category term="MVP" /><category term="CustomTypeDescriptor" /><category term="AJAX HTML Editor" /><category term="UIHint" /><category term="Vacation" /><category term="Blogger" /><category term="Templates" /><category term="InsertItemTemplate" /><category term="CTP4" /><category term="Hide Column" /><category term="NuGet" /><category term="Agile Principals" /><category term="FieldTemplate" /><category term="Custom Field Templates" /><category term="Expression Trees" /><category term="User Filter" /><category term="ASP.Net" /><category term="Looking for a Job" /><category term="Entity Framework" /><category term="Default Values" /><category term="Cascading FieldTemplates" /><category term="PDF To Text" /><category term="DynamicDataFutures" /><category term="OnSavingChanges" /><category term="Sorting" /><category term="Camp-Hôtel Pachacaïd" /><category term="Cascading Controls" /><category term="Business Logic/Validation" /><category term="MataTable" /><category term="Pascal to Human" /><category term="DynamicDataExtensions" /><category term="Permissions" /><category term="Syntax Highlighter" /><category term="ABCpdf .Net 7" /><category term="CTP" /><category term="I18N" /><category term="ForeignKey_Edit" /><category term="Security" /><category term="IAutoFieldGenerator" /><category term="Visual Studio 2010" /><category term="Build-5/23a" /><category term="RegisterControl" /><category term="Digsby" /><category term="ToArray" /><category term="VB Code" /><category term="Dynamic Data Filtering" /><category term="Advertisement" /><category term="Custom Page Template" /><category term="FilterUserControl" /><category term="Command Column" /><category term="Limit FilterRepeater" /><category term="Image Handler" /><category term="Links" /><category term="Routing Constraint" /><category term="Routing" /><category term="TypeDescriptionProvider" /><category term="Autocomplete" /><category term="ListView" /><category term="Read-Only" /><category term="Code First" /><category term="OnDataBind" /><category term="GetColumnValue" /><category term=".Net 4.0" /><category term="Metadata" /><category term="Linq to Entities" /><category term="Validation Groups" /><category term="FilterTemplates" /><category term="DisplayColumnAttribute" /><category term="Holiday" /><category term="DomainService" /><category term="ASP.Net 4.0" /><category term="Cascading Filters" /><category term="Filtering" /><category term="Web User Controls" /><category term="CustomValidator" /><category term="EditItemTemplate" /><category term="Custom Meta Classes" /><category term="Generics" /><category term="File Based Website" /><category term="Custom Pages" /><category term="Add Preview to Web Site" /><category term="Render" /><category term="Multi Column Search" /><category term="ForeignKey Columns" /><category term="Attributes" /><category term="Visual Studio 2008 SP1 beta" /><category term="AJAX History" /><category term="Children" /><category term="Linq" /><category term="Validation" /><category term="External Class Library" /><category term="Patterns and Practices in C#" /><category term="Multiple Models" /><category term="Filters" /><category term="Partial Methods" /><category term="Dynamic Data" /><category term="Custom Attribute" /><category term="GetActionPath" /><category term="Attribute Based Permission" /><category term="MetaColumn" /><category term="Password" /><category term="Entity Templates" /><category term="OrderBy" /><category term="Silverlight" /><category term="AJAX Control Toolkit" /><category term="Books" /><title>C# Bits</title><subtitle type="html">ASP.Net, Dynamic Data, LightSwitch and c# stuff: Focused on what new and cool, code tutorials and useful tricks and tips on getting the most out of ASP.Net and ASP.Net MVC. All in C#</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://csharpbits.notaclue.net/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>145</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/notaclue/IYRx" /><feedburner:info uri="notaclue/iyrx" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEQMQH8_cCp7ImA9WhdaEUQ.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-6925223093742230174</id><published>2011-10-21T12:23:00.001+01:00</published><updated>2011-10-21T12:26:21.148+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-21T12:26:21.148+01:00</app:edited><title>Axialis Software Ribbon &amp; Toolbar Stock Icons - Basic Set Offer</title><content type="html">&lt;p&gt;   &lt;table border="0" cellspacing="0" cellpadding="2" width="903"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="154"&gt;&lt;img src="https://usd.swreg.org/soft_shop/templates/47156/l4.gif" /&gt;&lt;/td&gt;          &lt;td valign="top" width="747"&gt;are offering 30%-off discount to my readers for their new &lt;a href="http://www.axialis.com/stock-icons/ribbon-toolbar.html"&gt;Windows Ribbon &amp;amp; Toolbars Stock Icons Basic Set&lt;/a&gt;, they are provided in sizes 48x48, 32x32, 24x42, 16x16, different states (normal, hot, disabled) and RGBA / RGB color depths. Called &amp;quot;Basic&amp;quot;, the first set contains 1108 unique icons. Including all sizes and derivatives, more that 29,000 images are provided. &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.axialis.com/stock-icons/ort-illustration-2.png" /&gt;&lt;/p&gt;  &lt;p&gt;Get the offer &lt;a href="https://usd.swreg.org/cgi-bin/s.cgi?s=47156&amp;amp;p=47156-14&amp;amp;q=1&amp;amp;rc=45K2D45KC4"&gt;here&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This offer will last 30 days up to Nov 20: &lt;/p&gt;  &lt;p&gt;These look great and will be ideal for &lt;a href="http://www.microsoft.com/click/services/Redirect2.ashx?CR_CC=200046556"&gt;Visual Studio LightSwitch 2011&lt;/a&gt; toolbars&lt;/p&gt; &lt;span class="sbmLink"&gt;   &lt;table cellspacing="1" cellpadding="1"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td class="sbmText"&gt;Share this post : &lt;/td&gt;          &lt;td&gt;&lt;a title="Post it to del.icio.us" href="http://del.icio.us/post?url=http://csharpbits.notaclue.net/2011/10/axialis-software-ribbon-toolbar-stock.html&amp;amp;;title=Axialis Software Ribbon &amp;amp; Toolbar Stock Icons - Basic Set Offer" target="_blank"&gt;&lt;img border="0" src="http://blogs.msdn.com/blogfiles/rahulso/WindowsLiveWriter/IconsfordifferentSocialBookmarkingSites_B387/deliciou4.png" /&gt;&lt;/a&gt;&lt;/td&gt;          &lt;td&gt;&lt;a title="Post it to digg" href="http://digg.com/submit?phase=2&amp;amp;url=http://csharpbits.notaclue.net/2011/10/axialis-software-ribbon-toolbar-stock.html&amp;amp;title=Axialis Software Ribbon &amp;amp; Toolbar Stock Icons - Basic Set Offer" target="_blank"&gt;&lt;img border="0" src="http://blogs.msdn.com/blogfiles/rahulso/WindowsLiveWriter/IconsfordifferentSocialBookmarkingSites_B387/digg14.png" /&gt;&lt;/a&gt;&lt;/td&gt;          &lt;td&gt;&lt;a title="Post it to dotnetkicks" href="http://www.dotnetkicks.com/kick/?url=http://csharpbits.notaclue.net/2011/10/axialis-software-ribbon-toolbar-stock.html&amp;amp;title=Axialis Software Ribbon &amp;amp; Toolbar Stock Icons - Basic Set Offer" target="_blank"&gt;&lt;img border="0" src="http://blogs.msdn.com/blogfiles/rahulso/WindowsLiveWriter/IconsfordifferentSocialBookmarkingSites_B387/CropperCapture154.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;          &lt;td&gt;&lt;a title="Post it to Facebook" href="http://www.facebook.com/sharer.php?u=http://csharpbits.notaclue.net/2011/10/axialis-software-ribbon-toolbar-stock.html&amp;amp;t=Axialis Software Ribbon &amp;amp; Toolbar Stock Icons - Basic Set Offer" target="_blank"&gt;&lt;img border="0" src="http://blogs.technet.com/photos/james/images/1765319/original.aspx" /&gt;&lt;/a&gt;&lt;/td&gt;          &lt;td&gt;&lt;a title="Post it to live" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;mkt=en-us&amp;amp;url=http://csharpbits.notaclue.net/2011/10/axialis-software-ribbon-toolbar-stock.html&amp;amp;title=Axialis Software Ribbon &amp;amp; Toolbar Stock Icons - Basic Set Offer" target="_blank"&gt;&lt;img border="0" src="http://blogs.msdn.com/blogfiles/rahulso/WindowsLiveWriter/IconsfordifferentSocialBookmarkingSites_B387/live4.png" /&gt;&lt;/a&gt;&lt;/td&gt;          &lt;td&gt;&lt;a title="Post it to reddit!" href="http://reddit.com/submit?url=http://csharpbits.notaclue.net/2011/10/axialis-software-ribbon-toolbar-stock.html&amp;amp;title=Axialis Software Ribbon &amp;amp; Toolbar Stock Icons - Basic Set Offer" target="_blank"&gt;&lt;img border="0" src="http://blogs.msdn.com/blogfiles/rahulso/WindowsLiveWriter/IconsfordifferentSocialBookmarkingSites_B387/reddit4.png" /&gt;&lt;/a&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/span&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-6925223093742230174?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CmOVDbQBLVMGiBM_f2Go-fa2NWU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CmOVDbQBLVMGiBM_f2Go-fa2NWU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CmOVDbQBLVMGiBM_f2Go-fa2NWU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CmOVDbQBLVMGiBM_f2Go-fa2NWU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/5C75Us77ICE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/6925223093742230174/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=6925223093742230174&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6925223093742230174?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6925223093742230174?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/5C75Us77ICE/axialis-software-ribbon-toolbar-stock.html" title="Axialis Software Ribbon &amp;amp; Toolbar Stock Icons - Basic Set Offer" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/10/axialis-software-ribbon-toolbar-stock.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UGQno_eSp7ImA9WhdRGEw.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-6719145916617017390</id><published>2011-08-08T14:47:00.001+01:00</published><updated>2011-08-08T14:47:03.441+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-08T14:47:03.441+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="LightSwitch" /><title>Visual Studio LightSwitch 2011 Arrives (Yes, I know it arrived a while ago!)</title><content type="html">&lt;p&gt;Well I have finally had the time to indulge in &lt;a href="http://www.microsoft.com/visualstudio/en-us/lightswitch/try" target="_blank"&gt;Visual Studio LightSwitch 2011 RTM&lt;/a&gt; (henceforth &lt;strong&gt;LS&lt;/strong&gt;), and it brings to Silverlight development what Dynamic Data (henceforth &lt;strong&gt;DD&lt;/strong&gt;) brought to Web Forms &lt;a href="http://www.urbandictionary.com/define.php?term=with+bells+on"&gt;with bells on&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;It’s faster to develop an app with &lt;strong&gt;LS&lt;/strong&gt; than it is with &lt;strong&gt;DD&lt;/strong&gt; and that’s a fact. I decided to develop an app that I had need to run my little company but had been putting off for the last two years for lack of time. You know how a builder always has work to do on his own home never completed, well no more with &lt;strong&gt;LS&lt;/strong&gt; I built it in just over one day see &lt;strong&gt;Figure 1&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-U_CCDGX4vTo/Tj_o1Mu-nFI/AAAAAAAABAE/DUaIulwVvLc/s1600-h/OneDayApp%25255B6%25255D.png" target="_blank"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="My App in one day" border="0" alt="My App in one day" src="http://lh4.ggpht.com/-H5KWfI71zTw/Tj_o1o5qYmI/AAAAAAAABAI/YXlhP-nRZuM/OneDayApp_thumb%25255B4%25255D.png?imgmax=800" width="640" height="397" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 1 – My App in one day&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All I have to add is the Invoice report which I am going to use &lt;a href="http://www.devexpress.com" target="_blank"&gt;DevExpress&lt;/a&gt; – &lt;a href="http://www.devexpress.com/Products/NET/Controls/LightSwitch/" target="_blank"&gt;XtraReports for Light Switch&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And the good news is that most of the Silverlight control venders are jumping in there with everything from &lt;em&gt;How to add our controls&lt;/em&gt; to custom installs for &lt;strong&gt;LS&lt;/strong&gt;;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.devexpress.com" target="_blank"&gt;DevExpress&lt;/a&gt; - &lt;a href="http://www.microsoft.com/visualstudio/en-us/lightswitch/extensions/devexpress" target="_blank"&gt;Learn more about the DevExpress extensions&lt;/a&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;See the XraReports for LightSwitch in action with this video &lt;a title="http://tv.devexpress.com/#XtraReportsGettingStartedLightSwitch;XtraReports+for+LightSwitch.product;1" href="http://tv.devexpress.com/#XtraReportsGettingStartedLightSwitch;XtraReports+for+LightSwitch.product;1" target="_blank"&gt;Getting Started with XtraReports for LightSwitch&lt;/a&gt; from &lt;a href="http://community.devexpress.com/blogs/seth/default.aspx" target="_blank"&gt;Seth Juarez&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;&lt;a href="http://www.microsoft.com/visualstudio/en-us/lightswitch/extension-videos/devexpress-drilldown" target="_blank"&gt;Video: DevExpress Visual Studio LightSwitch Extensions&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;a href="http://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=VisualStudioVersion&amp;amp;f%5B0%5D.Value=VSLS&amp;amp;f%5B0%5D.Text=Visual%20Studio%20LightSwitch&amp;amp;f%5B1%5D.Type=User&amp;amp;f%5B1%5D.Value=ComponentOne&amp;amp;f%5B1%5D.Text=ComponentOne" target="_blank"&gt;ComponentOne&lt;/a&gt; - &lt;a href="http://www.microsoft.com/visualstudio/en-us/lightswitch/extensions/componentone" target="_blank"&gt;Learn more about the ComponentOne extension&lt;/a&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://demo.componentone.com/LightSwitch/OLAP/?productID=309&amp;amp;utm_source=LandingPage&amp;amp;utm_medium=landing&amp;amp;utm_term=OLAPLightSwitchDemo&amp;amp;utm_campaign=OlapLandingJuly2011" target="_blank"&gt;Live sample&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;a href="http://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=VisualStudioVersion&amp;amp;f%5B0%5D.Value=VSLS&amp;amp;f%5B0%5D.Text=Visual%20Studio%20LightSwitch&amp;amp;f%5B1%5D.Type=User&amp;amp;f%5B1%5D.Value=Infragistics&amp;amp;f%5B1%5D.Text=Infragistics" target="_blank"&gt;Infragistics&lt;/a&gt; - &lt;a href="http://www.microsoft.com/visualstudio/en-us/lightswitch/extensions/infragistics"&gt;Learn more about the Infragistics extension&lt;/a&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://www.microsoft.com/visualstudio/en-us/lightswitch/extension-videos/infragistics-drilldown" target="_blank"&gt;Video: Infragistics Visual Studio LightSwitch Extensions&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;a href="http://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=VisualStudioVersion&amp;amp;f%5B0%5D.Value=VSLS&amp;amp;f%5B0%5D.Text=Visual%20Studio%20LightSwitch&amp;amp;f%5B1%5D.Type=Tag&amp;amp;f%5B1%5D.Value=LightSwitch%20Data%20Source&amp;amp;f%5B2%5D.Type=User&amp;amp;f%5B2%5D.Value=RSSBus&amp;amp;f%5B2%5D.Text=RSSBus" target="_blank"&gt;RSSBus&lt;/a&gt; - &lt;a href="http://www.microsoft.com/visualstudio/en-us/lightswitch/extensions/rssbus"&gt;Learn more about the RSSBus extensions&lt;/a&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;!--EndFragment--&gt;&lt;a href="http://www.microsoft.com/visualstudio/en-us/lightswitch/extension-videos/rssbus-drilldown" target="_blank"&gt;Video: RSSBus Visual Studio LightSwitch Extensions&lt;/a&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;a href="http://www.telerik.com" target="_blank"&gt;Telerik&lt;/a&gt; - &lt;a href="http://www.telerik.com/products/lightswitch-support.aspx?utm_source=twitter&amp;amp;utm_medium=sm&amp;amp;utm_campaign=lightswitch-launch" target="_blank"&gt;Extend Visual Studio LightSwitch with Telerik Dev Tools&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;And there are tones of starter kits on &lt;a href="http://go.microsoft.com/?linkid=9778472"&gt;Visual Studio Gallery&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;The forums are very active;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/lightswitch/threads" target="_blank"&gt;Visual Studio LightSwitch - General Questions&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/lsextensibility/threads" target="_blank"&gt;Visual Studio LightSwitch Extensibility&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Blogs I’ve found so far;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/lightswitch" target="_blank"&gt;Visual Studio LightSwitch Team Blog&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/bethmassi/" target="_blank"&gt;Sharing the goodness that is VB&lt;/a&gt; - Beth Massi&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/mthalman/" target="_blank"&gt;From The Depths&lt;/a&gt; - Matt Thalman&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.devexpress.com/blogs/seth/default.aspx" target="_blank"&gt;DevExpress Reporting Blog&lt;/a&gt; - Seth Juarez&lt;/li&gt;    &lt;li&gt;&lt;a href="http://dotnettim.wordpress.com/" target="_blank"&gt;Tim Leung's Blog&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I don’t expect this is an exhaustive list but it’s very encouraging and I will be joining the band waggon and build some of my own extensions and of course blog about it here.&lt;/p&gt;  &lt;p&gt;P.S. I have not left &lt;strong&gt;DD&lt;/strong&gt; this is just some new fun that will certainly compliment &lt;strong&gt;DD&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;P.P.S. I still have loads of stuff to put on &lt;a href="http://nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt; so keep an eye on me here.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-6719145916617017390?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Xqe5Q-y0kppt2xKDeHbQhP-Jgc0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Xqe5Q-y0kppt2xKDeHbQhP-Jgc0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Xqe5Q-y0kppt2xKDeHbQhP-Jgc0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Xqe5Q-y0kppt2xKDeHbQhP-Jgc0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/a5e13j-iKVo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/6719145916617017390/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=6719145916617017390&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6719145916617017390?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6719145916617017390?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/a5e13j-iKVo/visual-studio-lightswitch-2011-arrives.html" title="Visual Studio LightSwitch 2011 Arrives (Yes, I know it arrived a while ago!)" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-H5KWfI71zTw/Tj_o1o5qYmI/AAAAAAAABAI/YXlhP-nRZuM/s72-c/OneDayApp_thumb%25255B4%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/08/visual-studio-lightswitch-2011-arrives.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4GR3s7cCp7ImA9WhdTFUQ.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-4391504803162160081</id><published>2011-07-13T23:38:00.001+01:00</published><updated>2011-07-13T23:58:46.508+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-13T23:58:46.508+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="NuGet" /><category scheme="http://www.blogger.com/atom/ns#" term="FieldTemplate" /><category scheme="http://www.blogger.com/atom/ns#" term="Image Handler" /><title>Dynamic Data Image Field Template Updated</title><content type="html">&lt;p&gt;I’ve update the Database Embedded Image sample on &lt;a href="http://nuget.org" target="_blank"&gt;NuGet&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;table border="0" cellspacing="0" cellpadding="2" width="628"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td width="1%"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Dynamic Data Database Embedded Image Field Template " border="0" alt="Dynamic Data Database Embedded Image Field Template " src="http://lh5.ggpht.com/-410tWEg-C04/Th4f1LeKZCI/AAAAAAAAA_4/91j1EbAjpMg/DatabaseEmbededImage100x100a.png?imgmax=800" width="100" height="100" /&gt;&lt;/td&gt;          &lt;td width="99%"&gt;&amp;#160;&lt;a href="http://nuget.org/List/Packages/DynamicData.ImageFieldTemplate"&gt;Dynamic Data Database Embedded Image Field Template&lt;/a&gt; &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td width="1%"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Dynamic Data Image Handler" border="0" alt="Dynamic Data Image Handler" src="http://lh5.ggpht.com/-DGthqk2VEY0/Th4eT-V3xyI/AAAAAAAAA_8/kcHIV7RtAa4/ImageHandler100x100%25255B1%25255D.png?imgmax=800" width="100" height="100" /&gt;&lt;/td&gt;          &lt;td width="99%"&gt;&amp;#160;&lt;a href="http://nuget.org/List/Packages/Microsoft.Web.DynamicData.Handlers"&gt;Dynamic Data Image Handler&lt;/a&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;instead of depending on a &lt;a href="http://nuget.org/List/Packages/NotAClue.Web.Helpers"&gt;NotAClue.Web.Helpers&lt;/a&gt; it now depends on:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="629"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="1%"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="NotAClue Dynamic Data Extensions " border="0" alt="NotAClue Dynamic Data Extensions " src="http://lh3.ggpht.com/--Cx9ROgQ2OE/Th4f2Dugj0I/AAAAAAAABAA/e1VwYiXuni8/DynamicDataExtensions100x100%25255B5%25255D.png?imgmax=800" width="100" height="100" /&gt;&lt;/td&gt;        &lt;td width="99%"&gt;&amp;#160;&lt;a href="http://nuget.org/List/Packages/NotAClue.DynamicData.Extensions"&gt;NotAClue Dynamic Data Extensions&lt;/a&gt; &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;All future samples will build on this main library.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-4391504803162160081?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8xzqpQ3cXwFCC4sHdUkmrlf_Wa8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8xzqpQ3cXwFCC4sHdUkmrlf_Wa8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8xzqpQ3cXwFCC4sHdUkmrlf_Wa8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8xzqpQ3cXwFCC4sHdUkmrlf_Wa8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/83sXZ0-KcDQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/4391504803162160081/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=4391504803162160081&amp;isPopup=true" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/4391504803162160081?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/4391504803162160081?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/83sXZ0-KcDQ/dynamic-data-image-field-template.html" title="Dynamic Data Image Field Template Updated" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-410tWEg-C04/Th4f1LeKZCI/AAAAAAAAA_4/91j1EbAjpMg/s72-c/DatabaseEmbededImage100x100a.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/07/dynamic-data-image-field-template.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcDSX08fSp7ImA9WhZaF0o.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-409909221399298636</id><published>2011-07-04T00:26:00.001+01:00</published><updated>2011-07-04T10:01:18.375+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-04T10:01:18.375+01:00</app:edited><title>Custom Field Templates On NuGet</title><content type="html">&lt;p&gt;In this article I am going to build some custom field templates;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;File Upload field template &lt;/li&gt;    &lt;li&gt;Image Upload field template &lt;/li&gt;    &lt;li&gt;Image Select field template &lt;/li&gt;    &lt;li&gt;Date picker field template &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="CustomFieldTemplates" border="0" alt="CustomFieldTemplates" src="http://lh5.ggpht.com/-fxr5NbafOTw/ThD6lIiIVYI/AAAAAAAAA_E/o_tGs8bT7iw/CustomFieldTemplates%25255B5%25255D.png?imgmax=800" width="437" height="529" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 1 – Our proposed field templates&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;So first of all we need specify what we want each to do.&lt;/p&gt;  &lt;h5&gt;File Upload Field Template Requirements&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Be able to upload and file type (PDF, ZIP, DOC, XLS etc.). &lt;/li&gt;    &lt;li&gt;Restrict types to be uploaded. &lt;/li&gt;    &lt;li&gt;access uploaded file via hyperlink (enable or disable this). &lt;/li&gt;    &lt;li&gt;Store in folder in site. &lt;/li&gt;    &lt;li&gt;Replace old file if new file replaces it during edit (you would need to maintain deleting items using some business logic as the field template is not called during the deletion process). &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Image Upload Field Template Requirements&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Be able to upload and image type (jpeg, gif, png, etc.). &lt;/li&gt;    &lt;li&gt;Restrict which image types can be uploaded (i.e. restricts to jpeg or png etc.). &lt;/li&gt;    &lt;li&gt;Store in folder in site. &lt;/li&gt;    &lt;li&gt;Replace old file if new file replaces it during edit (you would need to maintain deleting items using some business logic as the field template is not called during the deletion process).&lt;!--EndFragment--&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Image Select Field Template Requirements&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Choose from a set of images . &lt;/li&gt;    &lt;li&gt;Use images a folder in site. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Ajax Date picker&lt;/h5&gt;  &lt;ul&gt;   &lt;li&gt;Select a date using a popup date picker from the Ajax Control toolkit. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;At another time we will do one based on the jQuery UI date picker.&lt;/p&gt;  &lt;h5&gt;Building the Field Templates&lt;/h5&gt;  &lt;p&gt;We could just pass the information we want using the UIHint attribute and it’s control parameters collection but there is no design time intellisense, so we will build an attribute that all three field template can use. We will call it the Upload attribute it will need to store the following information;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Folder to store images &lt;/li&gt;    &lt;li&gt;Folder to store file icons &lt;/li&gt;    &lt;li&gt;Size to display Icon or Image (Height and Width) &lt;/li&gt;    &lt;li&gt;Whether to display an hyperlink or not. &lt;/li&gt;    &lt;li&gt;Acceptable file type for image and file upload. &lt;/li&gt;    &lt;li&gt;Image extension for icons. &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;The Upload Attribute&lt;/h5&gt;  &lt;pre class="brush: csharp;"&gt;/// &amp;lt;summary&amp;gt;
/// Upload attribute defines values for the upload
/// field templates
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class UploadAttribute : Attribute
{
    #region Properties
    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the height to display the image, 
    /// if only one of the two dimensions are specified
    /// then the aspect ration will be retained.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The height.&amp;lt;/value&amp;gt;
    /// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    public int Height { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the width to display the image, 
    /// if only one of the two dimensions are specified
    /// then the aspect ration will be retained.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The width.&amp;lt;/value&amp;gt;
    /// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    public int Width { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the uploads folder.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The uploads folder.&amp;lt;/value&amp;gt;
    /// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    public String UploadFolder { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the icons folder.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The icons folder.&amp;lt;/value&amp;gt;
    /// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    public String ImagesFolder { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets a value indicating whether [show hyperlink].
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;&amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if [show hyperlink]; otherwise, &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.&amp;lt;/value&amp;gt;
    /// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    public Boolean ShowHyperlink { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the file types.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The file types.&amp;lt;/value&amp;gt;
    /// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    public String[] FileTypes { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the image extension.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The image extension.&amp;lt;/value&amp;gt;
    /// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    public String ImageExtension { get; set; }
    #endregion

    /// &amp;lt;summary&amp;gt;
    /// Initializes a new instance of the &amp;lt;see cref=&amp;quot;T:System.Attribute&amp;quot;/&amp;gt; class
    /// setting the Height to 50 and the folder to &amp;quot;~/images&amp;quot;.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;remarks&amp;gt;&amp;lt;/remarks&amp;gt;
    public UploadAttribute()
    {
        // set a default value of 50 and constrain aspect ratio.
        Height = 50;
        // set default images folder
        UploadFolder = &amp;quot;~/images&amp;quot;;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – Upload Attribute&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The attribute in &lt;strong&gt;Listing 1&lt;/strong&gt; handles all the properties we want so we can build each of the field templates.&lt;/p&gt;

&lt;h5&gt;Upload File Field Template&lt;/h5&gt;

&lt;p&gt;To start off expand the DynamicData folder to see the FieldTemplate folder and right click and choose &lt;strong&gt;Add-&amp;gt;New Item…&lt;/strong&gt; you can now choose “Dynamic Data Field” (this will create a new field template pretty much the same as the Text field template) enter the name “UploadFile” and you will see your new blank field template.&lt;/p&gt;

&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Dynamic Data Field" border="0" alt="Dynamic Data Field" src="http://lh3.ggpht.com/-k4rz6dzUN2Y/ThD6l2PrS6I/AAAAAAAAA_I/_G5gBiuf9SA/Dynamic%252520Data%252520Field%25255B7%25255D.png?imgmax=800" width="484" height="91" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2 – Dynamic Data Field&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have decided that I want nothing to show apart form the File Upload control until there is a file uploaded&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="200"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WithoutData" border="0" alt="WithoutData" src="http://lh6.ggpht.com/-7prXOx4PWgw/ThD6mEy9vjI/AAAAAAAAA_M/kpB1whsutS0/WithoutData%25255B5%25255D.png?imgmax=800" width="285" height="75" /&gt;&lt;/td&gt;

      &lt;td valign="top" width="200"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WithData" border="0" alt="WithData" src="http://lh6.ggpht.com/-1Vf6HH0VsEY/ThD6nA3lw1I/AAAAAAAAA_Q/baMwWCU00hU/WithData%25255B5%25255D.png?imgmax=800" width="285" height="85" /&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="200"&gt;&lt;strong&gt;Figure 3 – Insert mode&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="200"&gt;&lt;strong&gt;Figure 4 – Edit mode&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;h5&gt;&lt;font style="font-weight: normal"&gt;In &lt;strong&gt;Figures 2 &amp;amp; 3&lt;/strong&gt; we can see both modes we only see an image and link/text when data is already present. So I have put the mark-up for this in a place holder.&lt;/font&gt;&lt;/h5&gt;

&lt;pre class="brush: csharp;"&gt;&amp;lt;asp:PlaceHolder 
    ID=&amp;quot;PlaceHolder1&amp;quot; 
    runat=&amp;quot;server&amp;quot; 
    Visible=&amp;quot;false&amp;quot;&amp;gt;
    &amp;lt;asp:Image ID=&amp;quot;Image1&amp;quot; runat=&amp;quot;server&amp;quot; /&amp;gt;&amp;amp;nbsp;
    &amp;lt;asp:Label ID=&amp;quot;Label1&amp;quot; runat=&amp;quot;server&amp;quot; Text=&amp;quot;&amp;lt;%# FieldValueString %&amp;gt;&amp;quot; /&amp;gt;
    &amp;lt;asp:HyperLink ID=&amp;quot;HyperLink1&amp;quot; runat=&amp;quot;server&amp;quot;&amp;gt;&amp;lt;%# FieldValueString %&amp;gt;&amp;lt;/asp:HyperLink&amp;gt;
&amp;lt;/asp:PlaceHolder&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;asp:FileUpload 
    ID=&amp;quot;FileUpload1&amp;quot; 
    runat=&amp;quot;server&amp;quot; 
    CssClass=&amp;quot;DDTextBox&amp;quot; 
    Width=&amp;quot;150px&amp;quot;/&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 2 – Upload File field template mark-up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next we remove the current validators and replace with a custom validator.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;&amp;lt;asp:CustomValidator 
    ID=&amp;quot;CustomValidator1&amp;quot; 
    runat=&amp;quot;server&amp;quot; 
    ControlToValidate=&amp;quot;FileUpload1&amp;quot; 
    onservervalidate=&amp;quot;CustomValidator1_ServerValidate&amp;quot;&amp;gt;
&amp;lt;/asp:CustomValidator&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 4 – Custom validator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the code behind we need to setup the validator and the fileupload&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;protected void Page_Load(object sender, EventArgs e)
{
    CustomValidator1.Text = &amp;quot;*&amp;quot;;
    SetUpValidator(CustomValidator1);

    // get attributes
    uploadAttribute = MetadataAttributes.GetAttribute&amp;lt;UploadAttribute&amp;gt;();
    if (uploadAttribute == null)
    {
        // no attribute thrw an error
        throw new InvalidOperationException(&amp;quot;FileUpload must have valid uploadAttribute applied&amp;quot;);
    }
    else
    {
        // add tooltip describing what file types can be uploaded.
        FileUpload1.ToolTip = String.Format(&amp;quot;Upload {0} files&amp;quot;, uploadAttribute.FileTypes.ToCsvString());
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 5 – Page_Load&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here we setup the custom validator and get the Upload attribute, if the attribute is missing we throw an InvalidOperationException and if the attribute is there we set the FileUpload’s tooltip to a helpful message.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)
{
    if (FileUpload1.HasFile)
    {
        // get files name
        var fileName = FileUpload1.FileName;

        // get files extension without the dot
        String fileExtension = FileUpload1.GetFileExtension();

        // check file has an allowed file extension
        if (!uploadAttribute.FileTypes.Contains(fileExtension))
        {
            args.IsValid = false;
            CustomValidator1.ErrorMessage = String.Format(&amp;quot;{0} is not a valid upload file type (only {1} are supported).&amp;quot;,
                FileUpload1.FileName, 
                uploadAttribute.FileTypes.ToCsvString());
        }
    }
    else if (Column.IsRequired &amp;amp;&amp;amp; String.IsNullOrEmpty(Label1.Text))
    {
        args.IsValid = false;
        CustomValidator1.ErrorMessage = Column.RequiredErrorMessage;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 6 – CustomValidator1_ServerValidate method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Listing 6&lt;/strong&gt; is the Custom validator method here all we are concerned with is making sure we have a valid file to upload, so we check the file type via its file extension and if it matched one from out Upload attribute the file can be uploaded but if not we invalidate the page and add a custom error to our Custom validator. Also if the field is a required field then we check to see if there is a file present either from an edit or from the FileUpload control.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;protected override void OnDataBinding(EventArgs e)
{
    base.OnDataBinding(e);

    //check if field has a value
    if (FieldValue == null)
        return;

    // when there is already a value in the FieldValue
    // then show the icon and label/hyperlink
    PlaceHolder1.Visible = true;

    // get the file extension
    String extension = FieldValueString.GetFileExtension();

    if (uploadAttribute.ShowHyperlink)
    {
        Label1.Visible = false;
        // open in new window
        HyperLink1.Target = &amp;quot;_blank&amp;quot;;
        HyperLink1.Text = FieldValueString.GetFileNameTitle();
        HyperLink1.NavigateUrl = VirtualPathUtility.AppendTrailingSlash(uploadAttribute.UploadFolder) + FieldValueString;
    }
    else
    {
        HyperLink1.Visible = false;
        Label1.Text = FieldValueString;
    }

    // show the icon
    if (!String.IsNullOrEmpty(extension))
    {
        // set the file type image
        if (!String.IsNullOrEmpty(uploadAttribute.ImagesFolder))
        {
            // get file type image from folder specified in
            Image1.ImageUrl = String.Format(&amp;quot;{0}{1}.{2}&amp;quot;,
                VirtualPathUtility.AppendTrailingSlash(uploadAttribute.ImagesFolder),
                extension,
                uploadAttribute.ImageExtension);
        }

        Image1.AlternateText = extension + &amp;quot; file&amp;quot;;

        // set width
        if (uploadAttribute.Width &amp;gt; 0)
            Image1.Width = uploadAttribute.Width;

        // set height
        if (uploadAttribute.Height &amp;gt; 0)
            Image1.Height = uploadAttribute.Height;
    }
    else
    {
        // if file has no extension then hide image
        Image1.Visible = false;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 7 – OnDataBinding event&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the OnDataBinding event &lt;strong&gt;Listing 7&lt;/strong&gt; we first of all check to see if the FieldValue is null if it is we just return. If it’s not null then we show the place holder. New we have to determine if we are showing an Hyperlink or a Label for the name of the file. And lastly we check to see if we can show a icon to represent the uploaded file type. &lt;/p&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;The OnDataBinding event is the only place where we have access to the FieldValue in the field template code behind.&lt;/div&gt;



&lt;pre class="brush: csharp;"&gt;protected override void ExtractValues(IOrderedDictionary dictionary)
{
    // make sure file is valid
    if (FileUpload1.HasFile &amp;amp;&amp;amp; Page.IsValid)
    {
        // make sure we have the folder to upload the file to
        var uploadFolder = Server.MapPath(VirtualPathUtility.AppendTrailingSlash(uploadAttribute.UploadFolder));
        if(!Directory.Exists(uploadFolder))
            Directory.CreateDirectory(uploadFolder);

        // upload the file
        FileUpload1.SaveAs(uploadFolder + FileUpload1.FileName);

        // update the field with the filename
        dictionary[Column.Name] = ConvertEditedValue(FileUpload1.FileName);
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 8 – ExtractValues method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We make sure we have a file to upload and the there was no error from the custom validator, check that the upload folder exists and create it if not. We then save the file to the upload folder and update the data field.&lt;/p&gt;

&lt;h5&gt;Upload Image Field Template&lt;/h5&gt;

&lt;pre class="brush: csharp;"&gt;// show the uploaded image
Image1.ImageUrl = String.Format(&amp;quot;{0}{1}&amp;quot;, 
    VirtualPathUtility.AppendTrailingSlash(uploadAttribute.UploadFolder), 
    FieldValueString);

// add alternate text
Image1.AlternateText = FieldValueString.GetFileNameTitle();&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 9 – OnDataBinding event&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There only a few minor differences between UploadImage and UploadFile and they are in the section that displays the icon, in the UploadImage instead of displaying an Icon representing the file type we display the actual image.&lt;/p&gt;

&lt;h5&gt;Select Image Field Template&lt;/h5&gt;

&lt;p&gt;Here we are using a RadioButtonList and most of the work is done in the Page_Load &lt;strong&gt;Listing 10&lt;/strong&gt; &lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;protected void Page_Load(object sender, EventArgs e)
{
    // get attributes
    var uploadAttribute = MetadataAttributes.GetAttribute&amp;lt;UploadAttribute&amp;gt;();
    if (uploadAttribute == null)
        throw new InvalidOperationException(&amp;quot;FileUpload must have valid uploadAttribute applied&amp;quot;);

    SetUpValidator(RequiredFieldValidator1);
    SetUpValidator(DynamicValidator1);

    // if no images folder return
    var dirInfo = new DirectoryInfo(Server.MapPath(uploadAttribute.ImagesFolder));
    if (!dirInfo.Exists)
    {
        RadioButtonList1.Visible = false;
        return;
    }

    if (RadioButtonList1.Items.Count == 0)
    {
        // get a list of images in the ImageUrlAttribute folder
        var imagesFolder = ResolveUrl(uploadAttribute.ImagesFolder);
        var files = dirInfo.GetFiles(String.Format(&amp;quot;*.{0}&amp;quot;, uploadAttribute.ImageExtension));

        foreach (FileInfo file in files)
        {
            // size image to uploadAttribute
            var imgString = new StringBuilder();

            imgString.Append(
                String.Format(&amp;quot;&amp;lt;img src='{0}' alt='{1}' &amp;quot;,
                    imagesFolder + file.Name,
                    file.Name.GetFileNameTitle()
               ));

            if (uploadAttribute.Width &amp;gt; 0)
                imgString.Append(String.Format(&amp;quot;width='{0}' &amp;quot;, uploadAttribute.Width));

            if (uploadAttribute.Height &amp;gt; 0)
                imgString.Append(String.Format(&amp;quot;height='{0}' &amp;quot;, uploadAttribute.Height));

            imgString.Append(&amp;quot; /&amp;gt;&amp;quot;);

            // embed image in the radio button
            var listItem = new ListItem(imgString.ToString(), file.Name);
            listItem.Attributes.Add(&amp;quot;title&amp;quot;, file.Name.GetFileNameTitle());

            this.RadioButtonList1.Items.Add(listItem);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 10 – Page_Load&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here we get a list of file filtered by the file extension supplied by the Upload attribute the we populate the RadioButtonList with this list. it get a little clever as we add some html mark-up into the Text value of each ListItem added to the RadioButtonList showing the Image to choice.&lt;/p&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;Setting the images folder up you will need to place your selection of images for the user to choose from into the folder and name them appropriately as the file name will be used for the tool tip and be stored in the DB as the value for the selection. &lt;/div&gt;

&lt;h5&gt;Date Picker&amp;#160; Field Template&lt;/h5&gt;

&lt;p&gt;All I have done here is add an Ajax Control Toolkit CalendarExtender to the page and set it up.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;&amp;lt;asp:TextBox 
    ID=&amp;quot;TextBox1&amp;quot; 
    runat=&amp;quot;server&amp;quot; 
    CssClass=&amp;quot;DDTextBox&amp;quot; 
    Text=&amp;quot;&amp;lt;%# FieldValueEditString %&amp;gt;&amp;quot; 
    Columns=&amp;quot;20&amp;quot;&amp;gt;
&amp;lt;/asp:TextBox&amp;gt;
&amp;lt;ajaxToolkit:CalendarExtender 
    ID=&amp;quot;TextBox1_CalendarExtender&amp;quot; 
    runat=&amp;quot;server&amp;quot; 
    Enabled=&amp;quot;True&amp;quot;
    TargetControlID=&amp;quot;TextBox1&amp;quot;&amp;gt;
&amp;lt;/ajaxToolkit:CalendarExtender&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 11 – Date with Calendar Extender&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;private readonly static String DATE_FORMAT = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern

protected void Page_Load(object sender, EventArgs e)
{
    TextBox1_CalendarExtender.Format = DATE_FORMAT;
    TextBox1.ToolTip = Column.Description;

    SetUpValidator(RequiredFieldValidator1);
    SetUpValidator(RegularExpressionValidator1);
    SetUpValidator(DynamicValidator1);
    SetUpCustomValidator(DateValidator);
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listign 12 – Page_Load&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All I’ve had to do is make sure the CalendarExtender matches the localised date time format, we now get a nice data picker.&lt;/p&gt;

&lt;h5&gt;Sample Metadata&lt;/h5&gt;

&lt;pre class="brush: csharp;"&gt;[MetadataTypeAttribute(typeof(File.FileMetadata))]
public partial class File
{
    internal sealed class FileMetadata
    {
        public int ID { get; set; }
        public string Description { get; set; }

        [Upload(
            FileTypes = new String[] { &amp;quot;doc&amp;quot;, &amp;quot;xls&amp;quot; },
            UploadFolder = &amp;quot;~/FileUploads/&amp;quot;,
            ImagesFolder = &amp;quot;~/images/&amp;quot;,
            ShowHyperlink = true,
            ImageExtension = &amp;quot;png&amp;quot;,
            Height = 30)]
        [UIHint(&amp;quot;UploadFile&amp;quot;)]
        public string FileName { get; set; }

        [Upload(
            FileTypes = new String[] { &amp;quot;png&amp;quot;, &amp;quot;jpg&amp;quot;, &amp;quot;jpeg&amp;quot; },
            UploadFolder = &amp;quot;~/ImageUploads/&amp;quot;,
            ShowHyperlink = true,
            ImageExtension = &amp;quot;png&amp;quot;,
            Height = 30)]
        [UIHint(&amp;quot;UploadImage&amp;quot;)]
        public string ImageName { get; set; }

        [Upload(
            ImagesFolder = &amp;quot;~/ImageSelection/&amp;quot;,
            ImageExtension = &amp;quot;png&amp;quot;,
            Height = 30)]
        [UIHint(&amp;quot;SelectImage&amp;quot;)]
        public string Selection { get; set; }

        [DataType(DataType.Date)]
        public DateTime DateCreated { get; set; }

    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 13 – sample metadata&lt;/strong&gt;&lt;/p&gt;

&lt;h5&gt;Download NuGet Package&lt;/h5&gt;

&lt;p&gt;&lt;a href="http://nuget.org/List/Packages/NotAClue.DynamicData.CustomFieldTemplates" target="_blank"&gt;Dynamic Data Custom Field Templates - 1.0&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-409909221399298636?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gzy9iP_1sOGFNRBnu_DklE86Z3E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gzy9iP_1sOGFNRBnu_DklE86Z3E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gzy9iP_1sOGFNRBnu_DklE86Z3E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gzy9iP_1sOGFNRBnu_DklE86Z3E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/IueOYgH6JNg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/409909221399298636/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=409909221399298636&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/409909221399298636?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/409909221399298636?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/IueOYgH6JNg/custom-field-templates-on-nuget.html" title="Custom Field Templates On NuGet" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-fxr5NbafOTw/ThD6lIiIVYI/AAAAAAAAA_E/o_tGs8bT7iw/s72-c/CustomFieldTemplates%25255B5%25255D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/07/custom-field-templates-on-nuget.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMMRXY4eCp7ImA9WhZaEko.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-7974112223867322289</id><published>2011-06-28T16:21:00.001+01:00</published><updated>2011-06-28T16:21:24.830+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-28T16:21:24.830+01:00</app:edited><title>Autocomplete ForeignKey Field Template Now on NuGet</title><content type="html">&lt;p&gt;I have just added the ForeignKey field template based on the old Futures Autocomplete filter to &lt;a href="http://nuget.org" target="_blank"&gt;NuGet&lt;/a&gt; at &lt;a title="http://nuget.org/List/Packages/NotAClue.DynamicData.AutocompleteForeignKey" href="http://nuget.org/List/Packages/NotAClue.DynamicData.AutocompleteForeignKey"&gt;NotAClue.DynamicData.AutocompleteForeignKey&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="NotAClue.DynamicData.AutocompleteForeignKeySample" border="0" alt="NotAClue.DynamicData.AutocompleteForeignKeySample" src="http://lh5.ggpht.com/-EFgoosoTQbo/TgnxdPSjWfI/AAAAAAAAA_A/t0aGGWpQQDg/NotAClue.DynamicData.AutocompleteForeignKeySample%25255B5%25255D.png?imgmax=800" width="305" height="116" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Autocomplete in action&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All you need is to add a UIHint attribute to the to set the field template, &lt;/p&gt;  &lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;only works on Foreign Key columns&lt;/div&gt;    &lt;p&gt;you can als0 set the number of characters you need to type before autocomplete kicks in.&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;[UIHint(&amp;quot;Autocomplete&amp;quot;, null, &amp;quot;MinimumPrefixLength&amp;quot;,2)]
public Supplier Supplier { get; set; }&lt;/pre&gt;

&lt;p&gt;By setting the MinimumPrefixLength in the UIHint’s ControlParameters.
  &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-7974112223867322289?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EBzlMaSP4ZQ1Ajz4ayKKf-DlgxE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EBzlMaSP4ZQ1Ajz4ayKKf-DlgxE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EBzlMaSP4ZQ1Ajz4ayKKf-DlgxE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EBzlMaSP4ZQ1Ajz4ayKKf-DlgxE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/5FN96oxLPUE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/7974112223867322289/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=7974112223867322289&amp;isPopup=true" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7974112223867322289?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7974112223867322289?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/5FN96oxLPUE/autocomplete-foreignkey-field-template.html" title="Autocomplete ForeignKey Field Template Now on NuGet" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-EFgoosoTQbo/TgnxdPSjWfI/AAAAAAAAA_A/t0aGGWpQQDg/s72-c/NotAClue.DynamicData.AutocompleteForeignKeySample%25255B5%25255D.png?imgmax=800" height="72" width="72" /><thr:total>11</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/06/autocomplete-foreignkey-field-template.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYDRH06cSp7ImA9WhZaEU4.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-6708547348741029033</id><published>2011-06-27T02:13:00.001+01:00</published><updated>2011-06-27T02:29:35.319+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-27T02:29:35.319+01:00</app:edited><title>My Classic Cascading Filters and Field Templates on NuGet</title><content type="html">&lt;p&gt;I’ve just released my classic Cascading Filters and Field Templates on &lt;a href="http://nuget.org" target="_blank"&gt;NuGet&lt;/a&gt; for ease of install supports both Entity Framework and Linq to SQL.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-rljYP-Oyh7Q/TgfZPPfNgLI/AAAAAAAAA-4/ZJDDFI2UJrs/s1600-h/DynamicDataCascade100x100%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="DynamicDataCascade100x100" border="0" alt="DynamicDataCascade100x100" src="http://lh4.ggpht.com/-IP53h4yDkAw/TgfZPsci0pI/AAAAAAAAA-8/9jKpcE8LjS0/DynamicDataCascade100x100_thumb%25255B2%25255D.png?imgmax=800" width="100" height="87" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Dynamic Data Filters and Field Templates&lt;/strong&gt;&lt;/p&gt;  &lt;h5&gt;Sample Metadata&lt;/h5&gt;  &lt;pre class="brush: csharp;"&gt;[MetadataTypeAttribute(typeof(Vehicle.VehicleMetadata))]
public partial class Vehicle
{
    internal sealed class VehicleMetadata
    {
        public int Id { get; set; }
        public int ManufacturerId { get; set; }
        public int VehicleTypeId { get; set; }
        public int ModelId { get; set; }
        public int StyleId { get; set; }

        [Display(Order = 0)]
        public String Name { get; set; }

        /// &amp;lt;summary&amp;gt;
        /// Note for cascade to work correctly
        /// fields must be in cascade order Parent-&amp;gt;Child
        /// &amp;lt;/summary&amp;gt;
        [FilterUIHint(&amp;quot;CascadingForeignKey&amp;quot;)]
        [UIHint(&amp;quot;CascadingForeignKey&amp;quot;)]
        [Filter(Order = 0)]
        [Display(Order = 1)]
        public Manufacturer Manufacturer { get; set; }

        [FilterUIHint(&amp;quot;CascadingForeignKey&amp;quot;)]
        [UIHint(&amp;quot;CascadingForeignKey&amp;quot;)]
        [Cascade(&amp;quot;Manufacturer&amp;quot;)]
        [Filter(Order = 1)]
        [Display(Order = 2)]
        public VehicleType VehicleType { get; set; }

        [FilterUIHint(&amp;quot;CascadingForeignKey&amp;quot;)]
        [UIHint(&amp;quot;CascadingForeignKey&amp;quot;)]
        [Cascade(&amp;quot;VehicleType&amp;quot;)]
        [Filter(Order = 2)]
        [Display(Order = 3)]
        public Model Model { get; set; }

        [FilterUIHint(&amp;quot;CascadingForeignKey&amp;quot;)]
        [UIHint(&amp;quot;CascadingForeignKey&amp;quot;)]
        [Cascade(&amp;quot;Model&amp;quot;)]
        [Filter(Order = 3)]
        [Display(Order = 4)]
        public Style Style { get; set; }

    }
}&lt;/pre&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;For cascading to work each child must follow in order Parent-&amp;gt;Child note the Ordering of both filters and fields to facilitate the cascade. &lt;/div&gt;

&lt;p&gt;Next up are hierarchical cascade field templates&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-6708547348741029033?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tRtw0tTEwW6NrY17u392ML2A3Qc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tRtw0tTEwW6NrY17u392ML2A3Qc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tRtw0tTEwW6NrY17u392ML2A3Qc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tRtw0tTEwW6NrY17u392ML2A3Qc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/tMlKsRf6qSw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/6708547348741029033/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=6708547348741029033&amp;isPopup=true" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6708547348741029033?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6708547348741029033?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/tMlKsRf6qSw/my-classic-cascading-filters-and-filed.html" title="My Classic Cascading Filters and Field Templates on NuGet" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-IP53h4yDkAw/TgfZPsci0pI/AAAAAAAAA-8/9jKpcE8LjS0/s72-c/DynamicDataCascade100x100_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>8</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/06/my-classic-cascading-filters-and-filed.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIGSH49eSp7ImA9WhZbF0U.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-6427776880622752333</id><published>2011-06-23T01:05:00.001+01:00</published><updated>2011-06-23T01:05:29.061+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-23T01:05:29.061+01:00</app:edited><title>Links to Sample Down :(</title><content type="html">&lt;p&gt;It would appear that &lt;a href="http://live.com"&gt;Live.com&lt;/a&gt; have done some reorganisation of my SkyDrive for me &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-disappointedsmile" alt="Disappointed smile" src="http://lh6.ggpht.com/-RbZ3-H_MG_U/TgKDSPvPP-I/AAAAAAAAA-0/dPrWkwfknT0/wlEmoticon-disappointedsmile%25255B2%25255D.png?imgmax=800" /&gt; and now ALL the links to my samples are broken, you can see my public folder here &lt;a href="https://skydrive.live.com/?wa=wsignin1.0&amp;amp;cid=96845e7b0fac1eed#cid=96845E7B0FAC1EED&amp;amp;id=96845E7B0FAC1EED%21112" target="_blank"&gt;Public&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Sorry for this but it is out of my control.&lt;/p&gt;  &lt;p&gt;Anyway on a positive note I plan to have all my old samples update to .Net 4 and on &lt;a href="http://nuget.com" target="_blank"&gt;NuGet&lt;/a&gt; as we go forward, I will post a pole with a list of proposed samples to get a vote what people want most.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-6427776880622752333?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/flPEcFnXzhZm0Yeqd_DoxI3hSCc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/flPEcFnXzhZm0Yeqd_DoxI3hSCc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/flPEcFnXzhZm0Yeqd_DoxI3hSCc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/flPEcFnXzhZm0Yeqd_DoxI3hSCc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/PBWLoNVJlq0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/6427776880622752333/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=6427776880622752333&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6427776880622752333?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6427776880622752333?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/PBWLoNVJlq0/links-to-sample-down.html" title="Links to Sample Down :(" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-RbZ3-H_MG_U/TgKDSPvPP-I/AAAAAAAAA-0/dPrWkwfknT0/s72-c/wlEmoticon-disappointedsmile%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/06/links-to-sample-down.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QGQHczcCp7ImA9WhZbF0k.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-4916347066673037271</id><published>2011-06-22T13:20:00.001+01:00</published><updated>2011-06-22T13:22:01.988+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-22T13:22:01.988+01:00</app:edited><title>Filter NuGet Package updated</title><content type="html">&lt;h5&gt;&lt;a href="http://nuget.org/List/Packages/DynamicData.ThirteenFilters"&gt;&lt;font style="font-weight: normal"&gt;Thirteen Dynamic Data Custom Filters&lt;/font&gt;&lt;/a&gt;&lt;font style="font-weight: normal"&gt; has been updated to &lt;/font&gt;&lt;a href="http://nuget.org/List/Packages/DynamicData.CustomFilters"&gt;&lt;font style="font-weight: normal"&gt;Dynamic Data 15 Custom Filters&lt;/font&gt;&lt;/a&gt;&lt;font style="font-weight: normal"&gt; and the PackageId is now “DynamicData.CustomFilters”, makes more sense than “DynamicData.ThirteenFilters” especially it now had 15 filters instead of 13.&lt;/font&gt;&lt;/h5&gt;  &lt;p&gt;I have added&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;GreaterThanOrEqual &lt;/li&gt;    &lt;li&gt;LessThanOrEqual &lt;/li&gt; &lt;/ul&gt;  &lt;h5&gt;Sample Metadata&lt;/h5&gt;  &lt;pre class="brush: csharp;"&gt;[MetadataTypeAttribute(typeof(Product.ProductMetadata))]
public partial class Product
{
    internal sealed class ProductMetadata
    {
        [FilterUIHint(&amp;quot;MultiForeignKey&amp;quot;)]
        public Category Category { get; set; }

        public Nullable&amp;lt;int&amp;gt; CategoryID { get; set; }

        public bool Discontinued { get; set; }

        public EntityCollection&amp;lt;Order_Detail&amp;gt; Order_Details { get; set; }

        public int ProductID { get; set; }

        public string ProductName { get; set; }

        public string QuantityPerUnit { get; set; }

        public Nullable&amp;lt;short&amp;gt; ReorderLevel { get; set; }

        public Supplier Supplier { get; set; }

        public Nullable&amp;lt;int&amp;gt; SupplierID { get; set; }

        [FilterUIHint(&amp;quot;GreaterThanOrEqual&amp;quot;)]
        public Nullable&amp;lt;decimal&amp;gt; UnitPrice { get; set; }

        [FilterUIHint(&amp;quot;LessThanOrEqual&amp;quot;)]
        public Nullable&amp;lt;short&amp;gt; UnitsInStock { get; set; }

        public Nullable&amp;lt;short&amp;gt; UnitsOnOrder { get; set; }
    }
}&lt;/pre&gt;

&lt;p&gt;Much fun I expect there will be more soon.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-4916347066673037271?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zKuSeCLgtEcynnbrb2i65pU_Mxs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zKuSeCLgtEcynnbrb2i65pU_Mxs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zKuSeCLgtEcynnbrb2i65pU_Mxs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zKuSeCLgtEcynnbrb2i65pU_Mxs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/qpU-A62cYwY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/4916347066673037271/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=4916347066673037271&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/4916347066673037271?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/4916347066673037271?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/qpU-A62cYwY/filter-nuget-package-updated.html" title="Filter NuGet Package updated" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/06/filter-nuget-package-updated.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAHQXgzfCp7ImA9WhZbF04.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-7594345230616940738</id><published>2011-06-21T22:31:00.001+01:00</published><updated>2011-06-22T11:32:10.684+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-22T11:32:10.684+01:00</app:edited><title>More NuGet</title><content type="html">&lt;p&gt;I have just put up the the first instalment of my Dynamic Data Extensions this version (V1.0) we have&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;HideColumnIn attribute see &lt;a href="http://csharpbits.notaclue.net/2010/02/new-way-to-do-column-generation-in.html"&gt;A New Way To Do Column Generation in Dynamic Data 4&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;ShowColumnOnlyIn attribute does what it says on the tin shows column in particular page templates &lt;/li&gt;    &lt;li&gt;Filter attribute (I have only implemented the Order property as yet) this allows you to set the filter order. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Dynamic Data Extensions" border="0" alt="Dynamic Data Extensions" src="http://lh5.ggpht.com/-ZYKjzOiMEi4/TgEOii-dVEI/AAAAAAAAA-w/7kZs-3TP-xY/DynamicDataExtensions100x100%25255B3%25255D.png?imgmax=800" width="100" height="93" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Dynamic Data Extensions&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Search for DynamicData.Extensions on &lt;a href="http://nuget.org"&gt;NuGet&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;Example Metadata&lt;/h4&gt;  &lt;pre class="brush: csharp;"&gt;[MetadataTypeAttribute(typeof(Order.OrderMetadata))]
public partial class Order
{
    internal sealed class OrderMetadata
    {
        public string CustomerID { get; set; }
        public Nullable&amp;lt;int&amp;gt; EmployeeID { get; set; }
        public Nullable&amp;lt;int&amp;gt; ShipVia { get; set; }

        [ShowColumnOnlyIn(PageTemplate.List)]
        [ScaffoldColumn(true)]
        public int OrderID { get; set; }

        public Nullable&amp;lt;DateTime&amp;gt; OrderDate { get; set; }

        [HideColumnIn(PageTemplate.List | PageTemplate.Insert)]
        public Nullable&amp;lt;DateTime&amp;gt; RequiredDate { get; set; }

        [HideColumnIn(PageTemplate.List | PageTemplate.Insert)]
        public Nullable&amp;lt;DateTime&amp;gt; ShippedDate { get; set; }
        public Nullable&amp;lt;decimal&amp;gt; Freight { get; set; }
        public string ShipName { get; set; }
        public string ShipAddress { get; set; }
        public string ShipCity { get; set; }
        public string ShipCountry { get; set; }
        public string ShipRegion { get; set; }
        public string ShipPostalCode { get; set; }

        [Filter(Order=2)]
        public Customer Customer { get; set; }
        [Filter(Order = 1)]
        public Employee Employee { get; set; }
        [Filter(Order = 3)]
        public Shipper Shipper { get; set; }

        public EntityCollection&amp;lt;Order_Detail&amp;gt; Order_Details { get; set; }
    }
}&lt;/pre&gt;

&lt;p&gt;Here you can see all three custom attributes in action.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;strong&gt;HideColumnInAttribute&lt;/strong&gt; hides columns in page templates (note the use of the ‘|’ OR operator to allows multiple pages to be selected. &lt;/li&gt;

  &lt;li&gt;The &lt;strong&gt;ShowColumnOnlyInAttribute&lt;/strong&gt; does the opposite and only shows columns in selected pages.&lt;/li&gt;

  &lt;li&gt;The &lt;strong&gt;FilterAttribute&lt;/strong&gt; here sets the order to display the filters on the list page (Note there are other properties on Filter that are not yet implemented).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up on &lt;a href="http://nuget.org"&gt;NuGet&lt;/a&gt; are both of my original cascade and my hierarchical cascading field templates. 

  &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-7594345230616940738?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1vV9HIuf52I2ndKeStZ-S-K0kK0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1vV9HIuf52I2ndKeStZ-S-K0kK0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1vV9HIuf52I2ndKeStZ-S-K0kK0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1vV9HIuf52I2ndKeStZ-S-K0kK0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/D3byZL8ILC0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/7594345230616940738/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=7594345230616940738&amp;isPopup=true" title="17 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7594345230616940738?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7594345230616940738?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/D3byZL8ILC0/more-nuget.html" title="More NuGet" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-ZYKjzOiMEi4/TgEOii-dVEI/AAAAAAAAA-w/7kZs-3TP-xY/s72-c/DynamicDataExtensions100x100%25255B3%25255D.png?imgmax=800" height="72" width="72" /><thr:total>17</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/06/more-nuget.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UCQH85eSp7ImA9WhZbFkk.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-5255406502177164317</id><published>2011-06-19T08:54:00.001+01:00</published><updated>2011-06-21T09:34:21.121+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-21T09:34:21.121+01:00</app:edited><title>Web Application Project vs. Website</title><content type="html">&lt;p&gt;I have a poll &lt;a href="http://twtpoll.com/tkuwkm"&gt;here&lt;/a&gt; all I’m asking is what do you prefer?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-5255406502177164317?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8AN4DlUxnlET8Op1U3vXD5GySFk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8AN4DlUxnlET8Op1U3vXD5GySFk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8AN4DlUxnlET8Op1U3vXD5GySFk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8AN4DlUxnlET8Op1U3vXD5GySFk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/fG1euPIZv5U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/5255406502177164317/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=5255406502177164317&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/5255406502177164317?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/5255406502177164317?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/fG1euPIZv5U/web-application-project-vs-website.html" title="Web Application Project vs. Website" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/06/web-application-project-vs-website.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYGSHw_eyp7ImA9WhdSGEw.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-853277950335485588</id><published>2011-06-10T17:18:00.001+01:00</published><updated>2011-07-28T01:32:09.243+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-28T01:32:09.243+01:00</app:edited><title>A Second NuGet Package for Dynamic Data</title><content type="html">&lt;p&gt;&lt;a href="http://nuget.org/List/Packages/NotAClue.DynamicData.CustomFilters"&gt;Dynamic Data 15 Custom Filters&lt;/a&gt; is now on &lt;a href="http://nuget.org"&gt;NuGet&lt;/a&gt;&amp;#160; this package add thirteen filters to your Web Application Project see &lt;a href="http://csharpbits.notaclue.net/2010/11/five-cool-filters-for-dynamic-data-4.html"&gt;Five Cool Filters for Dynamic Data 4&lt;/a&gt; I have added some more filters to that list;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;AutoComplete – is ForeignKey filter but pre-filters results by what users has typed in. &lt;/li&gt;    &lt;li&gt;Contains – equivalent to T-SQL LIKE ‘%text%’ &lt;/li&gt;    &lt;li&gt;DateFrom – All Dates greater than or equal to the selected date. &lt;/li&gt;    &lt;li&gt;DateRange – A range of dates &lt;/li&gt;    &lt;li&gt;DateTo – Less than or equal to the selected date. &lt;/li&gt;    &lt;li&gt;EndsWith – Ends with entered text. &lt;/li&gt;    &lt;li&gt;GreaterThan – Greater than entered value &lt;/li&gt;    &lt;li&gt;LessThan – Less than entered value &lt;/li&gt;    &lt;li&gt;MultiForeignKey – allows multiple ForeignKey values to be selected. &lt;/li&gt;    &lt;li&gt;Range – a range of values &lt;/li&gt;    &lt;li&gt;StartWith – Starts with entered text. &lt;/li&gt;    &lt;li&gt;Where – is equal to entered text &lt;/li&gt;    &lt;li&gt;WhereDropdownList – a dropdown list of values from column to filter by. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This has a few more exciting bits that &lt;a href="http://nuget.org"&gt;NuGet&lt;/a&gt; offers &lt;strong&gt;Dependencies&lt;/strong&gt; and &lt;strong&gt;Framework Assembly References&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;, here this package there is dependency upon Ajax Control Toolkit &lt;/p&gt;  &lt;pre class="brush: xml;"&gt;&amp;lt;dependencies&amp;gt;
    &amp;lt;dependency id=&amp;quot;AjaxControlToolkit&amp;quot; version=&amp;quot;4.1.50508&amp;quot; /&amp;gt;
&amp;lt;/dependencies&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Framework Assembly References&lt;/strong&gt; – is requirement for an assembly reference from the GAC&lt;/p&gt;

&lt;pre class="brush: xml;"&gt;&amp;lt;frameworkAssemblies&amp;gt;
    &amp;lt;frameworkAssembly assemblyName=&amp;quot;System.Data.Entity&amp;quot; targetFramework=&amp;quot;net40&amp;quot; /&amp;gt;
&amp;lt;/frameworkAssemblies&amp;gt;&lt;/pre&gt;

&lt;p&gt;This give great flexibility without resorting to PowerShell.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://nuget.org"&gt;NuGet&lt;/a&gt; truly is awesome!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-853277950335485588?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/muEkGceb34u9f7vfZWERRjuLwbc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/muEkGceb34u9f7vfZWERRjuLwbc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/muEkGceb34u9f7vfZWERRjuLwbc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/muEkGceb34u9f7vfZWERRjuLwbc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/RKXWkooMSkE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/853277950335485588/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=853277950335485588&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/853277950335485588?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/853277950335485588?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/RKXWkooMSkE/second-nuget-package-for-dynamic-data.html" title="A Second NuGet Package for Dynamic Data" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><thr:total>6</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/06/second-nuget-package-for-dynamic-data.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcFRnw-eCp7ImA9WhZUF0Q.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-8664451811820405353</id><published>2011-06-10T14:52:00.001+01:00</published><updated>2011-06-11T13:56:57.250+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-11T13:56:57.250+01:00</app:edited><title>NuGet for Dynamic Data – First Package</title><content type="html">&lt;p&gt;I have just added my first &lt;a href="http://nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt; package, and you may no know what &lt;a href="http://nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt; is? so what is &lt;a href="http://nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt; it’s a Package management add on for Visual Studio 2010 and above (maybe more as it is integrated with Windows PowerShell).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-HDPiRPh4hFs/TfIhgulnL3I/AAAAAAAAA-Y/U_1VHSgqE5Y/s1600-h/Install%252520NuGet%25255B10%25255D.png" target="_blank"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Install NuGet" border="0" alt="Install NuGet" src="http://lh3.ggpht.com/-gYRkJcyHS2s/TfIhiP_A-ZI/AAAAAAAAA-c/Rr3aZgdVeMU/Install%252520NuGet_thumb%25255B8%25255D.png?imgmax=800" width="640" height="300" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 1 – Install NuGet&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;See &lt;a href="http://docs.nuget.org/docs/start-here/installing-nuget" target="_blank"&gt;Installing NuGet&lt;/a&gt; and then you will need &lt;a href="http://nuget.codeplex.com/releases/view/58939" target="_blank"&gt;NuGet.exe Command Line&lt;/a&gt; and or &lt;a href="http://nuget.codeplex.com/releases/view/59864" target="_blank"&gt;NuGet Package Explorer v1.1&lt;/a&gt; this is the GUI version (and unlike &lt;a href="http://www.hanselman.com/blog/" target="_blank"&gt;Scott Hanselman&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt; I like the GUI and try to avoid the DOS as much as possible I’m with &lt;a href="http://haacked.com/" target="_blank"&gt;Phil Haack&lt;/a&gt; on that see &lt;a href="http://channel9.msdn.com/events/MIX/MIX11/FRM09"&gt;NuGet In Depth: Empowering Open Source on the .NET Platform&lt;/a&gt; on Channel9) and can do a lot of what the command line tool does.&lt;/p&gt;  &lt;p&gt;You can get loads on information on &lt;a href="http://docs.nuget.org/" target="_blank"&gt;NuGet Docs&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;OK so I’m going to assume your all setup and ready to go.&lt;/p&gt;  &lt;h4&gt;Creating the Package&lt;/h4&gt;  &lt;p&gt;NuGet has some &lt;a href="http://docs.nuget.org/docs/creating-packages/package-conventions"&gt;Package Conventions&lt;/a&gt; and we should follow them (I’ll not explain them just go and have a read as documentation can be updated from time to time) for out package lets first of all look at what we want to package.&lt;/p&gt;  &lt;p&gt;For this Package I want to package up &lt;a href="http://blogs.msdn.com/b/scothu/" target="_blank"&gt;Scott Hunter’s&lt;/a&gt; old &lt;a href="http://blogs.msdn.com/b/scothu/archive/2008/01/14/sample.aspx"&gt;Sample for Displaying Images from the Database using Dynamic Data&lt;/a&gt; (DBImage) and it’s update &lt;a href="http://blogs.msdn.com/b/scothu/archive/2008/04/09/sample-for-displaying-images-updated-screencast.aspx"&gt;Sample for Displaying Images Updated + Screencast&lt;/a&gt; note the latest version of this is in the old &lt;a href="http://aspnet.codeplex.com/releases/view/14475"&gt;Dynamic Data Futures VS2008 SP1 RTM&lt;/a&gt; for DD 3.51 SP1.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Embedded image field template" border="0" alt="Embedded image field template" src="http://lh3.ggpht.com/-CfUN0PLhSn0/TfIhi_fxR5I/AAAAAAAAA-g/paq68TI8xL8/Embedded%252520image%252520field%252520template%25255B9%25255D.png?imgmax=800" width="576" height="342" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 2 – Embedded image field template&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This consists of several parts;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Read-Only field template &lt;/li&gt;    &lt;li&gt;Edit field template &lt;/li&gt;    &lt;li&gt;Image Format attribute &lt;/li&gt;    &lt;li&gt;Linq extension methods &lt;/li&gt;    &lt;li&gt;Image http handler. &lt;/li&gt;    &lt;li&gt;Web.Config settings &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I have decided to keep things simple for out first &lt;a href="http://nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt; Package and all the above will go into one package some of the above could be shared and as such we could spilt it between several packages and have dependencies but we will keep it simple for now.&lt;/p&gt;  &lt;p&gt;so to build our package there are some things we need to know like where do we put our files;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Package folder structure" border="0" alt="Package folder structure" src="http://lh6.ggpht.com/-gfr7UgxjTCc/TfIhjdE-BJI/AAAAAAAAA-k/tPok4wdO80s/Package%252520folder%252520structure%25255B20%25255D.png?imgmax=800" width="514" height="335" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 3 – Simple Package folder structure&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;As you can see I have broken the folder structure into three parts, the first part is quite simple, it’s the readme file which will give basic information about the package. &lt;/p&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Content (files to be copied on install)&lt;/h5&gt;  &lt;p&gt;Here you can have three types of file;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Copied as is with no changes. &lt;/li&gt;    &lt;li&gt;Transform files (see &lt;a href="http://docs.nuget.org/docs/creating-packages/configuration-file-and-source-code-transformations" target="_blank"&gt;Configuration File and Source Code Transformations&lt;/a&gt; for more info)       &lt;ul&gt;       &lt;li&gt;.transform or Configuration File Transformations &lt;/li&gt;        &lt;li&gt;.pp or Source Code Transformations &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The “.transform” files transform &lt;em&gt;web.config&lt;/em&gt; or &lt;em&gt;app.config&lt;/em&gt; files by adding/merging their content with the project’s configuration file. &lt;/p&gt;  &lt;p&gt;While the “.pp” files are files that are transformed as they are copied to the project in the same folder structure they have in the package. These files are a little more complex than the configuration files, as they have Visual Studio project properties in the code and these are used to transform the code files during install ((see &lt;a href="http://docs.nuget.org/docs/creating-packages/configuration-file-and-source-code-transformations" target="_blank"&gt;Configuration File and Source Code Transformations&lt;/a&gt; and the &lt;strong&gt;Specifying Source Code Transformations&lt;/strong&gt; section for more info).&lt;/p&gt;  &lt;h5&gt;Lib Folder&lt;/h5&gt;  &lt;p&gt;This folder contains any DLLs that are required, not that the “net40” subfolder this indicates that the DLL supports .Net 4 you could have several version that support different versions of the .Net framework here we will just support .Net 4.&lt;/p&gt;  &lt;h5&gt;Next&lt;/h5&gt;  &lt;p&gt;Note this is just the basic of where you need to put files for your package to work.&lt;/p&gt;  &lt;p&gt;now we have out files ready in a folder structure we need to create our “nuspec” file, this is an XML file containing details (the manifest) about the package you can manually create this or you can use &lt;strong&gt;NuGet Package Explorer&lt;/strong&gt; to create this see &lt;a href="http://docs.nuget.org/docs/creating-packages/using-a-gui-to-build-packages" target="_blank"&gt;Using A GUI (Package Explorer) to build packages&lt;/a&gt; once created you can manually edit the “nuspec” file manually if you like.&lt;/p&gt;  &lt;p&gt;You then place your “nuspec” file in the root of the package folder structure or if you follow &lt;a href="http://docs.nuget.org/docs/creating-packages/using-a-gui-to-build-packages" target="_blank"&gt;Using A GUI (Package Explorer) to build packages&lt;/a&gt; you can add them directly.&lt;/p&gt;  &lt;p&gt;Once done you just publish and it works!&lt;/p&gt;  &lt;h5&gt;Next steps&lt;/h5&gt;  &lt;p&gt;The real power come with PowerShell scripts see &lt;a href="http://channel9.msdn.com/Events/MIX/MIX11/FRM13"&gt;Scaffolding – ASP.NET, NuGet, Entity Framework Code First and More&lt;/a&gt; with &lt;a href="http://blog.stevensanderson.com/" target="_blank"&gt;Steve Sanderson&lt;/a&gt; he shows what you can really do.&lt;/p&gt;  &lt;p&gt;I am going to add more complex post here as I discover new and interesting feature of &lt;a href="http://nuget.org/" target="_blank"&gt;NuGet&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-8664451811820405353?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/l6jr2qpx5kimqzB3bDQJmmcmN8A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/l6jr2qpx5kimqzB3bDQJmmcmN8A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/l6jr2qpx5kimqzB3bDQJmmcmN8A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/l6jr2qpx5kimqzB3bDQJmmcmN8A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/6MgLwMfYxcc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/8664451811820405353/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=8664451811820405353&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/8664451811820405353?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/8664451811820405353?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/6MgLwMfYxcc/nuget-for-dynamic-data-first-package.html" title="NuGet for Dynamic Data – First Package" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-gYRkJcyHS2s/TfIhiP_A-ZI/AAAAAAAAA-c/Rr3aZgdVeMU/s72-c/Install%252520NuGet_thumb%25255B8%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/06/nuget-for-dynamic-data-first-package.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04NQX46eSp7ImA9WhZQFUk.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-7545920281970746451</id><published>2011-03-31T13:04:00.000+01:00</published><updated>2011-04-23T09:06:30.011+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-23T09:06:30.011+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".Net 4.0" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="Entity Templates" /><category scheme="http://www.blogger.com/atom/ns#" term="Attributes" /><title>Custom Entity Templates – Dynamic Data 4</title><content type="html">&lt;p&gt;In Dynamic Data 4 we have &lt;em&gt;Entity Templates &lt;/em&gt;these are great for customizing layout of tables (see &lt;a href="http://msdn.microsoft.com/en-us/library/dd723645(VS.100).aspx"&gt;Walkthrough: Customizing Table Layout Using &lt;em&gt;Entity Templates&lt;/em&gt;&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;).&amp;#160; At the moment you will have to create a Custom Entity template for each table, but not only that you will need to create a set of three (&lt;em&gt;Template&lt;/em&gt;, &lt;em&gt;Template&lt;/em&gt;_Edit and &lt;em&gt;Template&lt;/em&gt;_Insert) and that can be useful to have different layout for each view. &lt;/p&gt;  &lt;p&gt;But what if you want something different from the Default, (see &lt;a href="http://csharpbits.notaclue.net/2010/02/grouping-field-on-details-edit-and.html"&gt;Grouping Fields on Details, Edit and Insert with Dynamic Data 4, VS2010 and .Net 4.0 RC1&lt;/a&gt; my first custom Entity Template which then had to replace the Default and also had to have all three defined) but not on all your tables just on a selected few? &lt;/p&gt;  &lt;p&gt;I was inspired by Brian Pritchard’s post on the forum: &lt;a href="http://forums.asp.net/p/1443492/3277785.aspx"&gt;How to reduce code duplication when using Entity Template's&lt;/a&gt; for only having to create a single template that would switch between Read-Only, Edit and Insert modes.&lt;/p&gt;  &lt;p&gt;I want to go a little further:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Override the Default Entity Template with some sort of UIHint attribute. &lt;/li&gt;    &lt;li&gt;An only have to specify one template to keep things &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Detect if an Edit or Insert version of a template exists and use that. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So now we know out goal, let’s layout the ingredients for this recipe:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;An attribute to allow us to change the default Entity Template for any given Table. &lt;/li&gt;    &lt;li&gt;Custom entity factory to allow us to override normal entity behaviour like Brian Pritchard’s. &lt;/li&gt;    &lt;li&gt;A Custom dynamic Entity Template. &lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt;The Attribute&lt;/h4&gt;  &lt;p&gt;I thought I would be able to use UIHint at class level but alas we have to hand craft our own, I want some of the same feature of UIHint specifically the Control Parameters collection so that we can pass extra information into our custom Entity Templates with out creating a plethora extra attribute each specific to it’s one Entity Template. (I’ve used the Control Parameters collection before in &lt;a href="http://csharpbits.notaclue.net/2009/07/dynamic-data-custom-field-template_28.html"&gt;Dynamic Data Custom Field Template – Values List, Take 2&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The Attribute is relatively straight forward, the only complication is the &lt;em&gt;BuildControlParametersDictionary&lt;/em&gt; method which takes the &lt;em&gt;Object&lt;/em&gt; array passed in using the &lt;em&gt;params&lt;/em&gt; key word into a Key, Value Dictionary with some validation. Note we have also set this attribute to be only useable at Class level. &lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class EntityUIHintAttribute : Attribute
{
    private IDictionary&lt;string   , object&gt; _controlParameters;

    public IDictionary&lt;string   , object&gt; ControlParameters
    {
        get { return this._controlParameters; }
    }

    /// &lt;summary&gt;
    /// Gets or sets the UI hint.
    /// &lt;/summary&gt;
    /// &lt;value&gt;The UI hint.&lt;/value&gt;
    public String UIHint { get; private set; }

    public EntityUIHintAttribute(string uiHint) : this(uiHint, new object[0]) { }

    public EntityUIHintAttribute(string uiHint, params object[] controlParameters)
    {
        UIHint = uiHint;
        _controlParameters = BuildControlParametersDictionary(controlParameters);
    }

    public override object TypeId
    {
        get { return this; }
    }

    private IDictionary&lt;string   , object&gt; BuildControlParametersDictionary(object[] objArray)
    {
        IDictionary&lt;string   , object&gt; dictionary = new Dictionary&lt;string   , object&gt;();
        if ((objArray != null) &amp;amp;&amp;amp; (objArray.Length != 0))
        {
            if ((objArray.Length % 2) != 0)
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, &amp;quot;Need even number of control parameters.&amp;quot;, new object[0]));

            for (int i = 0; i &amp;lt; objArray.Length; i += 2)
            {
                object obj2 = objArray[i];
                object obj3 = objArray[i + 1];
                if (obj2 == null)
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, &amp;quot;Control parameter key is null.&amp;quot;, new object[] { i }));

                string key = obj2 as string;
                if (key == null)
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, &amp;quot;Control parameter key is not a string.&amp;quot;, new object[] { i, objArray[i].ToString() }));

                if (dictionary.ContainsKey(key))
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, &amp;quot;Control parameter key occurs more than once.&amp;quot;, new object[] { i, key }));

                dictionary[key] = obj3;
            }
        }
        return dictionary;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – EntityUIHintAttribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we need a method to use this attribute to change the default Entity Template, this factory need to do two things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Change the Default Entity Template based on out new EntityUIHint attribute. &lt;/li&gt;

  &lt;li&gt;Intercept the template mode so that single Entity Template can be used with out having to have three versions. &lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="brush: csharp;"&gt;public class AdvancedEntityTemplateFactory : System.Web.DynamicData.EntityTemplateFactory
{
    public override string BuildEntityTemplateVirtualPath(string templateName, DataBoundControlMode mode)
    {
        var path = base.BuildEntityTemplateVirtualPath(templateName, mode);
        var editPath = base.BuildEntityTemplateVirtualPath(templateName, DataBoundControlMode.Edit);;
        var defaultPath = base.BuildEntityTemplateVirtualPath(templateName, DataBoundControlMode.ReadOnly); ;

        if (File.Exists(HttpContext.Current.Server.MapPath(path)))
            return path;

        if (mode == DataBoundControlMode.Insert &amp;amp;&amp;amp; File.Exists(HttpContext.Current.Server.MapPath(editPath)))
            return editPath;

        if (mode != DataBoundControlMode.ReadOnly &amp;amp;&amp;amp; File.Exists(HttpContext.Current.Server.MapPath(defaultPath)))
            return defaultPath;

        return path;
    }

    public override EntityTemplateUserControl CreateEntityTemplate(MetaTable table, DataBoundControlMode mode, string uiHint)
    {
        var et = table.GetAttribute&lt;entityuihintattribute&gt;();
        if (et != null &amp;amp;&amp;amp; !String.IsNullOrEmpty(et.UIHint))
            return base.CreateEntityTemplate(table, mode, et.UIHint);

        return base.CreateEntityTemplate(table, mode, uiHint);
    }

    public override string GetEntityTemplateVirtualPath(MetaTable table, DataBoundControlMode mode, string uiHint)
    {
        var et = table.GetAttribute&lt;entityuihintattribute&gt;();
        if (et != null &amp;amp;&amp;amp; !String.IsNullOrEmpty(et.UIHint))
            return base.GetEntityTemplateVirtualPath(table, mode, et.UIHint);

        return base.GetEntityTemplateVirtualPath(table, mode, uiHint);
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 2 – AdvancedEntityTemplateFactory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Listing 1&lt;/strong&gt; shows us out AdvancedEntityTemplateFactory, we fulfil task 1. in the methods &lt;em&gt;CreateEntityTemplate&lt;/em&gt; and &lt;em&gt;GetEntityTemplateVirtualPath&lt;/em&gt; where we check for the presence of a &lt;em&gt;EntityUIHintAttribute&lt;/em&gt; and if we find one then set the name of the template to the UIHint property.&lt;/p&gt;

&lt;p&gt;Task 2. is dealt with in the &lt;em&gt;BuildEntityTemplateVirtualPath&lt;/em&gt; where we check to see if the file exists, if so we just return the path as is, otherwise we strip out the&amp;#160; _Edit or _Insert from the path and return. &lt;/p&gt;

&lt;p&gt;The last thing we need is to wire up the AdvancedEntityTemplateFactory in Global.asax.cs&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;DefaultModel.EntityTemplateFactory = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;AdvancedEntityTemplateFactory&lt;/span&gt;();&lt;/pre&gt;

&lt;p&gt;just before the RegisterContext in RegisterRoutes method.&lt;/p&gt;

&lt;h4&gt;&lt;/h4&gt;

&lt;h4&gt;The Custom Entity Template&lt;/h4&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_UUHjb9DZhJM/TM2sWRVrPUI/AAAAAAAAA6E/EDt0tJsZABI/s1600-h/MultiColumnEntityTemplate%5B9%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Multi Column Entity Template" border="0" alt="Multi Column Entity Template" src="http://lh5.ggpht.com/_UUHjb9DZhJM/TM2sW7NYWvI/AAAAAAAAA6I/0LWRtNUIv5U/MultiColumnEntityTemplate_thumb%5B5%5D.png?imgmax=800" width="779" height="445" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1 – Multi Column Entity Template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This entity template will be a multi column temp[late designed to give you a little more screen for your money &lt;img alt="Big Grin" src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/4.gif" /&gt; I have decided to pass the main parameters in via the EntityUIHint attribute’s Control Parameters, in &lt;strong&gt;Figure 2&lt;/strong&gt; you can see them in pairs.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_UUHjb9DZhJM/TM2sXlNu0FI/AAAAAAAAA6M/MpIk8J32yGw/s1600-h/ControlParameters%5B9%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Control Parameters" border="0" alt="Control Parameters" src="http://lh5.ggpht.com/_UUHjb9DZhJM/TM2sX3tk7tI/AAAAAAAAA6Q/L_da6y6EPss/ControlParameters_thumb%5B5%5D.png?imgmax=800" width="427" height="183" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2 – Control Parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;“Columns”, 3 sets the number of column the MultiColumn entity template will show.&lt;/p&gt;

&lt;p&gt;The next two pairs are the Title and Field CSS classes.&lt;/p&gt;

&lt;p&gt;I’ve also decided to add the ability for some columns to span more then one cell in the table.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;[AttributeUsage(AttributeTargets.Property)]
public class MultiColumnAttribute : Attribute
{
    /// &lt;summary&gt;
    /// Gets or sets the column span.
    /// &lt;/summary&gt;
    /// &lt;value&gt;The column span.&lt;/value&gt;
    public int ColumnSpan { get; private set; }

    public static MultiColumnAttribute Default = new MultiColumnAttribute();

    public MultiColumnAttribute() 
    { 
        ColumnSpan = 1;
    }

    public MultiColumnAttribute(int columnSpan)
    {
        ColumnSpan = columnSpan;
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 3 – MultiColumnAttribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The use of Default for when we use the DefaultIfEmpty method in Linq (see my &lt;a href="http://csharpbits.notaclue.net/2009/01/writing-attribute-and-extension-methods.html"&gt;Writing Attributes and Extension Methods for Dynamic Data&lt;/a&gt; more info) this allows us to get an attribute even if one is not specified so now with thi sline of code &lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; totalNoOfCells = metaColumns.Select(c =&amp;gt; c.GetAttributeOrDefault&amp;lt;&lt;span style="color: #2b91af"&gt;MultiColumnAttribute&lt;/span&gt;&amp;gt;().ColumnSpan).Sum();&lt;/pre&gt;

&lt;p&gt;we can get the total number of cell required with some columns having a span of more than on column see &lt;strong&gt;Figure 1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finally our Multi Column entity template is completed in &lt;strong&gt;Listing 4&lt;/strong&gt;&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public partial class MultiColumnEntityTemplate : System.Web.DynamicData.EntityTemplateUserControl
{
    private const string COLUMNS = &amp;quot;Columns&amp;quot;;
    private const string TITLE_CSS_CLASS = &amp;quot;TitleCssClass&amp;quot;;
    private const string FIELD_CSS_CLASS = &amp;quot;FieldCssClass&amp;quot;;

    protected override void OnLoad(EventArgs e)
    {
        // get columns from table
        var metaColumns = Table.GetScaffoldColumns(Mode, ContainerType).ToList();

        // do not render any HTML table if there are no columns returned
        if (metaColumns.Count == 0)
            return;

        // default the HTML table columns and CSS class names
        int columns = 2;
        String titleCssClass = String.Empty;
        String fieldCssClass = String.Empty;

        // Get the CssClass for the title &amp;amp; Field from the attribute
        var entityUHint = Table.GetAttribute&lt;entityuihintattribute&gt;();
        if (entityUHint != null)
        {
            if (entityUHint.ControlParameters.Keys.Contains(COLUMNS))
                columns = (int)entityUHint.ControlParameters[COLUMNS];
            if (entityUHint.ControlParameters.Keys.Contains(TITLE_CSS_CLASS))
                titleCssClass = entityUHint.ControlParameters[TITLE_CSS_CLASS].ToString();
            if (entityUHint.ControlParameters.Keys.Contains(FIELD_CSS_CLASS))
                fieldCssClass = entityUHint.ControlParameters[FIELD_CSS_CLASS].ToString();
        }

        // start in the left column
        int col = 0;

        // create the header &amp;amp; data cells
        var headerRow = new HtmlTableRow();
        if (!String.IsNullOrEmpty(titleCssClass))
            headerRow.Attributes.Add(&amp;quot;class&amp;quot;, titleCssClass);
        var dataRow = new HtmlTableRow();
        if (!String.IsNullOrEmpty(fieldCssClass))
            dataRow.Attributes.Add(&amp;quot;class&amp;quot;, fieldCssClass);

        // step through each of the columns to be added to the table
        foreach (var metaColumn in metaColumns)
        {
            // get the MultiColumn attribute for the column
            var multiColumn = metaColumn.GetAttributeOrDefault&lt;multicolumnattribute&gt;();
            if (multiColumn.ColumnSpan &amp;gt; columns)
                throw new InvalidOperationException(String.Format(&amp;quot;MultiColumn attribute specifies that this 
                    field occupies {0} columns, but the EntityUIHint attribute for the class only allocates {1} 
                    columns in the HTML table.&amp;quot;, multiColumn.ColumnSpan, columns));

            // check if there are sufficient columns left in the current row
            if (col + multiColumn.ColumnSpan &amp;gt; columns)
            {
                // save this header row
                this.Controls.Add(headerRow);
                headerRow = new HtmlTableRow();
                if (!String.IsNullOrEmpty(titleCssClass))
                    headerRow.Attributes.Add(&amp;quot;class&amp;quot;, titleCssClass);

                // save this data row
                this.Controls.Add(dataRow);
                dataRow = new HtmlTableRow();
                if (!String.IsNullOrEmpty(fieldCssClass))
                    dataRow.Attributes.Add(&amp;quot;class&amp;quot;, fieldCssClass);

                // need to start a new row
                col = 0;
            }

            // add the header cell
            var th = new HtmlTableCell();
            var label = new Label();
            label.Text = metaColumn.DisplayName;
            //if (Mode != System.Web.UI.WebControls.DataBoundControlMode.ReadOnly)
            //    label.PreRender += Label_PreRender;

            th.InnerText = metaColumn.DisplayName;
            if (multiColumn.ColumnSpan &amp;gt; 1)
                th.ColSpan = multiColumn.ColumnSpan;
            headerRow.Cells.Add(th);

            // add the data cell
            var td = new HtmlTableCell();
            var dynamicControl = new DynamicControl(Mode);
            dynamicControl.DataField = metaColumn.Name;
            dynamicControl.ValidationGroup = this.ValidationGroup;

            td.Controls.Add(dynamicControl);
            if (multiColumn.ColumnSpan &amp;gt; 1)
                td.ColSpan = multiColumn.ColumnSpan;
            dataRow.Cells.Add(td);

            // record how many columns we have used
            col += multiColumn.ColumnSpan;
        }
        this.Controls.Add(headerRow);
        this.Controls.Add(dataRow);
    }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 4 – MultiColumnEntityTemplate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #f0d0f0; margin: 4px; padding-left: 4px; padding-right: 4px; color: #800080; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Updated: &lt;/strong&gt; MultiColumnEntityTemplate updated by Phil Wigglesworth who kindly found a bug and fixed it, the bug was shown when there were no enough columns left on a row, this caused a crash. So thanks again to Phil.&lt;/div&gt;
Also we will need some styles to make out new Multi Column entity template look good. &lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;TR.SmallTitle
{
    background-color: #F7F7FF;
}
TR.SmallTitle TD
{
    font-size: 0.8em !important;
    font-weight: bold;
    background-color: #F7F7FF;
    padding: 2px !important;
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Listing 5 – CSS styles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hope this expand your use of Entity Templates.&lt;/p&gt;

&lt;p&gt;P.S. I’ll do an updated version of the Grouping entity template.&lt;/p&gt;

&lt;p&gt;Download&lt;/p&gt;
&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-96845e7b0fac1eed.office.live.com/embedicon.aspx/Public/CustomEntityTemplates.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-7545920281970746451?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/UJImdVNz7exaqPoV_J5g_PRjXig/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UJImdVNz7exaqPoV_J5g_PRjXig/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/UJImdVNz7exaqPoV_J5g_PRjXig/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UJImdVNz7exaqPoV_J5g_PRjXig/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/jrSO7AhPWnc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/7545920281970746451/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=7545920281970746451&amp;isPopup=true" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7545920281970746451?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7545920281970746451?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/jrSO7AhPWnc/custom-entity-templates-dynamic-data-4.html" title="Custom Entity Templates – Dynamic Data 4" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_UUHjb9DZhJM/TM2sW7NYWvI/AAAAAAAAA6I/0LWRtNUIv5U/s72-c/MultiColumnEntityTemplate_thumb%5B5%5D.png?imgmax=800" height="72" width="72" /><thr:total>13</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/10/custom-entity-templates-dynamic-data-4.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MHRn86fCp7ImA9Wx9WEk0.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-6617020443337423406</id><published>2011-01-16T19:05:00.001Z</published><updated>2011-01-16T19:17:17.114Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-16T19:17:17.114Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Sorting" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.Net 4.0" /><title>Setting the Initial Sort Order – Dynamic Data</title><content type="html">&lt;p&gt;This is just a quick note on a post I made on the &lt;a href="http://forums.asp.net/1145.aspx"&gt;Dynamic Data Forum&lt;/a&gt; to answer a question where setting the &lt;strong&gt;DisplayColumnAttribute&lt;/strong&gt; should set the default sort order of the &lt;strong&gt;GridView&lt;/strong&gt; on the &lt;strong&gt;List&lt;/strong&gt; page but didn’t. Here’s how I solved it with a hint or two from &lt;a href="http://blogs.msdn.com/marcinon/default.aspx"&gt;Marcin Dobosz&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:65e740b5-2b9c-4419-91c8-cd427a529715" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;[MetadataType(typeof(Orders_Metadata ))]
[DisplayColumn("OrderID", "OrderID", true)]
public partial class Orders
{
    public class Orders_Metadata
    {       
        // ...
    }
}&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Listing 1 – Example Metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Assuming you have a table with the &lt;strong&gt;DisplayColumnAttribute&lt;/strong&gt; set you could put this on your List page:&amp;#160; &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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:9c1fef38-b3bd-4239-b62c-1a8eedf3d3a3" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;table = GridDataSource.GetTable();

// set default sort
if (!IsPostBack &amp;amp;&amp;amp; table.SortColumn != null)
    GridView1.Sort(table.SortColumn.Name, table.SortDescending ? SortDirection.Descending : SortDirection.Ascending);&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Listing 2 – Add to Page_Init (.Net 3.5)&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:01a0d4fe-56b2-472e-bcf4-884bee05d537" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;// set default sort
if (!IsPostBack &amp;amp;&amp;amp; table.SortColumn != null)
{
    var order = new OrderByExpression()
    {
        DataField = table.SortColumn.Name,
        Direction = table.SortDescending ? SortDirection.Descending : SortDirection.Ascending,
    };
    GridQueryExtender.Expressions.Add(order);
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 3 – Add to Page_Init (.Net 4)&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:4ec042d4-0cf2-460e-b3ef-1f125768284f" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public static T GetAttribute&amp;lt;T&amp;gt;(this MetaTable table) where T : Attribute
{
    return table.Attributes.OfType&amp;lt;T&amp;gt;().FirstOrDefault();
}&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Listing 3 – you will also need this extension method see &lt;/strong&gt;&lt;a href="http://csharpbits.notaclue.net/2009/01/writing-attribute-and-extension-methods.html"&gt;Writing Attributes and Extension Methods for Dynamic Data&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add your &lt;strong&gt;DisplayColumnAttribute&lt;/strong&gt; (&lt;strong&gt;see Listing 1&lt;/strong&gt;) to the table you want sorted (&lt;strong&gt;note:&lt;/strong&gt; it must have the second string constant even if it’s the same name, as the second string it the one that the sort is done on, and the third value if true causes the sort to be descending). Then in &lt;strong&gt;Listing 2&lt;/strong&gt; you get the attribute using the extension method from &lt;strong&gt;Listing 3&lt;/strong&gt; and apply the relevant sort.&lt;/p&gt;

&lt;p&gt;This is here mainly so I can find it again! &lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="HappyWizard" border="0" alt="HappyWizard" src="http://lh5.ggpht.com/_UUHjb9DZhJM/TTNBiafQrOI/AAAAAAAAA8M/gHlRETXv0Sk/HappyWizard4.png?imgmax=800" width="19" height="33" /&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-6617020443337423406?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-a8UfyrVjqFVgwOpax0ViyGMGaI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-a8UfyrVjqFVgwOpax0ViyGMGaI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-a8UfyrVjqFVgwOpax0ViyGMGaI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-a8UfyrVjqFVgwOpax0ViyGMGaI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/8ePfq62yHxM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/6617020443337423406/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=6617020443337423406&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6617020443337423406?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6617020443337423406?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/8ePfq62yHxM/setting-initial-sort-order-dynamic-data.html" title="Setting the Initial Sort Order – Dynamic Data" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_UUHjb9DZhJM/TTNBiafQrOI/AAAAAAAAA8M/gHlRETXv0Sk/s72-c/HappyWizard4.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/01/setting-initial-sort-order-dynamic-data.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4EQHY-fCp7ImA9Wx9WE00.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-1813432532438792940</id><published>2011-01-13T00:03:00.001Z</published><updated>2011-01-17T23:45:01.854Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-17T23:45:01.854Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="Filtering" /><category scheme="http://www.blogger.com/atom/ns#" term="Multi Column Search" /><category scheme="http://www.blogger.com/atom/ns#" term="Searching" /><title>Adding a Multi-Column Search to the Default List page in Dynamic Data (UPDATED)</title><content type="html">&lt;p&gt;This will extend the default filters that Dynamic Data provides by adding a free text search box the will search multiple text fields on the same page. I have done this in a few projects now as one off but after this post &lt;a href="http://forums.asp.net/t/1640135.aspx"&gt;Custom filters &amp;amp; searches within DD in Visual Web Developer 2010 &lt;/a&gt;on the &lt;a href="http://forums.asp.net/1145.aspx"&gt;Dynamic Data Forum&lt;/a&gt; I decided to document it here.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_UUHjb9DZhJM/TS5BZl-w1uI/AAAAAAAAA78/6AAb99HK39I/s1600-h/MultiColumnSearch%5B5%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Multi Column Search" border="0" alt="Multi Column Search" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TS5BaA9sgBI/AAAAAAAAA8A/3cR6dDWXav0/MultiColumnSearch_thumb%5B3%5D.png?imgmax=800" width="307" height="260" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 1 – Multi Column Search&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Here in &lt;strong&gt;Figure 1 &lt;/strong&gt;you can see the multi column search box, in this example the search is on FistName, LastName, Address, City and Country, it will even allow search across entities e.g. on Orders Employee.LastName etc. which make it very flexible.&lt;/p&gt;  &lt;h4&gt;Things we will need to do&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Attribute to tell the system which columns to search on. &lt;/li&gt;    &lt;li&gt;Add mark-up to show the UI on the List page. &lt;/li&gt;    &lt;li&gt;Code to wire up the UI and QueryExtender. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;The Attribute&lt;/h4&gt;  &lt;p&gt;This attribute will be added to the Class/Table not it’s columns and will have only one property Columns.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:3b206a04-2e8a-4280-a648-2141689aa302" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;[AttributeUsage(AttributeTargets.Class)]
public class MultiColumnSearchAttribute : Attribute
{
    public String[] Columns { get; private set; }

    public MultiColumnSearchAttribute(params String[] columns)
    {
        Columns = columns;
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – MultiColumnSearchAttribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and we apply it as in &lt;strong&gt;Listing 2&lt;/strong&gt; The Employee table show standard multi-column search but the Order table shows how we can search across entity boundaries you can see this in &lt;strong&gt;Figure 2&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:28115f29-7bb9-4b21-bab4-fddb0c5624d1" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;[MetadataTypeAttribute(typeof(Employee.EmployeeMetadata))]
[MultiColumnSearch(
    "LastName", 
    "FirstName", 
    "Address", 
    "City", 
    "Country")]
public partial class Employee
{
    internal sealed class EmployeeMetadata
    {
        //...
    }
}

[MetadataTypeAttribute(typeof(Order.OrderMetadata))]
[MultiColumnSearch(
    "Employee.LastName", 
    "Employee.FirstName", 
    "Customer.CompanyName", 
    "Customer.ContactName", 
    "Shipper.CompanyName")]
public partial class Order
{
    internal sealed class OrderMetadata
    {
        //...
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 2 – sample metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="http://lh3.ggpht.com/_UUHjb9DZhJM/TS5BaZXnnII/AAAAAAAAA8E/XYTnfH1gyWQ/s1600-h/Cross%20Entity%20Search%5B4%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Cross Entity Search" border="0" alt="Cross Entity Search" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TS5BbLAgZVI/AAAAAAAAA8I/JQW17gOWznA/Cross%20Entity%20Search_thumb%5B2%5D.png?imgmax=800" width="706" height="247" /&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2 – cross entity search&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;Adding UI Mark-Up&lt;/h4&gt;

&lt;p&gt;I have added the multi column search UI in between the validators and the QueryableFilterRepeater see &lt;strong&gt;Listing 3&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:9738cb06-fbda-44b4-a4b7-0df680c1d5be" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;asp:DynamicValidator runat="server" ID="GridViewValidator" ControlToValidate="GridView1"
    Display="None" CssClass="DDValidator" /&amp;gt;

&amp;lt;fieldset id="MultiSearchFieldSet" class="DD" runat="server" visible="false"&amp;gt;
    &amp;lt;legend&amp;gt;Full Text Search&amp;lt;/legend&amp;gt;
    &amp;lt;asp:TextBox ID="txbMultiColumnSearch" CssClass="DDTextBox" runat="server" /&amp;gt;
    &amp;lt;asp:Button ID="btnMultiColumnSearchSubmit" CssClass="DDControl" runat="server" Text="Search"
        OnClick="btnMultiColumnSearch_Click" /&amp;gt;
    &amp;lt;asp:Button ID="btnMultiColumnSearchClear" CssClass="DDControl" runat="server" Text="Clear"
        OnClick="btnMultiColumnSearch_Click" /&amp;gt;
&amp;lt;/fieldset&amp;gt;
&amp;lt;br /&amp;gt;

&amp;lt;asp:QueryableFilterRepeater runat="server" ID="FilterRepeater"&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 3 – Multi Column Search UI&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;Code to wire up the UI and QueryExtender&lt;/h4&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:fb5c20e3-dc28-4ad8-8dcf-088828d72230" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;/// &amp;lt;summary&amp;gt;
/// Setups the multi column search.
/// &amp;lt;/summary&amp;gt;
private void SetupMultiColumnSearch()
{
    // get multi column search attribute
    var multiColumnSearch = table.GetAttribute&amp;lt;MultiColumnSearchAttribute&amp;gt;();

    if (multiColumnSearch != null)
    {
        var searchExpression = new SearchExpression()
            {
                DataFields = multiColumnSearch.Columns.ToCsvString(),
                SearchType = SearchType.Contains
            };
        
        // create control parameter
        var controlParameter = new ControlParameter() { ControlID = txbMultiColumnSearch.ID };
        
        // add control parameter to search expression
        searchExpression.Parameters.Add(controlParameter);

        // set context
        searchExpression.SetContext(GridQueryExtender, Context, GridDataSource);

        // add search expression to query extender
        GridQueryExtender.Expressions.Add(searchExpression);

        // make multicolumn search field set visible
        MultiSearchFieldSet.Visible = true;
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 5 – SetupMultiColumnSearch method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Listing 5&lt;/strong&gt; (which is called from the Page_Init method) we get the attribute and the SearchExpression the if both are not null we add the fields to the SearchExpressions DataFileds property, then we make the whole thing visible. 

  &lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;Much thanks to &lt;a href="http://blog.davidebbo.com/"&gt;David Ebbo&lt;/a&gt; who sorted out the issue I had had with adding the search expression in code rather than declaratively. &lt;/div&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:43cc61ef-de07-48f2-b2e2-25a0e6ce302e" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void btnMultiColumnSearch_Click(object sender, EventArgs e)
{
    var button = (Button)sender;
    if (button.ID == btnMultiColumnSearchClear.ID)
        txbMultiColumnSearch.Text = String.Empty;
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 6 – button event&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And lastly we need an event to fire when the clear button is fired. &lt;/p&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;I have both buttons wired-up to this handler as I also add session history here so that when you search on something and go to another page when you return you get the same search, but I also want it cleared if I click the clear button.&lt;/div&gt;

&lt;h4&gt;Download&lt;/h4&gt;
&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-96845e7b0fac1eed.office.live.com/embedicon.aspx/Public/MultiColumnSearch.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-1813432532438792940?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/O5vugO8Fq1WIztuU7bxm2CpzmSc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/O5vugO8Fq1WIztuU7bxm2CpzmSc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/O5vugO8Fq1WIztuU7bxm2CpzmSc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/O5vugO8Fq1WIztuU7bxm2CpzmSc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/LOsofPU2Fzg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/1813432532438792940/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=1813432532438792940&amp;isPopup=true" title="24 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/1813432532438792940?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/1813432532438792940?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/LOsofPU2Fzg/adding-multi-column-search-to-default.html" title="Adding a Multi-Column Search to the Default List page in Dynamic Data (UPDATED)" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_UUHjb9DZhJM/TS5BaA9sgBI/AAAAAAAAA8A/3cR6dDWXav0/s72-c/MultiColumnSearch_thumb%5B3%5D.png?imgmax=800" height="72" width="72" /><thr:total>24</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2011/01/adding-multi-column-search-to-default.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QNRnwzcSp7ImA9Wx9RFU0.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-6746854902610109773</id><published>2010-12-08T13:08:00.001Z</published><updated>2010-12-16T12:09:57.289Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-16T12:09:57.289Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".Net 4.0" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="History" /><category scheme="http://www.blogger.com/atom/ns#" term="Filters" /><title>Filter History for Dynamic Data 4</title><content type="html">&lt;p&gt;I did a &lt;a href="http://csharpbits.notaclue.net/2009/02/ajax-history-in-dynamic-data-website.html"&gt;AJAX History in a Dynamic Data Website&lt;/a&gt; article back in February 2009 to make filter respect the back button in the browser, this however was not enough for my customers they wanted the filter to be remembered even when they came back to the page without using the back button.&lt;/p&gt;  &lt;p&gt;So I decided to store the filter info in Session state for this sample sample (but you could also use a database I have where the client wanted the filters to be remembered across sessions and by user).&lt;/p&gt;  &lt;p&gt;I’m adding this extension to the previous sample from &lt;a href="http://csharpbits.notaclue.net/2010/11/five-cool-filters-for-dynamic-data-4.html"&gt;Five Cool Filters for Dynamic Data 4&lt;/a&gt; (which now has a couple more filters added) to give history across all the filters.&lt;/p&gt;  &lt;h4&gt;Extension Methods&lt;/h4&gt;  &lt;p&gt;So to the code there are two extension methods for this sample AddFilterValueToSession which you can guess adds a filters current value to session and GetFilterValuesFromSession which retrieves an Dictionary of values for the specified table.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:5f098a54-7fb9-44a0-add8-6547b385da25" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;/// &amp;lt;summary&amp;gt;
/// Adds the filters current value to the session.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="page"&amp;gt;The page.&amp;lt;/param&amp;gt;
/// &amp;lt;param name="column"&amp;gt;The column.&amp;lt;/param&amp;gt;
/// &amp;lt;param name="value"&amp;gt;The value.&amp;lt;/param&amp;gt;
public static void AddFilterValueToSession(this Page page, MetaColumn column, Object value)
{
    Dictionary&amp;lt;String, Object&amp;gt; filterValues;
    var objectName = column.Table.DataContextPropertyName;

    // get correct column name 
    var columnName = column.Name;
    if (column is MetaForeignKeyColumn)
        columnName = ((MetaForeignKeyColumn)column).ForeignKeyNames.ToCommaSeparatedString();

    // check to see if we already have a session object
    if (page.Session[objectName] != null)
        filterValues = (Dictionary&amp;lt;String, Object&amp;gt;)page.Session[objectName];
    else
        filterValues = new Dictionary&amp;lt;String, Object&amp;gt;();

    // add new filter value to session object
    if (filterValues.Keys.Contains(columnName))
        filterValues[columnName] = value;
    else
        filterValues.Add(columnName, value);

    // add back to session
    if (page.Session[objectName] != null)
        page.Session[objectName] = filterValues;
    else
        page.Session.Add(objectName, filterValues);
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – AddFilterValueToSession&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you follow the code and comments you will see that first we try to get the session object for this table from session and if it is not there we simply create one. Then we add/update the value for this column and finally save back to session.&lt;/p&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;that &lt;strong&gt;Listing 1&lt;/strong&gt; uses an extension method ToCommaSeperatedString() this just simplifies the code for us by removing reusable code. &lt;/div&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #f0d0f0; margin: 4px; padding-left: 4px; padding-right: 4px; color: #800080; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Updated: &lt;/strong&gt;As ValZ posted in the comments I have updated the GetFilterValuesFromSession extension method to make sure any links from other List pages are honoured, for instance if you go to the Suppliers page and click on View Products link but already have a filter value that will now be honoured. I’ve also used IDictionary so we don’t have to cast the default values that are passed in.&lt;/div&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:fa21218e-239a-4400-bfd3-d9b3ed51e5c5" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;/// &amp;lt;summary&amp;gt;
/// Gets the filter values from session.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="page"&amp;gt;The page.&amp;lt;/param&amp;gt;
/// &amp;lt;param name="table"&amp;gt;The table.&amp;lt;/param&amp;gt;
/// &amp;lt;param name="defaultValues"&amp;gt;The default values.&amp;lt;/param&amp;gt;
/// &amp;lt;returns&amp;gt;An IDictionary of filter values from the session.&amp;lt;/returns&amp;gt;
public static IDictionary&amp;lt;String, Object&amp;gt; GetFilterValuesFromSession(this Page page, 
    MetaTable table, 
    IDictionary&amp;lt;String, Object&amp;gt; defaultValues)
{
    var queryString = new StringBuilder();
    var objectName = table.DataContextPropertyName;
    if (page.Session[objectName] != null)
    {
        var sessionFilterValues = new Dictionary&amp;lt;String, Object&amp;gt;((Dictionary&amp;lt;String, Object&amp;gt;)page.Session[objectName]);
        foreach (string key in defaultValues.Keys)
        {
            if (!sessionFilterValues.Keys.Contains(key) || sessionFilterValues[key] == null)
                sessionFilterValues.Add(key, defaultValues[key]);
            else
                sessionFilterValues[key] = defaultValues[key];
        }
        var t = (Dictionary&amp;lt;String, Object&amp;gt;)page.Session[objectName];
        return sessionFilterValues;
    }
    else
        return defaultValues;
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 2 – GetFilterValuesFromSession&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Listing 2&lt;/strong&gt; we simply get the Dictionary object back from session and then return it.&lt;/p&gt;

&lt;h4&gt;Applying to the Filters&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Listing 3&lt;/strong&gt; is a for the ForeignKey filter, here call the AddFilterValueToSession extension method passing in the Column and value from the DropdownList.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:9a4c4615-a08f-48bf-afcf-8eff8babfd9e" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
    OnFilterChanged();
    Page.AddFilterValueToSession(Column, DropDownList1.SelectedValue);
}&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Listing 3 – ForeignKey filter&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every filter in that sample has this applied and there are several different examples in there.&lt;/p&gt;

&lt;h4&gt;Extracting the Filter Values&lt;/h4&gt;

&lt;p&gt;Now all we need is to get the values and pass them back to the filters each time we arrive at a List page. In &lt;strong&gt;Listing 4&lt;/strong&gt; I have updated the Page_Init method,&amp;#160; I first attempt to get the filter values from session if none are found I fall back to default List page behaviour.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d7210b11-c2b0-463f-8889-5f5882aeb7c8" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void Page_Init(object sender, EventArgs e)
{
    table = DynamicDataRouteHandler.GetRequestMetaTable(Context);

    var defaultValues = Page.GetFilterValuesFromSession(table, table.GetColumnValuesFromRoute(Context));
    GridView1.SetMetaTable(table, defaultValues);

    GridDataSource.EntityTypeFilter = table.EntityType.Name;
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 4 – Updating the List page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now if we switch back to the ForeignKey filter and the Page_Init method &lt;strong&gt;Listing 5&lt;/strong&gt; you will see that I have not had to change anything here, because we are adding the default values in the List page they will arrive in each filter via the DefaultValue property.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:dc6eb2e4-8698-4c54-8bba-6cc87b94736c" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void Page_Init(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        if (!Column.IsRequired)
        {
            DropDownList1.Items.Add(new ListItem("[Not Set]", NullValueString));
        }
        PopulateListControl(DropDownList1);

        // Set the initial value if there is one
        string initialValue = DefaultValue;
        if (!String.IsNullOrEmpty(initialValue))
        {
            DropDownList1.SelectedValue = initialValue;
            // optional add auto filters to history
            Page.AddFilterValueToSession(Column, initialValue);
        }
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 5 – updating the filter&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #f0d0f0; margin: 4px; padding-left: 4px; padding-right: 4px; color: #800080; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Updated: &lt;/strong&gt;I’ve also added a optional Page.AddFilterValueToSession(Column, initialValue); to each filter so that filter values passed in in query string can be added to history, &lt;strong&gt;NOTE:&lt;/strong&gt; &lt;strong&gt;I’ve only added this to the ForeignKey filter so it’s easy to remove if not required.&lt;/strong&gt;&lt;/div&gt;

&lt;p&gt;I’ll show one complex example of setting up the values in a filter, we will look at me DateRange filter for this. First look at &lt;strong&gt;Listing 6&lt;/strong&gt; here I am concatenating both values together separated by ‘|’.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:ba75de3f-ad08-4a68-9f73-5b9601be22f5" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void btnRangeButton_Click(object sender, EventArgs e)
{
    var button = (Button)sender;
    if (button.ID == btnClear.ID)
    {
        txbDateFrom.Text = String.Empty;
        txbDateTo.Text = String.Empty;
    }
    OnFilterChanged();
    Page.AddFilterValueToSession(Column, String.Format("{0}|{1}", txbDateFrom.Text, txbDateTo.Text));
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 6 – DateRange button click event&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then if you look at the DateRange filters Page_Init method all need to do is check I have a value, reveres the concatenation and put the values in the correct textboxes.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:f97ee9dc-072e-4e59-9224-18e58cff011b" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void Page_Init(object sender, EventArgs e)
{
    // set correct date time format
    txbDateFrom_CalendarExtender.Format = DATE_FORMAT;
    txbDateTo_CalendarExtender.Format = DATE_FORMAT;

    if (!Column.ColumnType.Equals(typeof(DateTime)))
        throw new InvalidOperationException(String.Format("A date range filter was loaded for column '{0}' but the column has an incompatible type '{1}'.",
            Column.Name, Column.ColumnType));

    if (DefaultValue != null)
    {
        var values = DefaultValue.Split(new char[] { '|' });
        if (values.Length == 2)
        {
            txbDateFrom.Text = values[0];
            txbDateTo.Text = values[1];
        }
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 7 – DateRange Page_Init method&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #f0d0f0; margin: 4px; padding-left: 4px; padding-right: 4px; color: #800080; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Updated: &lt;/strong&gt;Add clear filters button to clear all filters for a table.&lt;/div&gt;

&lt;h4&gt;Clear Filters&lt;/h4&gt;

&lt;p&gt;Last we add a button to clear the filters&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:43291070-8dff-478b-b2ce-d4dc34982e45" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: python;"&gt;&amp;lt;div class="DD"&amp;gt;
    &amp;lt;asp:ValidationSummary ID="ValidationSummary1" runat="server" EnableClientScript="true"
        HeaderText="List of validation errors" CssClass="DDValidator" /&amp;gt;
    &amp;lt;asp:DynamicValidator runat="server" ID="GridViewValidator" ControlToValidate="GridView1"
        Display="None" CssClass="DDValidator" /&amp;gt;
    &amp;lt;asp:QueryableFilterRepeater runat="server" ID="FilterRepeater"&amp;gt;
        &amp;lt;ItemTemplate&amp;gt;
            &amp;lt;asp:Label runat="server" Text='&amp;lt;%# Eval("DisplayName") %&amp;gt;' OnPreRender="Label_PreRender" /&amp;gt;
            &amp;lt;asp:DynamicFilter runat="server" ID="DynamicFilter" OnFilterChanged="DynamicFilter_FilterChanged" /&amp;gt;
            &amp;lt;br /&amp;gt;
        &amp;lt;/ItemTemplate&amp;gt;
    &amp;lt;/asp:QueryableFilterRepeater&amp;gt;
    &amp;lt;asp:Button 
        ID="ClearFiltersButton" 
        runat="server" 
        Text="Clear Filters" 
        CssClass="DDControl"
        OnClick="ClearFiltersButton_Click" /&amp;gt;
    &amp;lt;br /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 8 – Clear filters button&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and in the post back of the button&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d3b6a80a-7478-48d9-888f-7c038948142d" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void ClearFiltersButton_Click(object sender, EventArgs e)
{
    Page.ClearTableFilters(table);
    Response.Redirect(table.ListActionPath);
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 9 – Clears filters button method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and lastly we need the method the clears the filters for us,&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:a5727fb5-3006-4c9b-9686-87a2c47d2d46" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public static void ClearTableFilters(this Page page, MetaTable table)
{
    var objectName = table.DataContextPropertyName;

    if (page.Session[objectName] != null)
        page.Session[objectName] = null;
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 10 – Clear filters extension method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lastly we will need to hide the button when there are no filters.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:1e6da780-1a8e-490d-b9be-8b9236df454d" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected override void OnPreRenderComplete(EventArgs e)
{
    RouteValueDictionary routeValues = new RouteValueDictionary(GridView1.GetDefaultValues());
    InsertHyperLink.NavigateUrl = table.GetActionPath(PageAction.Insert, routeValues);
    if (FilterRepeater.Controls.Count == 0)
        ClearFiltersButton.Visible = false;
    base.OnPreRenderComplete(e);
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 11 – hiding the clear filters button&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So then all done then.&lt;/p&gt;

&lt;h4&gt;Download&lt;/h4&gt;
&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-96845e7b0fac1eed.office.live.com/embedicon.aspx/Public/CustomFiltersWithFilterHistory%202010-12-15.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-6746854902610109773?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/X2xg2XvHRp5jEVrxeHWxYLHN8v0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/X2xg2XvHRp5jEVrxeHWxYLHN8v0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/X2xg2XvHRp5jEVrxeHWxYLHN8v0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/X2xg2XvHRp5jEVrxeHWxYLHN8v0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/MuaYegIKufw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/6746854902610109773/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=6746854902610109773&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6746854902610109773?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/6746854902610109773?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/MuaYegIKufw/filter-history-for-dynamic-data-4.html" title="Filter History for Dynamic Data 4" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><thr:total>6</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/12/filter-history-for-dynamic-data-4.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIAQ3g8cSp7ImA9Wx9TGEg.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-422892713307885809</id><published>2010-11-26T21:42:00.001Z</published><updated>2010-11-27T11:15:42.679Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-27T11:15:42.679Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Advertisement" /><title>BLACK FRIDAY/CYBER MONDAY DEAL:</title><content type="html">&lt;p&gt;Note&amp;#160; I don’t normally post adds for products but this is really easy to create icons I’m always creating favicons for my sites and it make the task real easy.&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://www.axialis.com/iconworkshop/index.html" target="_blank"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="sale" border="0" alt="sale" src="http://lh4.ggpht.com/_UUHjb9DZhJM/TPAprX5Oy3I/AAAAAAAAA7Q/XSjhvEzEfpE/sale%5B4%5D.jpg?imgmax=800" width="200" height="143" /&gt;&lt;/a&gt; &lt;/h4&gt;  &lt;p&gt;All Axialis products are available at 50 percent Off. Starting Black Friday, this offer ends Nov 30. This is for 5 days, and 5 days only. Half price but full service! You get the same Axialis advantages: professionally-designed products, LIFETIME LICENCE! (never pay for future updates), access to thousands of ready-to-use image object packs, and more...&lt;/p&gt;  &lt;p&gt;&lt;em&gt;So don't miss this opportunity! ACT NOW and get 50 percent off your total order!&lt;/em&gt;&lt;/p&gt;  &lt;h4&gt;IconWorkshop 6.53 Released:&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://www.axialis.com/iconworkshop/" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="IconWorkshop" border="0" alt="IconWorkshop" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TPDoXUXh9VI/AAAAAAAAA7Y/cmxdrZ-zIwY/iw%5B1%5D.jpg?imgmax=800" width="120" height="115" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This minor release includes various bug fixes and enhancements:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Compatible with Visual Studio 2010: The installer detects and add the IconWorkshop add-in in Visual Studio 2010. &lt;/li&gt;    &lt;li&gt;Ability to create icons for iPhone 4: This new version includes new image presets to create those icons. &lt;/li&gt;    &lt;li&gt;New Object Packs: Two new object packs are provided to create iPhone icons (Applications and Tab Bar Icons). &lt;/li&gt;    &lt;li&gt;Various other enhancements and bug fixes. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Registered users can freely upgrade to this latest version using the built-in update feature.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-422892713307885809?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/q94gj7goL6fJ_YUSChf7NJ9EHYk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q94gj7goL6fJ_YUSChf7NJ9EHYk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/q94gj7goL6fJ_YUSChf7NJ9EHYk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q94gj7goL6fJ_YUSChf7NJ9EHYk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/lr2ASBzRO00" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/422892713307885809/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=422892713307885809&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/422892713307885809?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/422892713307885809?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/lr2ASBzRO00/black-fridaycyber-monday-deal.html" title="BLACK FRIDAY/CYBER MONDAY DEAL:" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_UUHjb9DZhJM/TPAprX5Oy3I/AAAAAAAAA7Q/XSjhvEzEfpE/s72-c/sale%5B4%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/11/black-fridaycyber-monday-deal.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYCRHs6fyp7ImA9Wx9TE0k.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-4519571833071616769</id><published>2010-11-21T12:17:00.001Z</published><updated>2010-11-21T12:22:45.517Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-21T12:22:45.517Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="Filters" /><title>Five Cool Filters for Dynamic Data 4</title><content type="html">&lt;p&gt;Starting with the Range Autocomplete, Range &amp;amp; MultiForeignKey Filters from the old &lt;a href="http://cid-96845e7b0fac1eed.office.live.com/self.aspx/Public/DynamicDataPreview4Refresh.zip"&gt;Dynamic Data Preview 4 Refresh&lt;/a&gt;, I have also added five of my filters:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;DateRange &lt;/li&gt;    &lt;li&gt;StartsWith &lt;/li&gt;    &lt;li&gt;EndsWith &lt;/li&gt;    &lt;li&gt;Contains &lt;/li&gt;    &lt;li&gt;Where &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I won’t go into much detail here as Oleg Sych has done this great series on DD4 filters, that pretty much explains it all for you.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.olegsych.com/2010/07/understanding-aspnet-dynamic-data-filter-templates/"&gt;Understanding ASP.NET Dynamic Data: Filter Templates&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.olegsych.com/2010/08/extending-aspnet-dynamic-data-filtering-with-joins/"&gt;Extending ASP.NET Dynamic Data: Filtering with Joins&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.olegsych.com/2010/09/understanding-aspnet-dynamic-data-entity-templates/"&gt;Understanding ASP.NET Dynamic Data: Entity Templates&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I am using the &lt;a href="http://ajaxcontroltoolkit.codeplex.com/"&gt;Ajax Control Toolkit&lt;/a&gt; for the date picker in the DateRange filter but other than that it’s not much different form the Range filter from the &lt;a href="http://cid-96845e7b0fac1eed.office.live.com/self.aspx/Public/DynamicDataPreview4Refresh.zip"&gt;Dynamic Data Preview 4 Refresh&lt;/a&gt; sample. &lt;/p&gt;  &lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffdddd; margin: 4px; padding-left: 4px; padding-right: 4px; color: #ff0000; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;!Important: &lt;/strong&gt;One thing I would like to point out is that both Entity Framework and Linq to SQL have a small but important issue. This issue is the the “Contains” Expression used in the above filter of the same name is actually expressed as the “Like ‘%{0}%’” and so you &lt;strong&gt;DO NOT &lt;/strong&gt;get full text search using “Contains”.     &lt;br /&gt;    &lt;br /&gt;“Contains” when it was introduced in SQL Server 7 was given a big build up and to be omitted in EF and L2S is a big let down.&lt;/div&gt;  &lt;p&gt;Some examples:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_UUHjb9DZhJM/TOkN66dhboI/AAAAAAAAA7A/581ZGYyhsFo/s1600-h/Other%20Filters%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Other Filters" border="0" alt="Other Filters" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TOkN7pHfIFI/AAAAAAAAA7E/0uihL1muXIQ/Other%20Filters_thumb%5B2%5D.png?imgmax=800" width="684" height="330" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 1 – DateRange, StartsWith, EndsWith, Contains, Where and AutoComplete filters&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_UUHjb9DZhJM/TOkN8JXzooI/AAAAAAAAA7I/iLidjC8HAKI/s1600-h/Range%20and%20Multi%20Select%5B10%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Range and Multi Select Filters" border="0" alt="Range and Multi Select Filters" src="http://lh5.ggpht.com/_UUHjb9DZhJM/TOkN8nRxpzI/AAAAAAAAA7M/mmUu4VdiEQY/Range%20and%20Multi%20Select_thumb%5B6%5D.png?imgmax=800" width="647" height="249" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 2 – Range and Multi Select Filters&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I just thought that these filters would be useful for your tool boxes. &lt;/p&gt;  &lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffdddd; margin: 4px; padding-left: 4px; padding-right: 4px; color: #ff0000; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;!Important: &lt;/strong&gt;I can’t take credit for all the Expression helpers most come from the above mentioned Preview 4 that is no longer on the ASP.Net &lt;a href="http://aspnet.codeplex.com" target="_blank"&gt;Codeplex&lt;/a&gt; site.&lt;/div&gt;  &lt;h5&gt;Download&lt;/h5&gt;  &lt;p&gt;&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-96845e7b0fac1eed.office.live.com/embedicon.aspx/Public/CustomFilters.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;  &lt;p&gt;Note I’ve included my five filters and the three filters from the Preview.&lt;/p&gt;  &lt;p&gt;As always happy coding.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-4519571833071616769?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wnQeNYibrz4LyuAtPrrJnOoEJU8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wnQeNYibrz4LyuAtPrrJnOoEJU8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wnQeNYibrz4LyuAtPrrJnOoEJU8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wnQeNYibrz4LyuAtPrrJnOoEJU8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/i4UtIWLzQ2M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/4519571833071616769/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=4519571833071616769&amp;isPopup=true" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/4519571833071616769?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/4519571833071616769?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/i4UtIWLzQ2M/five-cool-filters-for-dynamic-data-4.html" title="Five Cool Filters for Dynamic Data 4" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_UUHjb9DZhJM/TOkN7pHfIFI/AAAAAAAAA7E/0uihL1muXIQ/s72-c/Other%20Filters_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>10</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/11/five-cool-filters-for-dynamic-data-4.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQnszeip7ImA9Wx5aF04.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-7994847342021313852</id><published>2010-11-14T12:09:00.001Z</published><updated>2010-11-14T12:18:13.582Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-14T12:18:13.582Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="white-space: nowrap" /><category scheme="http://www.blogger.com/atom/ns#" term="IAutoFieldGenerator" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><title>Making the Text in the DynamicData List Pages GridView Wrap.</title><content type="html">&lt;p&gt;Why won’t the text in my Dynamic Data List page GridView wrap? This is answered here and in this post on the &lt;a href="http://forums.asp.net/1145.aspx"&gt;ASP.NET Dynamic Data Forum&lt;/a&gt; here &lt;a title="http://forums.asp.net/p/1573073/4167960.aspx#4163602" href="http://forums.asp.net/p/1573073/4167960.aspx#4163602"&gt;Re: DynamicField within GridView truncating data&lt;/a&gt; where &lt;a href="http://forums.asp.net/members/yuipcheng.aspx"&gt;Yuipcheng&lt;/a&gt; asks; &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“I commented out the code to truncate the FieldValueString, but the rendered text doesn't wrap since the td tag has (style=&amp;quot;white-space: nowrap;&amp;quot;)”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I answered &lt;a href="http://forums.asp.net/p/1573073/4167960.aspx#4167960"&gt;here&lt;/a&gt; but I thought I would document it here also.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://lh3.ggpht.com/_UUHjb9DZhJM/TN_Tfjpx4SI/AAAAAAAAA6k/j6Og4HZKPYg/s1600-h/14-11-2010%2011-54-57.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Before" border="0" alt="Before" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TN_RcGBTHnI/AAAAAAAAA6o/dot24bZqacA/14-11-2010%2011-54-57_thumb.png?imgmax=800" width="240" height="229" /&gt;&lt;/a&gt; &lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;a href="http://lh6.ggpht.com/_UUHjb9DZhJM/TN_Rc6mrpVI/AAAAAAAAA6s/xUdzD9pC2js/s1600-h/14-11-2010%2011-56-47.png" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="After" border="0" alt="After" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TN_Rdve5lpI/AAAAAAAAA60/kZG1szo7V7E/14-11-2010%2011-56-47_thumb.png?imgmax=800" width="240" height="229" /&gt;&lt;/a&gt; &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;strong&gt;After&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;So you may be asking Dynamic Data 1 didn’t do this, so why does Dynamic Data 4 do it?&lt;/p&gt;  &lt;p&gt;The answer it has to do with the validation “*”&amp;#160; showing up next to the field in Edit mode and appears to have just gotten into the GridView as by default we don't do inline editing.&lt;/p&gt;  &lt;p&gt;The solution from David Fowler is to create an class and inherit from System.Web.DynamicData.DefaultAutoFieldGenerator and then override the CreateField method, so here it is:&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:33e7290b-5033-46e6-9fd5-0dae31e32ed4" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;/// &amp;lt;summary&amp;gt;
/// Add the option to the Default Auto Field Generator 
/// to not add the (Style="white-space: nowrap;") to each field.
/// &amp;lt;/summary&amp;gt;
public class AdvancedAutoFieldGenerator : DefaultAutoFieldGenerator
{
    private Boolean _noWrap;

    /// &amp;lt;summary&amp;gt;
    /// Initializes a new instance of the 
    /// &amp;lt;see cref="AdvancedAutoFieldGenerator"/&amp;gt; class.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="table"&amp;gt;The table.&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="noWrap"&amp;gt;if set to &amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; 
    /// the (Style="white-space: nowrap;") is added 
    /// to each field.&amp;lt;/param&amp;gt;
    public AdvancedAutoFieldGenerator(MetaTable table, Boolean noWrap)
        : base(table)
    {
        _noWrap = noWrap;
    }

    protected override DynamicField CreateField(
        MetaColumn column, 
        ContainerType containerType, 
        DataBoundControlMode mode)
    {
        DynamicField field = base.CreateField(column, containerType, mode)

        // override the wrap behavior
        // with the noWrap parameter
        field.ItemStyle.Wrap = !_noWrap;
        return field;
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – Advanced Field Generator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and we apply it in the Page_Load event of the List page (or you own custom page)&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:83537bb8-9190-45d3-849b-fef428c9826d" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;// apply custom auto field generator
GridView1.ColumnsGenerator = new AdvancedAutoFieldGenerator(table, false);&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will then remove the unwanted style,&lt;/p&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;If you still want this on some pages I have not hard coded it, so you can change it in code where you want to. &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-7994847342021313852?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KRpwuWSBKdPXhZ6XJmoZ_0tCwOE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KRpwuWSBKdPXhZ6XJmoZ_0tCwOE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KRpwuWSBKdPXhZ6XJmoZ_0tCwOE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KRpwuWSBKdPXhZ6XJmoZ_0tCwOE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/hh3c4ZugdJA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/7994847342021313852/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=7994847342021313852&amp;isPopup=true" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7994847342021313852?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7994847342021313852?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/hh3c4ZugdJA/making-text-in-dynamicdata-list-pages.html" title="Making the Text in the DynamicData List Pages GridView Wrap." /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_UUHjb9DZhJM/TN_RcGBTHnI/AAAAAAAAA6o/dot24bZqacA/s72-c/14-11-2010%2011-54-57_thumb.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/11/making-text-in-dynamicdata-list-pages.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcHRXc-fyp7ImA9Wx5bFUg.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-5049212495141900033</id><published>2010-08-17T12:32:00.001+01:00</published><updated>2010-10-31T19:23:54.957Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-31T19:23:54.957Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".Net 4.0" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="Custom Field Templates" /><title>A Boolean Date Time Field Template for Dynamic Data 4</title><content type="html">&lt;p&gt;Here’s the idea, you want to mark a status of a row with a checkbox and you also need the date time setting one the row to record when the status changed. You normally end up with two fields in your table for this. I decided that in many cases I would only need the date time i.e. if the date time is set then the status has changed is null then not, e.g. to set Order Status to complete set the Complete column to DateTime.Now.&lt;/p&gt;  &lt;p&gt;Another reason you may want to use a checkbox to enter a date is to set the date without letting the user enter a custom date.&lt;/p&gt;  &lt;p&gt;This turned out to be a little more complicated than I first though and I needed to consult &lt;a href="http://blogs.msdn.com/b/davidebb/"&gt;David Ebbo&lt;/a&gt; at Microsoft to get the answer. First we’ll deal with the issue I came across that at first was a road block. This is the issue of setting the field to null when the user unchecks the check box. &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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:71f06a8e-0cc0-4a8e-bb39-280b87e3f2d9" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;%@ Control
    Language="C#" 
    CodeBehind="DateTimeBoolean_Edit.ascx.cs" 
    Inherits="CustomFieldTemplates.DateTimeBoolean_EditField" %&amp;gt;

&amp;lt;asp:CheckBox runat="server" ID="CheckBox1" /&amp;gt;
&amp;lt;asp:HiddenField ID="HiddenField1" runat="server" /&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – DateTimeBoolean_Edit.ascx&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So here in &lt;strong&gt;Listing 2 &lt;/strong&gt;we see the first ExtractValues attempt&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:02c8e18a-93b3-4de5-9fcf-415c736b7e73" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected override void ExtractValues(IOrderedDictionary dictionary)
{
    if (!CheckBox1.Checked)
    {
        // only set to null if unchecked
        dictionary[Column.Name] = String.Empty;
    }
    else if (String.IsNullOrEmpty(HiddenField1.Value))
    {
        // only set a value if there is no current value
        dictionary[Column.Name] = DateTime.Now;
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 2 – ExtractValues method v1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As you can see if the CheckBox1 is unchecked I set the return value to String.Empty this you would think would do the trick but it doesn't what happens is the value is retained. What confused the matter for me was is if I have a new row or a row with a null value and check it, it sets the value &lt;img alt="Surprise" src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/13.gif" /&gt;&lt;/p&gt;

&lt;p&gt;It turns out that the reason is that the ExtractValues method is called twice the first time when the field template is initialised and the second time when the updated value is returned. But if look at my logic it returns no value the first time the method is called, but a value is required for the system to know that it is to be set to null the second time it is called &lt;img alt="Big Grin" src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/4.gif" /&gt;&lt;/p&gt;

&lt;p&gt;So here the full code behind of the Edit template, you will see now that the hidden field is set in the OnDataBound event to make sure we return the correct value the first time ExtractValues is called.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:4aef40eb-bcbf-4155-8cb6-4814139760d6" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public partial class DateTimeBoolean_EditField : System.Web.DynamicData.FieldTemplateUserControl
{
    protected override void OnDataBinding(EventArgs e)
    {
        base.OnDataBinding(e);

        // keep current value
        HiddenField1.Value = FieldValueString;

        if (FieldValue != null)
            CheckBox1.Checked = true;
        else
            CheckBox1.Checked = false;
    }

    protected override void ExtractValues(IOrderedDictionary dictionary)
    {
        if (!CheckBox1.Checked)
        {
            // only set to null if unchecked
            dictionary[Column.Name] = String.Empty;
        }
        else if (String.IsNullOrEmpty(HiddenField1.Value))
        {
            // only set a value if there is no current value
            dictionary[Column.Name] = DateTime.Now;
        }
        //else
        //    dictionary[Column.Name] = ConvertEditedValue(HiddenField1.Value);
    }

    public override Control DataControl
    {
        get { return CheckBox1; }
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 3 – DateTimeBoolean_Edit.ascx.cs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And for completeness the read-only version of the field template.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:9e2d1a0d-e6ff-4f41-86aa-3c369339a116" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;%@ Control
    Language="C#" 
    CodeBehind="DateTimeBoolean.ascx.cs" 
    Inherits="CustomFieldTemplates.DateTimeBooleanField" %&amp;gt;

&amp;lt;asp:CheckBox ID="CheckBox1" runat="server" Enabled="false" /&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 4 – DateTimeBoolean.ascx&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:e5f3ed9c-08aa-4f27-9ba2-5446d606fa03" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public partial class DateTimeBooleanField : System.Web.DynamicData.FieldTemplateUserControl
{
    protected override void OnDataBinding(EventArgs e)
    {
        base.OnDataBinding(e);
        CheckBox1.Checked = !String.IsNullOrEmpty(FieldValueString);
        if (FieldValue != null)
            CheckBox1.ToolTip = FieldValueString;
    }

    public override Control DataControl
    {
        get { return CheckBox1; }
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 5 – DateTimeBoolean.ascx.cs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You may want to show a date time value instead of the checkbox if so you can just use a copy of the default read-only Date Time field template.&lt;/p&gt;

&lt;p&gt;And remember to add a UIHint to set the column to use the new field template&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;[&lt;span style="color: #2b91af"&gt;UIHint&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;DateTimeBoolean&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Nullable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt;&amp;gt; ShippedDate { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;/pre&gt;

&lt;p&gt;As always happy coding &lt;/p&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:51CF81A4-8F44-4a2c-8837-198C090B9994:107400f1-49f8-4d33-9a64-4b7d37bbcd3b" class="wlWriterEditableSmartContent"&gt;&lt;p&gt;&lt;img style="border-right: 2px; border-top: 2px; border-left: 2px; border-bottom: 2px" height="33" src="http://lh4.ggpht.com/_UUHjb9DZhJM/Sb5XWgVfjAI/AAAAAAAAAkw/SJ8l6FyyWdo/s72/HappyWizard%5B3%5D.png" width="19"&gt;&lt;/p&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-5049212495141900033?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-WALoIGo7lxfBVn7m8quGhyNQJI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-WALoIGo7lxfBVn7m8quGhyNQJI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-WALoIGo7lxfBVn7m8quGhyNQJI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-WALoIGo7lxfBVn7m8quGhyNQJI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/jlvy50A4ARM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/5049212495141900033/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=5049212495141900033&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/5049212495141900033?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/5049212495141900033?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/jlvy50A4ARM/boolean-date-time-field-template-for.html" title="A Boolean Date Time Field Template for Dynamic Data 4" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_UUHjb9DZhJM/Sb5XWgVfjAI/AAAAAAAAAkw/SJ8l6FyyWdo/s72-c/HappyWizard%5B3%5D.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/08/boolean-date-time-field-template-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQFQ3s4fip7ImA9Wx5TEE0.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-7464329344634111061</id><published>2010-07-24T17:11:00.001+01:00</published><updated>2010-07-24T21:11:52.536+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-24T21:11:52.536+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods" /><category scheme="http://www.blogger.com/atom/ns#" term="Row Highlighting" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="GridView" /><category scheme="http://www.blogger.com/atom/ns#" term="Attributes" /><title>Conditional Row Highlighting in Dynamic Data</title><content type="html">&lt;p&gt;There are occasions when you want to highlight a row in the GridView (I usually want this based on a Boolean field) so here’s what you do. &lt;/p&gt;  &lt;p&gt;First of all we need some way of telling the column to do this an I usually use an attribute see &lt;strong&gt;Listing 1&lt;/strong&gt; it have two properties one for the value when we want the CSS class to be applied, and the other the CSS class to apply.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:4a0ee509-a793-4757-bc95-4b9a677b3326" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class RowHighlightingAttribute : Attribute
{
    /// &amp;lt;summary&amp;gt;
    /// Initializes a new instance of the &amp;lt;see cref="RowHighlightingAttribute"/&amp;gt; class.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name="valueWhenTrue"&amp;gt;The value when true.&amp;lt;/param&amp;gt;
    /// &amp;lt;param name="cssClass"&amp;gt;The CSS class.&amp;lt;/param&amp;gt;
    public RowHighlightingAttribute(String valueWhenTrue, String cssClass)
    {
        ValueWhenTrue = valueWhenTrue;
        CssClass = cssClass;
    }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the value when true.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The value when true.&amp;lt;/value&amp;gt;
    public String ValueWhenTrue { get; set; }

    /// &amp;lt;summary&amp;gt;
    /// Gets or sets the CSS class.
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;value&amp;gt;The CSS class.&amp;lt;/value&amp;gt;
    public String CssClass { get; set; }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – RowHighlightingAttribute&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next we need a way of applying the CSS class based on the condition, see &lt;strong&gt;Listing 2&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:922a48e5-5aea-4b16-a6b8-edc14afc7f2d" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;/// &amp;lt;summary&amp;gt;
/// Highlights the row.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="fieldTemplate"&amp;gt;The field template.&amp;lt;/param&amp;gt;
public static void HighlightRow(this FieldTemplateUserControl fieldTemplate)
{
    // get the attribute
    var rowHighlighting = fieldTemplate.MetadataAttributes.GetAttribute&amp;lt;RowHighlightingAttribute&amp;gt;();
    // make sure the attribute is not null
    if (rowHighlighting != null)
    {
        // get the GridViewRow, note this will not
        // be present in a DetailsView.
        var parentRow = fieldTemplate.GetContainerControl&amp;lt;GridViewRow&amp;gt;();
        if (parentRow != null 
            &amp;amp;&amp;amp; rowHighlighting.ValueWhenTrue == fieldTemplate.FieldValueString)
        {
            // apply the CSS class appending if a class is already applied.
            if (String.IsNullOrWhiteSpace(parentRow.CssClass))
                parentRow.CssClass += " " + rowHighlighting.CssClass;
            else
                parentRow.CssClass = rowHighlighting.CssClass;
        }
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;strong&gt;&lt;/strong&gt;

&lt;p&gt;&lt;strong&gt;Listing 2 – HighlightRow extension method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now to add the extension method to a field template, we will apply it to the Boolean read-only field template.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:ce6072a7-c635-49c6-b66d-e8d0c3bd3e45" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected override void OnDataBinding(EventArgs e)
{
    base.OnDataBinding(e);

    object val = FieldValue;
    if (val != null)
        CheckBox1.Checked = (bool)val;

    // apply highlighting
    this.HighlightRow();
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 3 – Apply highlighting.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the sample I’ve also added it to the Text.ascx.cs field template.&lt;/p&gt;

&lt;p&gt;Adding some attributes&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_UUHjb9DZhJM/TEsQmq_6KTI/AAAAAAAAA30/6ClNjZgokLo/s1600-h/24-07-2010%2017-02-23%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Metadata applied" border="0" alt="Metadata applied" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TEsQnX8uc_I/AAAAAAAAA34/gBnRpnE7Xlk/24-07-2010%2017-02-23_thumb%5B2%5D.png?imgmax=800" width="537" height="568" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 1 - Metadata applied&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You could also us this technique on other values, but this will do for this sample.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_UUHjb9DZhJM/TEsQoDVmBcI/AAAAAAAAA38/Yn1Qj0oHWz8/s1600-h/24-07-2010%2016-56-57%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Row Highlighting applied" border="0" alt="Row Highlighting applied" src="http://lh5.ggpht.com/_UUHjb9DZhJM/TEsQojcP7xI/AAAAAAAAA4A/r_u87YdFZfk/24-07-2010%2016-56-57_thumb%5B2%5D.png?imgmax=800" width="640" height="266" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 2 – Row Highlighting applied.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So you can see with a little bit of work you can add conditional row level highlighting to Dynamic Data.&lt;/p&gt;

&lt;h4&gt;Download&lt;/h4&gt;
&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-96845e7b0fac1eed.office.live.com/embedicon.aspx/Public/ConditionalRowHighlighting.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-7464329344634111061?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/s6XEYyPWnC9QFri9ZqmhZmrizYE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s6XEYyPWnC9QFri9ZqmhZmrizYE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/s6XEYyPWnC9QFri9ZqmhZmrizYE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s6XEYyPWnC9QFri9ZqmhZmrizYE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/wJPa11w3vik" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/7464329344634111061/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=7464329344634111061&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7464329344634111061?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7464329344634111061?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/wJPa11w3vik/conditional-row-highlighting-in-dynamic.html" title="Conditional Row Highlighting in Dynamic Data" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_UUHjb9DZhJM/TEsQnX8uc_I/AAAAAAAAA34/gBnRpnE7Xlk/s72-c/24-07-2010%2017-02-23_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/07/conditional-row-highlighting-in-dynamic.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcCQ3w6fip7ImA9Wx5TEk8.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-502928979862182479</id><published>2010-07-24T16:30:00.001+01:00</published><updated>2010-07-27T09:41:02.216+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-27T09:41:02.216+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="External Class Library" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="Entity Framework" /><title>Using Entity Framework from a different DLL in Dynamic Data</title><content type="html">&lt;p&gt;I just thought I should document what we learned in this thread here &lt;a href="http://forums.asp.net/t/1580276.aspx"&gt;Entity Framework: Entity Model in a separated DLL&lt;/a&gt; first of all it is easy to do in Dynamic Data 4 and needs a fix on each page for Dynamic Data 1 (this version that shipped with Visual Studio 2008 SP1 and .Net 3.5 SP1) &lt;a title="http://blogs.msdn.com/b/rickandy/archive/2008/12/09/explicit-connection-string-for-ef.aspx" href="http://blogs.msdn.com/b/rickandy/archive/2008/12/09/explicit-connection-string-for-ef.aspx"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffffcc; margin: 4px; padding-left: 4px; padding-right: 4px; color: #666666; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Note: &lt;/strong&gt;see also Rick Andersons blog post here &lt;a title="http://blogs.msdn.com/b/rickandy/archive/2008/12/09/explicit-connection-string-for-ef.aspx" href="http://blogs.msdn.com/b/rickandy/archive/2008/12/09/explicit-connection-string-for-ef.aspx"&gt;Explicit connection string for EF and L2S&lt;/a&gt; &lt;/div&gt;  &lt;h4&gt;Adding Model from DLL or Class Library&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_UUHjb9DZhJM/TEsHAlYf5DI/AAAAAAAAA3s/J_ploVVjlFc/s1600-h/24-07-2010%2015-46-39%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Sample Project" border="0" alt="Sample Project" src="http://lh4.ggpht.com/_UUHjb9DZhJM/TEsHA1pRtTI/AAAAAAAAA3w/5A5YDm-FHLA/24-07-2010%2015-46-39_thumb%5B2%5D.png?imgmax=800" width="261" height="371" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 1 – sample project with Model in Class Library&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;To use the Northwind Model in our project we need to get a new instance of the Northwind context, to do this we could add the code to instantiate it in the Glabal.asax.cs file. But for me the object of having it in an external class library/DLL is to keep it reusable, so I had the idea of building the connection string in the external class library rather than locally. We add &lt;strong&gt;Listing 1&lt;/strong&gt; to the class library, as a partial class of the NorthwindEntities class, pass-in the server name (we could pass-in more but the server name will do here).&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:958464bf-64f5-4116-ae4a-328d6f6232fb" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public partial class NorthwindEntities
{
    /// &amp;lt;summary&amp;gt;
    /// Gets a new NorthwindEntities object.
    /// &amp;lt;/summary&amp;gt;
    public static ObjectContext GetContext(String server, String database)
    {
        EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
        entityBuilder.Provider = "System.Data.SqlClient";
        entityBuilder.ProviderConnectionString =
            String.Format("server={0};database={1};Integrated Security=SSPI;MultipleActiveResultSets=True",
            server,
            database);
        entityBuilder.Metadata = @"res://*";
        var objContext = new NorthwindContext.NorthwindEntities(entityBuilder.ToString());

        return objContext;
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;strong&gt;&lt;/strong&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – GetContext helper method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So now all we need to add this to our Dynamic Data app is use this in the RegisterContext method in the Global.asax.cs&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:389930f4-449c-44b9-8b9b-7af2222b956a" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;DefaultModel.RegisterContext(() =&amp;gt; NorthwindContext.NorthwindEntities.GetContext("aragorn","Northwind"),
            new ContextConfiguration()
            {
                ScaffoldAllTables = true
            });&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 2 – Using the GetContext helper&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;Fixing it up to work in Original version of Dynamic Data&lt;/h4&gt;

&lt;p&gt;This work beautifully in Dynamic Data 4, but not in the previous release &lt;img alt="Sad" src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/2.gif" /&gt;we need the fix mentioned in Rick Andersons post &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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:d968709d-2604-4fa6-809e-3dd58ef6fedf" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;GridDataSource.ContextCreating += delegate(object ceSender,
    EntityDataSourceContextCreatingEventArgs ceArgs)
    {
        ceArgs.Context = (ObjectContext)table.CreateContext();
    };&lt;/pre&gt;&lt;/div&gt;
&lt;strong&gt;&lt;/strong&gt;

&lt;p&gt;&lt;strong&gt;Listing 3 – Fix for Dynamic Data 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Added to the List page it looks like this:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:1faca1f7-5d23-4eea-82c2-89b86b98b9f7" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void Page_Init(object sender, EventArgs e)
{
    DynamicDataManager1.RegisterControl(GridView1, true /*setSelectionFromUrl*/);
    GridDataSource.ContextCreating += delegate(object ceSender,
        EntityDataSourceContextCreatingEventArgs ceArgs)
        {
            ceArgs.Context = (ObjectContext)table.CreateContext();
        };
}&lt;/pre&gt;&lt;/div&gt;
&lt;strong&gt;&lt;/strong&gt;

&lt;p&gt;&lt;strong&gt;Listing 4 – Added to List page template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have to add this to each page template and add it twice on the ListDetails page template.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-502928979862182479?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wAEWCKae9H4VlIK_6O6BsYS82kg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wAEWCKae9H4VlIK_6O6BsYS82kg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wAEWCKae9H4VlIK_6O6BsYS82kg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wAEWCKae9H4VlIK_6O6BsYS82kg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/BIxW_K0oceU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/502928979862182479/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=502928979862182479&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/502928979862182479?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/502928979862182479?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/BIxW_K0oceU/using-entity-framework-from-different.html" title="Using Entity Framework from a different DLL in Dynamic Data" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_UUHjb9DZhJM/TEsHA1pRtTI/AAAAAAAAA3w/5A5YDm-FHLA/s72-c/24-07-2010%2015-46-39_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/07/using-entity-framework-from-different.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8HQ3k8cSp7ImA9Wx9WGUU.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-593180359644578850</id><published>2010-07-20T18:16:00.001+01:00</published><updated>2011-01-25T19:13:52.779Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-25T19:13:52.779Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Code First" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="Entity Framework" /><category scheme="http://www.blogger.com/atom/ns#" term="CTP4" /><title>Using Entity Framework Code First (CTP4) in Dynamic Data</title><content type="html">&lt;p&gt;Following the sample &lt;a href="http://blogs.msdn.com/b/adonet/archive/2010/07/14/ctp4piwalkthrough.aspx"&gt;EF CTP4 Walkthrough: Productivity Improvements&lt;/a&gt; you end up with a sample &lt;em&gt;DbContext&lt;/em&gt; and of course I immediately thought of using this in Dynamic Data using the “ASP.NET Dynamic Data Entities Web Application” template (&lt;strong&gt;Figure 1&lt;/strong&gt;),&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_UUHjb9DZhJM/TEXZysYCKrI/AAAAAAAAA3c/K5IroY8DoNc/s1600-h/20-07-2010%2017-43-39%5B3%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Select ASP.NET Dynamic Data Entities Web Application" border="0" alt="Select ASP.NET Dynamic Data Entities Web Application" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TEXZzzImxqI/AAAAAAAAA3g/HORLjmLOG3M/20-07-2010%2017-43-39_thumb%5B1%5D.png?imgmax=800" width="481" height="334" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 1 - Select ASP.NET Dynamic Data Entities Web Application&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;but I got the following error:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_UUHjb9DZhJM/TEXZ0d3ZldI/AAAAAAAAA3k/KVG0YDQ0ACg/s1600-h/20-07-2010%2017-48-38%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Error when using DbContext with DD4 EF Template." border="0" alt="Error when using DbContext with DD4 EF Template." src="http://lh3.ggpht.com/_UUHjb9DZhJM/TEXZ1L9JxXI/AAAAAAAAA3o/QvkZ1QhDnyY/20-07-2010%2017-48-38_thumb%5B2%5D.png?imgmax=800" width="730" height="385" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 2 – Error when using DbContext with DD4 EF Template.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This my my default code &lt;strong&gt;Listing 1&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:a3ad8717-f499-4852-a7fa-c7e8096ccad7" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;DefaultModel.RegisterContext(typeof(Models.ProductCatalog),
    new ContextConfiguration()
    {
        ScaffoldAllTables = true
    });&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – my default DbContext registration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I fired off an e-mail to Microsoft and was told “the guideline will be to use DD with DomainService, which will have full support of DbContext in the future” although that wont work out of the box at the moment so, I gave up&lt;img alt="Blushing" src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/9.gif" /&gt;&lt;/p&gt;

&lt;p&gt;Then Diego Vega posted on twitter a link to Rowan Millers blog &lt;a href="http://romiller.com/2010/07/19/ef-ctp4-tips-tricks-wcf-data-service-on-dbcontext/"&gt;EF CTP4 Tips &amp;amp; Tricks: WCF Data Service on DbContext&lt;/a&gt; this turned out to be very useful, he talks about getting the underlying ObjectContext see &lt;strong&gt;Listing 2&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:2296928a-46bb-4e96-b920-74d604f08658" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public class ProductCatalog : DbContext
{
    public ProductCatalog(String connectionString)
    {
        // set default connection string
        this.Database.Connection.ConnectionString = connectionString;
    }

    public ObjectContext UnderlyingContext
    {
        get { return this.ObjectContext; }
    }

    public DbSet&amp;lt;Category&amp;gt; Categories { get; set; }
    public DbSet&amp;lt;Product&amp;gt; Products { get; set; }
}

public class Category
{
    public string CategoryId { get; set; }
    public string Name { get; set; }

    public virtual ICollection&amp;lt;Product&amp;gt; Products { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public string CategoryId { get; set; }

    public virtual Category Category { get; set; }
}&lt;/pre&gt;&lt;/div&gt;







&lt;p&gt;&lt;strong&gt;Listing 2 – my ProductCatalog &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Listing 2&lt;/strong&gt; I use this feature to get the underlying &lt;em&gt;ObjectContext&lt;/em&gt; (Also note my setting the connection string in the constructor). So now we have a cool way of getting Entity Framework Code First CTP4 working with Dynamic Data 4. This makes me very happy&lt;img alt="Happy Wizzard" src="http://www.notaclue.co.uk/images/HappyWizard.png" /&gt;&lt;/p&gt;

&lt;p&gt;So you will see that all we need to do to get this working with Dynamic Data now is to replace the&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(Models.&lt;span style="color: #2b91af"&gt;ProductCatalog&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;with&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;() =&amp;gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; Models.&lt;span style="color: #2b91af"&gt;ProductCatalog&lt;/span&gt;(connectionString).UnderlyingContext&lt;/pre&gt;

&lt;p&gt;in the RegisterContext method to get at the underlying ObjectContext, which now leads us to &lt;strong&gt;Listing 3&lt;/strong&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:13157c1e-e9d5-4e2b-824b-28ae4bef8507" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public static void RegisterRoutes(RouteCollection routes)
{
    var connectionString = "Data Source=aragorn;Initial Catalog=ProductCatalog;Integrated Security=True";
    DefaultModel.RegisterContext(() =&amp;gt; new Models.ProductCatalog(connectionString).UnderlyingContext,
        new ContextConfiguration()
        {
            ScaffoldAllTables = true
        });

    routes.Add(new DynamicDataRoute("{table}/{action}.aspx")
    {
        Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert" }),
        Model = DefaultModel
    });
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 3 – Global.asax RegisterRoutes method.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we can Edit, Update and Insert using Entity Framework Code First feature in CTP4.&lt;/p&gt;

&lt;h4&gt;Download&lt;/h4&gt;
&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-96845e7b0fac1eed.office.live.com/embedicon.aspx/Public/CodeFirstSample^_CTP4.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #f0d0f0; margin: 4px; padding-left: 4px; padding-right: 4px; color: #800080; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;Nice: &lt;/strong&gt;One of my favourite things about this is deployment of the DB is that if the DB does not exist on the server specified in the connection string the Entity Framework CTP4 will create it for you (or if you did not specify a connection string it will try to create it in the local SQL Express instance. &lt;/div&gt;

&lt;div style="border-bottom: gray 1px dotted; border-left: gray 1px dotted; padding-bottom: 4px; background-color: #ffdddd; margin: 4px; padding-left: 4px; padding-right: 4px; color: #ff0000; border-top: gray 1px dotted; border-right: gray 1px dotted; padding-top: 4px"&gt;&lt;strong&gt;!Important: &lt;/strong&gt; CTP5 make some minor API changes see &lt;a href="http://blog.davidebbo.com/"&gt;Dabid Ebbo’s&lt;/a&gt; article here &lt;a href="http://blog.davidebbo.com/2011/01/using-dynamic-data-with-ef-code-first.html"&gt;Using Dynamic Data with EF Code First and NuGet &lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-593180359644578850?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/iGytJHLYjk86G9H1N5as75FMbIc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iGytJHLYjk86G9H1N5as75FMbIc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/iGytJHLYjk86G9H1N5as75FMbIc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iGytJHLYjk86G9H1N5as75FMbIc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/nSEecNpzgYo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/593180359644578850/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=593180359644578850&amp;isPopup=true" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/593180359644578850?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/593180359644578850?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/nSEecNpzgYo/using-entity-framework-code-first-ctp4.html" title="Using Entity Framework Code First (CTP4) in Dynamic Data" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_UUHjb9DZhJM/TEXZzzImxqI/AAAAAAAAA3g/HORLjmLOG3M/s72-c/20-07-2010%2017-43-39_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/07/using-entity-framework-code-first-ctp4.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MCSHY8fSp7ImA9Wx5TEEs.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-8193699584132653718</id><published>2010-07-17T12:07:00.001+01:00</published><updated>2010-07-25T15:51:09.875+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-25T15:51:09.875+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".Net 4.0" /><category scheme="http://www.blogger.com/atom/ns#" term="Autocomplete" /><category scheme="http://www.blogger.com/atom/ns#" term="Dynamic Data" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio 2010" /><category scheme="http://www.blogger.com/atom/ns#" term="Filters" /><title>Autocomplete Filter from the old Futures project working in Dynamic Data 4</title><content type="html">&lt;p&gt;I was sorry that the Autocomplete filter from the old Futures project was not added to Dynamic Data 4 &lt;img alt="Crying" src="http://us.i1.yimg.com/us.yimg.com/i/mesg/emoticons7/20.gif" /&gt;So I thought I would do it, so here it is. I also thought I would make it work with the Entity Framework as well.&lt;/p&gt;  &lt;p&gt;First of all if you don’t have a copy of the old futures project then go get it from here &lt;a href="http://aspnet.codeplex.com/releases/view/14475"&gt;Dynamic Data Futures VS2008 SP1 RTM&lt;/a&gt; this has many useful samples that are worth adapting to DD4.&lt;/p&gt;  &lt;h4&gt;Copying The Necessary Files&lt;/h4&gt;  &lt;p&gt;First we need to copy some filed from the old Futures project to the new project in Visual Studio 2010, see &lt;strong&gt;Figure 1&lt;/strong&gt; for the files we need and &lt;strong&gt;Figure 2&lt;/strong&gt; for the where we need to copy them&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;a href="http://lh5.ggpht.com/_UUHjb9DZhJM/TEGO7KJT9dI/AAAAAAAAA20/0Zj1EMcb4Fc/s1600-h/150720101552014.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Autocomplete files" border="0" alt="Autocomplete files" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TEGO7WAk1QI/AAAAAAAAA24/Sn0BlcGyNio/15072010155201_thumb2.png?imgmax=800" width="299" height="390" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;a href="http://lh3.ggpht.com/_UUHjb9DZhJM/TEGO75a2hUI/AAAAAAAAA28/9Pu72yi7FYo/s1600-h/150720101554504.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="LinqExpressionHelper.cs" border="0" alt="LinqExpressionHelper.cs" src="http://lh6.ggpht.com/_UUHjb9DZhJM/TEGO8f_v3OI/AAAAAAAAA3A/M9Q17g-iLCc/15072010155450_thumb2.png?imgmax=800" width="235" height="298" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;strong&gt;Figure 1 - Required files from old Futures project&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_UUHjb9DZhJM/TEGO9KAlqDI/AAAAAAAAA3E/JBSGDw-YTMk/s1600-h/150720101600439.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Files Added to Custom Filter project" border="0" alt="Files Added to Custom Filter project" src="http://lh5.ggpht.com/_UUHjb9DZhJM/TEGO9oBFieI/AAAAAAAAA3I/x0RiMlLGeEs/15072010160043_thumb5.png?imgmax=800" width="320" height="566" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 2 - Files Added to Custom Filters project&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The Files will now need updating to work with this project.&lt;/p&gt;  &lt;h4&gt;Change namespace in each file&lt;/h4&gt;  &lt;p&gt;For this I usually just do a global replace in entire project&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_UUHjb9DZhJM/TEGO-IYRy7I/AAAAAAAAA3M/ILxBexv3g-4/s1600-h/170720101103266.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Ctrl+H  “Find and Replace”" border="0" alt="Ctrl+H  “Find and Replace”" src="http://lh5.ggpht.com/_UUHjb9DZhJM/TEGO-bIyHTI/AAAAAAAAA3Q/InMdQJBG-Ms/17072010110326_thumb2.png?imgmax=800" width="439" height="432" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Figure 3 - Ctrl+H&amp;#160; “Find and Replace”&lt;/strong&gt;&lt;/p&gt;  &lt;h4&gt;Remove redundant using&lt;/h4&gt;  &lt;p&gt;In the Autocomplete.ascx.cs file remove the redundant using statement for &lt;em&gt;Microsoft.Web.DynamicData&lt;/em&gt;.&lt;/p&gt;  &lt;h4&gt;Fix up the AutocompleteFilter.asmx.cs service. &lt;/h4&gt;  &lt;p&gt;First we need to add some references:&lt;/p&gt;  &lt;p&gt;Download and add a reference to Ajax Control Toolkit,&lt;/p&gt;  &lt;p&gt;Next we need is to add the using for generic collections;&lt;/p&gt;  &lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

&lt;p&gt;Then we need to change this;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:0f20b6a2-eecb-422f-b421-4913683467fc" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt; return queryable.Cast&amp;lt;object&amp;gt;().Select(row =&amp;gt; CreateAutoCompleteItem(table, row)).ToArray();&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;for this;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:868ae971-0823-48cc-b47a-972c52b19932" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;var values = new List&amp;lt;String&amp;gt;();
foreach (var row in queryable)
{
    values.Add( CreateAutoCompleteItem(table, row));
}

return values.ToArray(); &lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This also makes it compatible with the Entity Framework&lt;/p&gt;

&lt;h4&gt;Fix up the Autocomplete filter it’s self. &lt;/h4&gt;

&lt;p&gt;The very first thing is the filter needs to inherit from “System.Web.DynamicData.QueryableFilterUserControl”&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;partial&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Autocomplete_Filter&lt;/span&gt; : System.Web.DynamicData.&lt;span style="color: #2b91af"&gt;QueryableFilterUserControl&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Add the following Usings:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Web.UI;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Collections;&lt;/pre&gt;

&lt;p&gt;Then we need to add some properties;&lt;/p&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:a35e0f0f-9026-41a2-944d-ae5aa1fed639" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;private new MetaForeignKeyColumn Column
{
    get { return (MetaForeignKeyColumn)base.Column; }
}

public override Control FilterControl
{
    get { return AutocompleteTextBox; }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Next replace ALL&amp;#160; occurrences of &lt;em&gt;InitialValue&lt;/em&gt; with &lt;em&gt;DefaultValue&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;In the CleantButton_Click event add OnFilterChanged() call&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:fde7b96f-f770-4b4a-bd0c-d87bd3822999" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public void ClearButton_Click(object sender, EventArgs e)
{
    // this would probably be better handled using client JavaScirpt
    AutocompleteValue.Value = String.Empty;
    AutocompleteTextBox.Text = String.Empty;
    OnFilterChanged();
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Remove the SelectedValue property and add the following event handler and method.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:f7391205-50d0-4ae3-bd96-af5c491fe19c" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;protected void AutocompleteValue_ValueChanged(object sender, EventArgs e)
{
    OnFilterChanged();
}

public override IQueryable GetQueryable(IQueryable source)
{
    string selectedValue = String.IsNullOrEmpty(AutocompleteValue.Value) ? null : AutocompleteValue.Value
    if (String.IsNullOrEmpty(selectedValue))
        return source;

    IDictionary dict = new Hashtable();
    Column.ExtractForeignKey(dict, selectedValue);
    foreach (DictionaryEntry entry in dict)
    {
        string key = (string)entry.Key;
        if (DefaultValues != null)
            DefaultValues[key] = entry.Value;

        source = ApplyEqualityFilter(source, Column.GetFilterExpression(key), entry.Value);
    }
    return source;
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 1 – New Methods for Autocomplete filter.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next we need to hook-up the &lt;em&gt;HiddenField’s&lt;/em&gt; &lt;em&gt;OnValueChanged&lt;/em&gt; event handler to point to &lt;em&gt;AutocompleteValue_ValueChanged&lt;/em&gt; method we just added, so it looks like this.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:84b918cd-280b-41d7-a1ce-318d87dfaced" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;asp:HiddenField
    runat="server" 
    ID="AutocompleteValue" 
    OnValueChanged="AutocompleteValue_ValueChanged"/&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;Add a link to the Autocomplete css&lt;/h4&gt;

&lt;p&gt;Open site.master and drag the AutocompleteStyle.css to the Head section &lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;link&lt;/span&gt;&amp;#160;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;AutocompleteStyle.css&amp;quot;&lt;/span&gt;&amp;#160;&lt;span style="color: red"&gt;rel&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt;&amp;#160;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Now we need to add some styling to the Autocomplete.ascx filter, I’m just adding&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: red"&gt;CssClass&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;DDControl&amp;quot;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;to the TextBox and Button controls.&lt;/p&gt;

&lt;h4&gt;Add some Metadata&lt;/h4&gt;

&lt;p&gt;In &lt;strong&gt;Listing 1&lt;/strong&gt; we have added a FilterUIHint setting the Autocomplete filter as the the filter for the Orders Customer property.&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:db06bb01-c46f-4893-ab11-c0eaa789390d" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;[MetadataTypeAttribute(typeof(Order.OrderMetadata))]
public partial class Order
{
    internal sealed class OrderMetadata
    {
        [FilterUIHint("Autocomplete")]
        public Customer Customer { get; set; }
    }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Listing 3 -&amp;#160; sample metadata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;You should now have a working sample run it up and go to the Orders table list page:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_UUHjb9DZhJM/TEGO-1QEdoI/AAAAAAAAA3U/roU_bQRjrfc/s1600-h/17-07-2010%2012-03-11%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Autocomplete filter in action" border="0" alt="Autocomplete filter in action" src="http://lh3.ggpht.com/_UUHjb9DZhJM/TEGO_J_dn4I/AAAAAAAAA3Y/XDB3WEX1wkQ/17-07-2010%2012-03-11_thumb%5B2%5D.png?imgmax=800" width="444" height="285" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Figure 4 - Autocomplete filter in action&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;Downloads&lt;/h2&gt;
&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-96845e7b0fac1eed.office.live.com/embedicon.aspx/Public/AutoCompleteFilterSample.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;

&lt;p&gt;Happy Coding &lt;img alt="Happy Wizzard" src="http://www.notaclue.co.uk/images/HappyWizard.png" /&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-8193699584132653718?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PXTZCYLj3E_SxIVgxSEGVnN8Pxo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PXTZCYLj3E_SxIVgxSEGVnN8Pxo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PXTZCYLj3E_SxIVgxSEGVnN8Pxo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PXTZCYLj3E_SxIVgxSEGVnN8Pxo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/xlk8KROHEz0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/8193699584132653718/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=8193699584132653718&amp;isPopup=true" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/8193699584132653718?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/8193699584132653718?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/xlk8KROHEz0/autocomplete-filter-from-old-futures.html" title="Autocomplete Filter from the old Futures project working in Dynamic Data 4" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_UUHjb9DZhJM/TEGO7WAk1QI/AAAAAAAAA24/Sn0BlcGyNio/s72-c/15072010155201_thumb2.png?imgmax=800" height="72" width="72" /><thr:total>8</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/07/autocomplete-filter-from-old-futures.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkACR38_eSp7ImA9WxFaEk8.&quot;"><id>tag:blogger.com,1999:blog-6907873803403737979.post-7178219831562415768</id><published>2010-07-15T20:03:00.001+01:00</published><updated>2010-07-15T20:06:06.141+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-15T20:06:06.141+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Code First" /><category scheme="http://www.blogger.com/atom/ns#" term="CTP" /><category scheme="http://www.blogger.com/atom/ns#" term="Entity Framework" /><title>EF CTP4 Released!</title><content type="html">&lt;p&gt;Entity Framework Code First CTP4 is now available see following links:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/adonet/archive/2010/07/14/ctp4announcement.aspx"&gt;ADO.NET team blog - EF CTP4 Released!&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=4e094902-aeff-4ee2-a12d-5881d4b0dd3e&amp;amp;displaylang=en#filelist"&gt;Microsoft ADO.NET Entity Framework Feature Community Technology Preview 4&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/adonet/archive/2010/07/14/ctp4piwalkthrough.aspx"&gt;EF CTP4 Walkthrough: Productivity Improvements&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/adonet/archive/2010/07/14/ctp4codefirstwalkthrough.aspx"&gt;EF CTP4 Walkthrough: Code First&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/efdesign/archive/2010/06/21/productivity-improvements-for-the-entity-framework.aspx"&gt;Productivity Improvements for the Entity Framework&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/efdesign/archive/2010/06/01/conventions-for-code-first.aspx"&gt;Conventions for Code First&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/efdesign/archive/2010/03/30/data-annotations-in-the-entity-framework-and-code-first.aspx"&gt;Data Annotations in the Entity Framework and Code First&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://romiller.com/2010/07/14/ef-ctp4-tips-tricks-include-with-lambda/"&gt;EF CTP4 Tips &amp;amp; Tricks: Include with Lambda&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;And a quick note from my testing:&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:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:add4605b-ee6d-4722-8a0d-1fc879e43a3b" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: c#;"&gt;public class ProductCatalog : DbContext
{
    public ProductCatalog()
    {
        this.Database.Connection.ConnectionString =
           "Data Source=.;Initial Catalog=ProductCatalog;Integrated Security=True";
    }

    public DbSet&amp;lt;Category&amp;gt; Categories { get; set; }
    public DbSet&amp;lt;Product&amp;gt; Products { get; set; }
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Above is from the first sample you create in VS2010 with EF Code First, and a quick way to create your DB on a different server than on &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, courier, sans-serif"&gt;localhost\SQLEXPRESS&lt;/span&gt; thought this is super cool.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_UUHjb9DZhJM/TD9bY-Wo_YI/AAAAAAAAA2s/lIL9DH0THUQ/s1600-h/HappyWizard%5B1%5D%5B3%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Happy Wizard" border="0" alt="Happy Wizard" src="http://lh4.ggpht.com/_UUHjb9DZhJM/TD9bZZfTBwI/AAAAAAAAA2w/1PlNm_aQqQw/HappyWizard%5B1%5D_thumb%5B1%5D.png?imgmax=800" width="19" height="33" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6907873803403737979-7178219831562415768?l=csharpbits.notaclue.net' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uNbyob4DKSthQMK19ZwnfMru8oU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uNbyob4DKSthQMK19ZwnfMru8oU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uNbyob4DKSthQMK19ZwnfMru8oU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uNbyob4DKSthQMK19ZwnfMru8oU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/notaclue/IYRx/~4/nSR45l3DMYs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://csharpbits.notaclue.net/feeds/7178219831562415768/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6907873803403737979&amp;postID=7178219831562415768&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7178219831562415768?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6907873803403737979/posts/default/7178219831562415768?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/notaclue/IYRx/~3/nSR45l3DMYs/ef-ctp4-released.html" title="EF CTP4 Released!" /><author><name>Steve</name><uri>http://www.blogger.com/profile/17435527974910745156</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="25" height="32" src="http://bp1.blogger.com/_UUHjb9DZhJM/SDtH0AxIZOI/AAAAAAAAAEM/TFDI9vas7Sc/S220/Me+63x80.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_UUHjb9DZhJM/TD9bZZfTBwI/AAAAAAAAA2w/1PlNm_aQqQw/s72-c/HappyWizard%5B1%5D_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://csharpbits.notaclue.net/2010/07/ef-ctp4-released.html</feedburner:origLink></entry></feed>

