<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Andrew Rea | Blog | C# &amp; ASP.NET Development</title><link>http://weblogs.asp.net/andrewrea/default.aspx</link><description>A BLOG which I use to publicize my findings while I work. From Programming C# to Server side, Clientside and a few in between.</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><geo:lat>53.5443</geo:lat><geo:long>-2.6311</geo:long><image><link>http://weblogs.asp.net/andrewrea</link><url>http://www.andrewrea.co.uk/FeedLogo.jpg</url><title>Andrews Rea's Blog</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/AndrewRea" type="application/rss+xml" /><feedburner:emailServiceId>AndrewRea</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>ASP.NET Dynamic Data – Using Column Generators based on Meta Data</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/T-3pH5k6E4w/asp-net-dynamic-data-using-column-generators-based-on-meta-data.aspx</link><pubDate>Wed, 25 Mar 2009 21:10:36 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7001272</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=7001272</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/03/25/asp-net-dynamic-data-using-column-generators-based-on-meta-data.aspx#comments</comments><description>&lt;p&gt;I was looking at the generated site which ASP.NET Dynamic Data had provided and thought, I wonder how I can choose which columns I want to display based on the model itself.&amp;#160; This is then dynamic, in the way that for one model I show one column, but for the others I may show five, or six etc… &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_64D9C089.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="349" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_76D5DE49.png" width="600" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I have been following the posts from &lt;a href="http://mattberseth.com/" target="_blank"&gt;Matt Berseth&lt;/a&gt;, where he exploits the attributes from the System.ComponentModel namespace.&amp;#160; He shows how you can create a nice nested menu based on Category and Display Name attributes.&amp;#160; &lt;/p&gt;  &lt;p&gt;So, this got me thinking, along the lines of, it is very convenient to use attributes in order to determine outcomes when working with meta data, and in this case, which columns I want to display inside the List.aspx template which you get provided out of the box as a standard template.&amp;#160; Alteration more than anything but before that, I need to set a few things up.&lt;/p&gt;  &lt;h3&gt;The MetaDataModels&lt;/h3&gt;  &lt;p&gt;These are the classes which dictate what meta information are available for your entities at runtime.&amp;#160; You assign the relevant meta data model to the entity using an attribute like the following:&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7c4d714a-b142-4034-80c6-ce8486c2eb0d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[MetadataType(typeof(ProductMetadata))]
 public partial class Product
 {
     public Product(){

     }
 }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I then create another class which is the actual ProductMetaData.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:99b53eeb-99ed-41bb-a2c9-8f698d9c433b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[Category("Products")]
public class ProductMetadata
{
    [ScaffoldColumn(false)]
    public int ProductID{get;set;}

    [ListVisible]
    public string ProductCode{get;set;}
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now in the second example above you will notice the ListVisible attribute, this is custom and is defined simply like this:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:51156929-aa74-480d-aade-9343b3f0afef" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;[AttributeUsage(AttributeTargets.Property)]
public class ListVisibleAttribute : Attribute
{

}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;The Column Generators&lt;/h3&gt;

&lt;p&gt;Once this is done you can then apply it to properties inside your class.&amp;#160; I only want to use this for Properties so I limit its scope using the AttributeUsage attribute.&amp;#160; So the idea now is this, once we have the meta table we are going to bind with, we want to then extract all the columns which have the attribute ListVisible.&amp;#160; I don’t want to create a new template though, not sure how yet lol, so I just want to edit the current.&amp;#160; The GridView auto generates its columns and something which I rooted out today was the ColumnGenerator type, or rather the IAutoFieldGenerator interface.&amp;#160; When you provide a GridView with this, it then knows which columns should be auto generated, so inline with this example I want to make a column generator which gets all the columns with the ListVisible attribute.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9c3831d2-c2af-4188-9541-5b9e21f526fb" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public class GridViewMetaColumnGenerator :IAutoFieldGenerator
{
    protected MetaTable table;

    public GridViewMetaColumnGenerator(MetaTable table)
    {
        this.table = table;
    }

    #region IAutoFieldGenerator Members

    public System.Collections.ICollection GenerateFields(Control control)
    {
        DataControlFieldCollection columns = new DataControlFieldCollection();

        foreach (MetaColumn col in table.Columns)
        {
            if (col.GetListVisible())
            {
                BoundField column = new BoundField();
                column.DataField = col.Name;
                column.SortExpression = col.Name;
                column.HeaderText = col.Name;
                columns.Add(column);
            }
        }

        return columns;
    }

    #endregion
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, i create the class which takes one argument in the constructor which is the MetaTable.&amp;#160; The GenerateFields method will be called by the GridView, so inside here I loop through the columns inside the MetaTable and if the column is decorated with the ListVisible attribute, I add it to the DataControlFieldCollection.&amp;#160; You will notice some familiar properties of the BoundField above.&amp;#160; The method GetListVisible is an extension method which I made, and simply checks for the presence of the attribute on the MetaColumn:&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:ff9a30ac-93d7-4a1c-84ce-6159dc528f33" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public static bool GetListVisible(this MetaColumn column)
{
    return column.Attributes[typeof(ListVisibleAttribute)] != null;
}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;All that is left to do now is to alter the List.aspx template to include the column generator.&amp;#160; Below is the updated Page_Load event:&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7d863d5f-f721-4717-8245-b61cb7e7dc4c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;protected void Page_Load(object sender, EventArgs e)
{
    table = GridDataSource.GetTable();
    Title = table.DisplayName;
    InsertHyperLink.NavigateUrl = table.GetActionPath(PageAction.Insert);
    // Disable various options if the table is readonly

    GridViewMetaColumnGenerator metaColumnsGenerator = new GridViewMetaColumnGenerator(table);

    GridView1.ColumnsGenerator = metaColumnsGenerator;

    if (table.IsReadOnly)
    {
        GridView1.Columns[0].Visible = false;
        InsertHyperLink.Visible = false;
    }

}&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And it works a treat, and if this is not the best way, I still think it is kind of clean.&amp;#160; Well I hope this helps some people as I appreciate this is new territory and I my self am constantly on the look out for helpful tutorials trying to open up the topic.&lt;/p&gt;

&lt;p&gt;Cheers for now:&lt;/p&gt;

&lt;p&gt;Andrew&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE 27th March 2008&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Although the above does work to an extent it does not work completely.&amp;#160; For one thing I have totally destroyed the functionality of the Dynamic Controls which are rendered based on the UIHint.&amp;#160; So, from reading about the internet I have found a few things including the fact that IAutoFieldGenerator has been used by the community in the ASP.NET Dynamic Data area for some time now.&amp;#160; The change required is the type which I am returning inside the GenerateFields method.&amp;#160; I currently instantiate BoundFields, where as I should be instantiating Dynamic Fields.&lt;/p&gt;

&lt;p&gt;I also integrated a new field template which handles Many To Many relationships and that I got from this &lt;a href="http://blogs.msdn.com/davidebb/" target="_blank"&gt;kind fellow at Micrsoft, David Ebbo&lt;/a&gt;.&amp;#160; Lots of Dynamic Data topics on here.&lt;/p&gt;

&lt;p&gt;Another update I should also make the code above, is to provided further funationality on the custom attribute.&amp;#160; I am basically limiting its functionality to simply Lists.&amp;#160; Instead of that it would be better if you could state Flags for the type of Page Template the certain columns should be visible in.&amp;#160; Again this has already been done after searching round the internet.&amp;#160; So basically it provides a more robust approach than mine above.&amp;#160; Here is the example: &lt;a href="http://stuartmanning.com/blogs/aspnet/archive/2009/01/26/dynamic-data-hiding-columns-in-selected-pagetemplates.aspx" target="_blank"&gt;http://stuartmanning.com/blogs/aspnet/archive/2009/01/26/dynamic-data-hiding-columns-in-selected-pagetemplates.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So having not yet integrated that into my project I have still got the following as my GenerateFields method:&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:eca6fdcd-c19a-4116-a324-cb6dbddf57b0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;
  &lt;div class="dp-highlighter"&gt;
    &lt;div class="bar"&gt;
      &lt;div class="tools"&gt;&lt;a onclick="dp.sh.Toolbar.Command(&amp;#39;ViewSource&amp;#39;,this);return false;" href="about:blank#"&gt;view plain&lt;/a&gt;&lt;a onclick="dp.sh.Toolbar.Command(&amp;#39;CopyToClipboard&amp;#39;,this);return false;" href="about:blank#"&gt;copy to clipboard&lt;/a&gt;&lt;a onclick="dp.sh.Toolbar.Command(&amp;#39;PrintSource&amp;#39;,this);return false;" href="about:blank#"&gt;print&lt;/a&gt;&lt;/div&gt;
    &lt;/div&gt;

    &lt;ol class="dp-c"&gt;
      &lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; System.Collections.ICollection GenerateFields(Control control)&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;{&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="comment"&gt;// Auto-generate fields from metadata. &lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; var fields = &lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; List&amp;lt;DynamicField&amp;gt;();&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="keyword"&gt;foreach&lt;/span&gt;&lt;span&gt; (MetaColumn column &lt;/span&gt;&lt;span class="keyword"&gt;in&lt;/span&gt;&lt;span&gt; table.Columns)&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="comment"&gt;// Skip column that shouldn't be scaffolded &lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (!column.Scaffold) &lt;/span&gt;&lt;span class="keyword"&gt;continue&lt;/span&gt;&lt;span&gt;;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="comment"&gt;// Don't display long string in controls that show multiple items &lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="comment"&gt;// REVIEW: we should avoid hard coding a list of control, but IDataBoundControl does not give us this info &lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; ((column.IsLongString &amp;amp;&amp;amp; control &lt;/span&gt;&lt;span class="keyword"&gt;is&lt;/span&gt;&lt;span&gt; GridView) || !column.GetListVisible())&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="keyword"&gt;continue&lt;/span&gt;&lt;span&gt;;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="comment"&gt;// If it's a Many To Many column, use our special field template &lt;/span&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt; uiHint = &lt;/span&gt;&lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt;;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt; (column.Provider.Association != &lt;/span&gt;&lt;span class="keyword"&gt;null&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp; column.Provider.Association.Direction == AssociationDirection.ManyToMany)&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; uiHint = &lt;/span&gt;&lt;span class="string"&gt;&amp;quot;ManyToMany&amp;quot;&lt;/span&gt;&lt;span&gt;;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; fields.Add(&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; DynamicField() { DataField = column.Name, UIHint = uiHint });&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;&amp;#160; &lt;/span&gt;&lt;/li&gt;

      &lt;li class=""&gt;&lt;span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt; fields;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;

      &lt;li class="alt"&gt;&lt;span&gt;}&amp;#160; &lt;/span&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/div&gt;

  &lt;pre class="c#" style="display: none" name="code"&gt;public System.Collections.ICollection GenerateFields(Control control)
{
    // Auto-generate fields from metadata.
    var fields = new List&amp;lt;DynamicField&amp;gt;();
    foreach (MetaColumn column in table.Columns)
    {
        // Skip column that shouldn't be scaffolded
        if (!column.Scaffold) continue;

        // Don't display long string in controls that show multiple items
        // REVIEW: we should avoid hard coding a list of control, but IDataBoundControl does not give us this info
        if ((column.IsLongString &amp;amp;&amp;amp; control is GridView) || !column.GetListVisible())
            continue;


        // If it's a Many To Many column, use our special field template
        string uiHint = null;
        if (column.Provider.Association != null &amp;amp;&amp;amp; column.Provider.Association.Direction == AssociationDirection.ManyToMany)
        {
            uiHint = &amp;quot;ManyToMany&amp;quot;;
        }

        fields.Add(new DynamicField() { DataField = column.Name, UIHint = uiHint });
    }

    return fields;
}&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7001272" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cT8zDXz7Ahgo8AENz7NK4MrPjJs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cT8zDXz7Ahgo8AENz7NK4MrPjJs/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/cT8zDXz7Ahgo8AENz7NK4MrPjJs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cT8zDXz7Ahgo8AENz7NK4MrPjJs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=T-3pH5k6E4w:mt7MH1sHQX8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=T-3pH5k6E4w:mt7MH1sHQX8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=T-3pH5k6E4w:mt7MH1sHQX8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=T-3pH5k6E4w:mt7MH1sHQX8:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=T-3pH5k6E4w:mt7MH1sHQX8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=T-3pH5k6E4w:mt7MH1sHQX8:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/T-3pH5k6E4w" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/03/25/asp-net-dynamic-data-using-column-generators-based-on-meta-data.aspx</feedburner:origLink></item><item><title>Programmatic WebControls – Variations of design</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/r0Ff5sSuSS4/programmatic-webcontrols-variations-of-design.aspx</link><pubDate>Tue, 17 Mar 2009 17:50:25 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6971078</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6971078</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/03/17/programmatic-webcontrols-variations-of-design.aspx#comments</comments><description>&lt;p&gt;I thought I would compose a short how to on programmatic web controls.&amp;#160; Often I have looked at the core set of controls within ASP.NET and wonder what design is required in order to get the design time mark up similar to that of the various controls.&amp;#160; The types of markup I am referring to includes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Containers &lt;/li&gt;    &lt;li&gt;Lists &lt;/li&gt;    &lt;li&gt;Templates &lt;/li&gt;    &lt;li&gt;Nested Controls of a certain type &lt;/li&gt;    &lt;li&gt;Data bound controls      &lt;ul&gt;       &lt;li&gt;Only one example here, as I have wanted to do for ages and could not quite put my finger on how it was achieved.&amp;#160; Turns out, really simple lol &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The following imports are used in these examples:&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:57fd4980-f22b-46e8-b0a9-2864bc4c01bd" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Simple Container Control&lt;/h3&gt;

&lt;p&gt;The first custom control structure I want to make is a custom panel.&amp;#160; Not inherited from a panel, although the same would be achieved but rather the simplest custom container.&amp;#160; &lt;/p&gt;

&lt;p&gt;Desired Mark up&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8b8c2e27-b43f-48fe-9e1d-d4a1409c970d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;        &amp;lt;aebs:CustomPanel ID="Panel1" runat="server"&amp;gt;
            Hell World
        &amp;lt;/aebs:CustomPanel&amp;gt;&lt;/pre&gt;&lt;/div&gt;
This is as simple as it gets.&amp;#160; This is a web control which persists any children controls or elements which you put in side. 

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f2350ba9-f996-4a51-ad01-e05d29f2349a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    [ParseChildren(false)]
    [PersistChildren(true)]
    public class CustomPanel : WebControl
    {
        public CustomPanel()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;A Control with an object list&lt;/h3&gt;

&lt;p&gt;This control is a web control but it has a list of an object, so you can add numerous types of the object to its collection.&amp;#160; The collection could be of a web control and if so it would be wise to inherit from a composite control as opposed to a web control.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Desired mark-up&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2bedc168-0ab8-4909-8644-18cd350d54c1" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;        &amp;lt;aebs:ListControl1 ID="ListControl1" runat="server"&amp;gt;
            &amp;lt;CustomObjects&amp;gt;
                &amp;lt;aebs:CustomObject CustomProperty="Hello World" /&amp;gt;
                &amp;lt;aebs:CustomObject CustomProperty="Hello World 2" /&amp;gt;
            &amp;lt;/CustomObjects&amp;gt;
        &amp;lt;/aebs:ListControl1&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;So in design time you will see the intellisense prompt you for a tag called CustomObjects followed by nested prompts of a tag called Custom Object.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_3ABB1C04.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="181" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_39768325.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9dbf2db5-1093-43e5-a961-17c455137b71" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    [ParseChildren(true)]
    [PersistChildren(false)]
    public class ListControl1 : WebControl
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public List&amp;lt;CustomObject&amp;gt; CustomObjects { get; set; }

        public ListControl1()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Custom object is nothing more than a class with a property. see here&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:33e18a0d-cd37-4f5b-8516-b81adb086443" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    public class CustomObject
    {
        public string CustomProperty { get; set; }

        public CustomObject()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;A Template Control&lt;/h3&gt;

&lt;p&gt;The mark up achieved with this type of control is like the type you see with for example the form view control which allows for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Item Template &lt;/li&gt;

  &lt;li&gt;Insert Item Template &lt;/li&gt;

  &lt;li&gt;Edit Item Template &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All I am doing is showing the mark-up required for the design time mark-up, so when using you will need to use the ITemplate InstantiateIn method providing a web control or html control as the container.&lt;/p&gt;

&lt;p&gt;Desired mark-up&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f3c30a31-1fc6-4e50-ba35-fd161526322e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;        &amp;lt;aebs:TemplateControl ID="TemplateControl1" runat="server"&amp;gt;
            &amp;lt;HeaderTemplate&amp;gt;
                Hello Header World
            &amp;lt;/HeaderTemplate&amp;gt;
            &amp;lt;ContentTemplate&amp;gt;
                Hello Content World
            &amp;lt;/ContentTemplate&amp;gt;
            &amp;lt;FooterTemplate&amp;gt;
                Hello Footer World
            &amp;lt;/FooterTemplate&amp;gt;
        &amp;lt;/aebs:TemplateControl&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_5E279A9C.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="193" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_5CE301BD.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The code to achieve this is as follows.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f8219138-7043-4fd1-8910-b671993e15c6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    [ParseChildren(true)]
    [PersistChildren(false)]
    public class TemplateControl : WebControl
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate HeaderTemplate { get; set; }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate ContentTemplate { get; set; }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate FooterTemplate { get; set; }

        public TemplateControl()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You are going to want to control how each template is rendered but for the purposes of this example I am only showing the bare bones of how to achieve the mark-up. &lt;/p&gt;

&lt;h3&gt;A container control with specific object types as options&lt;/h3&gt;

&lt;p&gt;A good example of this type of control is when you use the object or sql data source control.&amp;#160; It allows you to specify parameters for the select, insert, update etc…&amp;#160; The options though which are provided to you are restricted so you can only choose parameter objects.&amp;#160; The key here is to specify a list property of the control with the type being a class other inherit from, not necessarily abstract.&lt;/p&gt;

&lt;p&gt;Desired mark-up&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:41db01b2-95fc-4f7f-b15c-690fd8892729" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;        &amp;lt;aebs:ConstrainedCollection ID="Constrained1" runat="server"&amp;gt;
            &amp;lt;AbstractProperties&amp;gt;
                &amp;lt;aebs:ConcreteOne /&amp;gt;
                &amp;lt;aebs:ConcreteTwo /&amp;gt;
            &amp;lt;/AbstractProperties&amp;gt;
        &amp;lt;/aebs:ConstrainedCollection&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_415DFFBA.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="166" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_6B5DFDE2.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The code to achieve this mark-up is as follows:&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2376729d-1d7c-42c8-a4e5-3213b381427d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    [ParseChildren(true)]
    [PersistChildren(false)]
    public class ConstrainedCollection : WebControl
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public List&amp;lt;AbstractClass1&amp;gt; AbstractProperties { get; set; }

        public ConstrainedCollection()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;So you can see that the only difference between this and the list control example above is that I use a type for the list which is inherited by two other types being ConcreteOne and also ConcreteTwo.&lt;/p&gt;

&lt;h3&gt;A DataPanel&lt;/h3&gt;

&lt;p&gt;I have wanted to do this for a while but could not quite put my finger on how it was achieved.&amp;#160; Like I said up top, this turns out to be really simple.&amp;#160; The same could be achieved with an ObjectDataSource and a FormView but i want a light weight container which I could throw an object at and use Eval inside it.&amp;#160; I have many many uses for such a light weight singular object display.&amp;#160; Plus I also wondered how the use of Eval was achieved in Custom Controls, turns out that it is through the use the &lt;strong&gt;System.Web.UI.IDataItemContainer &lt;/strong&gt;Interface&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Desired Mark-up&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b28b3149-8918-4055-8780-7c9359bb8d26" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;        &amp;lt;aebs:DataPanel ID="datapanel1" runat="server"&amp;gt;
            &amp;lt;%# Eval("ProjectName") %&amp;gt;
        &amp;lt;/aebs:DataPanel&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So I am not doing anything more than requesting a property of the object which I throw at the control.&amp;#160; Throwing the object at the control I do inside the Page_Load event just for demo.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e65cd58d-d2c3-4b8e-8223-927527d4ffc2" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    public void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            DataPanel.Project p = new DataPanel.Project();
            p.ProjectName = "Project 101";

            datapanel1.BoundObject = p;
            datapanel1.DataBind();
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_1E4D8E4A.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="352" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_275A19CB.png" width="604" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;So the code to achieve this is just the simple container control above but this time I implement the interface.&amp;#160; For the purposes of demonstration I have also banged the class inside this type as nested too.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7924c585-92e0-4a1d-a324-3013e968fa2e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    [ParseChildren(false)]
    [PersistChildren(true)]
    public class DataPanel : WebControl, IDataItemContainer
    {
        public class Project
        {
            public string ProjectName { get; set; }
        }

        private object boundObject;

        public DataPanel()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public object BoundObject
        {
            set
            {
                boundObject = value;
            }
        }

        #region IDataItemContainer Members

        public object DataItem
        {
            get { return boundObject; }
        }

        public int DataItemIndex
        {
            get { return 0; }
        }

        public int DisplayIndex
        {
            get { return 0; }
        }

        #endregion
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Well I hope this is of some use to others,&amp;#160; I will try and update this post soon with examples of custom DataSource controls and also custom DataBound Controls.&amp;#160; When you start get into List Controls from a data source it gets real fun.&lt;/p&gt;

&lt;p&gt;Cheers &lt;/p&gt;

&lt;p&gt;Andrew&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6971078" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GoOsqMtLMNxtlwcJ1sLYyomOGNM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GoOsqMtLMNxtlwcJ1sLYyomOGNM/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/GoOsqMtLMNxtlwcJ1sLYyomOGNM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GoOsqMtLMNxtlwcJ1sLYyomOGNM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=r0Ff5sSuSS4:wChbixPcnmQ:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=r0Ff5sSuSS4:wChbixPcnmQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=r0Ff5sSuSS4:wChbixPcnmQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=r0Ff5sSuSS4:wChbixPcnmQ:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=r0Ff5sSuSS4:wChbixPcnmQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=r0Ff5sSuSS4:wChbixPcnmQ:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/r0Ff5sSuSS4" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Visual+C_2300_/default.aspx">Visual C#</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Custom+Controls/default.aspx">Custom Controls</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Data+Bound+Controls/default.aspx">Data Bound Controls</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/03/17/programmatic-webcontrols-variations-of-design.aspx</feedburner:origLink></item><item><title>Idea for a Helper Utility Class Generator for a WCF Rest Service</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/OdruZ_do3Mc/idea-for-a-helper-utility-class-generator-for-a-wcf-rest-service.aspx</link><pubDate>Tue, 17 Mar 2009 16:49:31 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6970879</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6970879</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/03/17/idea-for-a-helper-utility-class-generator-for-a-wcf-rest-service.aspx#comments</comments><description>&lt;p&gt;This morning I followed an Adobe Flex tutorial, well 3, about consuming Twitters restful API inside Flex.&amp;#160; After this it got me thinking about WCF and their Rest Starter Kit.&amp;#160; I looked and they are now up to Preview 2, so I downloaded it and in my spare time focused on this recently release white paper:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd203052.aspx" target="_blank"&gt;A Guide to Designing and Building RESTful Web Services with WCF 3.5&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Installing the starter kit, which also installs some project templates, gives you a good starting point.&amp;#160; It also introduced me to some new concepts.&amp;#160; The starter kit actually generates a help page for your service which is an xml feed and XSLT Style Sheet e.g.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_0FA9A3EC.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="412" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_0A2B0D7B.png" width="604" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So It provides all the relevant information required i.e. the method, the uri template, the request and response schema.&amp;#160; I tested out a quick code up for the simplest form for consumption by C# and it worked out pretty well.&amp;#160; I focused on the fact that the info can be returned currently in two formats being XML and also JSON.&amp;#160; I wanted an abstract class to hold the URI’s for each method and also abstract methods which each derived object needs to override.&lt;/p&gt;  &lt;p&gt;The idea is ultimately to have strongly typed helper methods for consuming restful apis.&amp;#160; So the tool, similar to the WSDL or SVCUTIL could be supplied with the following information:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;namespace &lt;/li&gt;    &lt;li&gt;language &lt;/li&gt;    &lt;li&gt;url of help feed &lt;/li&gt;    &lt;li&gt;asynchronous &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;What I would want to build on is the language part, as the interoperability of a rest api is huge.&amp;#160; If you make an implementation of the help generator in C# for example and use a Strategy pattern for the generation then this gives rise to the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;C# Generation Strategy &lt;/li&gt;    &lt;li&gt;VB.NET Generation Strategy &lt;/li&gt;    &lt;li&gt;ActionScript Generation Strategy &lt;/li&gt;    &lt;li&gt;C++ Generation Strategy &lt;/li&gt;    &lt;li&gt;Pure JavaScript Generation Strategy &lt;/li&gt;    &lt;li&gt;Jquery Generation Strategy (Yes I differentiated from the JavaScript option) &lt;/li&gt;    &lt;li&gt;PHP Generation Strategy &lt;/li&gt;    &lt;li&gt;Java Strategy &lt;/li&gt;    &lt;li&gt;Python Strategy &lt;/li&gt;    &lt;li&gt;Ruby on rails strategy &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So you get the idea, it could be built then extended over time.&amp;#160; Am I getting ahead of myself here?&amp;#160; Is there one in production? WHO KNOWS? but it is fun never the less to jump in and have a go.&amp;#160; &lt;/p&gt;  &lt;p&gt;So the quick Code Up I did is as follows:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Duplicate the type used in the REST Service and decorate with the namespace for XML Serialization needs&lt;/strong&gt;&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:37ed19d6-c298-4850-8872-36b89fbedd6e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    [XmlRoot(Namespace="http://schemas.datacontract.org/2004/07/Swissmod.Service.Model")]
    public class Project
    {
        public string ID { get; set; }
        public string UserID { get; set; }
        public string ClientID { get; set; }
        public string ProjectTitle { get; set; }
        public string ProjectDescription { get; set; }
        public DateTime Created { get; set; }
        public DateTime LastModified { get; set; }
        public string Version { get; set; }

        public override string ToString()
        {
            StringBuilder sb1 = new StringBuilder();

            foreach (PropertyInfo pi in this.GetType().GetProperties())
            {
                sb1.AppendLine(pi.Name + " : " + pi.GetValue(this, null));
            }

            return sb1.ToString();
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Define the abstract class for the Project Service&lt;/strong&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a3dfac2a-7e36-4014-ac5b-d2a7632073f3" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    public abstract class ProjectRestClient
    {
        protected string baseUrl = "http://test.@yoursite.com/ProjectService.svc/";

        public abstract Project GetProject(string id);
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Implement an XML Version of the Project Rest Client&lt;/strong&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c9e890e5-a72a-46c0-9434-ffefa663894e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    public class ProjectXmlRestClient : ProjectRestClient
    {
        public override Project GetProject(string id)
        {
            WebRequest wr = WebRequest.Create(baseUrl + id);
            wr.Method = "GET";
            wr.ContentType = "text/xml";
            WebResponse wresp = wr.GetResponse();
            XmlSerializer serializer = new XmlSerializer(typeof(Project));
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationFlags = XmlSchemaValidationFlags.None;
            settings.ValidationType = ValidationType.None;
            settings.ConformanceLevel = ConformanceLevel.Auto;
            settings.IgnoreProcessingInstructions = true;
            settings.NameTable = new NameTable();
            settings.NameTable.Add("http://schemas.datacontract.org/2004/07/Swissmod.Service.Model");
            XmlReader reader = XmlReader.Create(wresp.GetResponseStream(),settings);
            Project p = (Project)serializer.Deserialize(reader);
            return p;
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Implement a JSON Version of the Project Rest Client&lt;/strong&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:90964c01-c022-43d6-9252-5a6dc3e3a775" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    public class ProjectJsonRestClient : ProjectRestClient
    {
        public override Project GetProject(string id)
        {
            WebRequest wr = WebRequest.Create(baseUrl + id + "?format=json");
            wr.Method = "GET";
            WebResponse wresp = wr.GetResponse();
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Project));
            Project p = (Project)serializer.ReadObject(wresp.GetResponseStream());
            return p;
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Give it a whirl&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At this point I know what is going to happen, but I am just protyping to give myself ideas for when I come to make a generation tool for the actual complete feed.&amp;#160; IF I CAN OFCOURSE! lol :-)&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:694c7314-a62d-4ef5-8fad-5ee5fd582e96" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    public static class Program
    {
        const string XML = "XML";
        const string JSON = "JSON";

        [STAThread]
        public static void Main(string[] args)
        {
            IUnityContainer container = new UnityContainer();
            container.RegisterType&amp;lt;ProjectRestClient, ProjectXmlRestClient&amp;gt;(XML, new ContainerControlledLifetimeManager());
            container.RegisterType&amp;lt;ProjectRestClient, ProjectJsonRestClient&amp;gt;(JSON, new ContainerControlledLifetimeManager());

            ProjectRestClient xmlCient = container.Resolve&amp;lt;ProjectRestClient&amp;gt;(XML);
            ProjectRestClient jsonCient = container.Resolve&amp;lt;ProjectRestClient&amp;gt;(JSON);

            Console.WriteLine(xmlCient.GetProject("1"));
            Console.WriteLine(jsonCient.GetProject("1"));

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;P.S. I have used unity here for a few reasons but mainly because I love the idea of Inversion of Control and Dependency Injections.&amp;#160; The above simply allows me to obtain a singleton instance of either class whenever I want to execute a service method.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_4C01CCFC.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="306" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_0C7469AC.png" width="604" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;So to summarise, the only reason I am doing this is so that the consumption of the Rest service is strongly typed, I am not doing this because I think it is a necessity, simply because I think it would be extremely helpful for me.&amp;#160; The ability to strongly type things gives me much more happiness when working across language barriers.&lt;/p&gt;

&lt;p&gt;Anyways,&lt;/p&gt;

&lt;p&gt;Cheers for now,&lt;/p&gt;

&lt;p&gt;Andrew&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6970879" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/eJM7HJSl_uUN_DMHK4-j1cnhfHg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eJM7HJSl_uUN_DMHK4-j1cnhfHg/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/eJM7HJSl_uUN_DMHK4-j1cnhfHg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eJM7HJSl_uUN_DMHK4-j1cnhfHg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=OdruZ_do3Mc:NEqWKPe0k44:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=OdruZ_do3Mc:NEqWKPe0k44:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=OdruZ_do3Mc:NEqWKPe0k44:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=OdruZ_do3Mc:NEqWKPe0k44:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=OdruZ_do3Mc:NEqWKPe0k44:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=OdruZ_do3Mc:NEqWKPe0k44:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/OdruZ_do3Mc" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/WCF/default.aspx">WCF</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/03/17/idea-for-a-helper-utility-class-generator-for-a-wcf-rest-service.aspx</feedburner:origLink></item><item><title>My Jquery Plugins : Fader</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/f5Hz2HAbv9k/my-jquery-plugins-fader.aspx</link><pubDate>Sun, 15 Mar 2009 09:59:11 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6964302</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6964302</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/03/15/my-jquery-plugins-fader.aspx#comments</comments><description>&lt;p&gt;This plug-in I made is quite handy and has a few applications.&amp;#160; I think JQuery is a fantastic library for javascript, as it does what it says on the tin:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;WRITE LESS, DO MORE&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Ok so the fader, I have written this plugin with a few options, which are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;slideClass      &lt;ul&gt;       &lt;li&gt;This is a JQuery selector syntax &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;slideDuration      &lt;ul&gt;       &lt;li&gt;This duration that the currently item stays visible for &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;fadeOutDuration      &lt;ul&gt;       &lt;li&gt;The duration it takes for an item to fade out &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;fadeInDuration      &lt;ul&gt;       &lt;li&gt;The duration it takes for an item to fade in &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The structure which the plugin expects is simply a container element e.g. a div and subsequent nested containers which it will apply its effect to:&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7f25708a-484e-4524-ade1-dbc777148caa" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    &amp;lt;div class="slides"&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 1&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 2&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 3&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 4&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To trigger this function as soon as possible I place the following just before the end of the body tag:&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:04522b26-a24d-4102-a459-dcf062a2fe8a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;...  
	&amp;lt;script type="text/javascript"&amp;gt;
        (function() {
            var options = {
                slideClass: ".slide",
                slideDuration: 6000,
                fadeOutDuration: 2000,
                fadeInDuration: 500
            };

            $(".slides").fader(options);
        })();
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So if we look at the above HTML structure inline with the js, you can see the selector of “.slide” which tells the plugin which items to fade in/out.&amp;#160; You can apply this to many different containers with different options, the below shows an example of this with different speeds.&amp;#160; The html markup is as follows:&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e6158c3d-bd74-400b-bb07-6e40943c3db7" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    &amp;lt;div class="slides"&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 1&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 2&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 3&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 4&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    
   &amp;lt;div class="slides2"&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 1&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 2&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 3&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="slide"&amp;gt;
            &amp;lt;h1&amp;gt;Slide 4&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This time I create a second container of class “slides2” but keep the containing elements with class of “slide.” To start the plugin on both containers I add another instance of options and select the second container.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:41fed7c6-64d4-4878-94cd-b20683e83e11" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;...
	&amp;lt;script type="text/javascript"&amp;gt;
        (function() {
            var options = {
                slideClass: ".slide",
                slideDuration: 6000,
                fadeOutDuration: 2000,
                fadeInDuration: 500
            };

            var options2 = {
                slideClass: ".slide",
                slideDuration: 2000,
                fadeOutDuration: 500,
                fadeInDuration: 500
            };

            $(".slides").fader(options);
            $(".slides2").fader(options2);
        })();
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;The Plug-in Code&lt;/h2&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:12259b52-8858-4c3b-9ef3-4ff6918700de" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;jQuery.fn.fader = function(options) {
    if (!options.slideClass || options.slideClass == "") {
        var error = new Error();
        error.message = "No slide class has been supplied";
    }

    if (!options.slideDuration || !parseInt(options.slideDuration)) {
        options.slideDuration = 4000;
    }

    if (!options.fadeOutDuration || !parseInt(options.fadeOutDuration)) {
        options.fadeOutDuration = 4000;
    }


    if (!options.fadeInDuration || !parseInt(options.fadeInDuration)) {
        options.fadeInDuration = 4000;
    }

    return this.each(function() {
        $(options.slideClass, this).hide();
        $(options.slideClass + ":eq(0)", this).show();
        var currentIndex = 0;
        var obj = this;
        var t = setInterval(function() {
        $(options.slideClass + ":eq(" + currentIndex + ")", obj).fadeOut(options.fadeOutDuration, function() {
                currentIndex++;
                if (currentIndex &amp;gt; $(options.slideClass, obj).size() - 1)
                    currentIndex = 0;
                $(options.slideClass + ":eq(" + currentIndex + ")", obj).fadeIn(options.fadeInDuration);
            });
        }, options.slideDuration);
    });
};&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6964302" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6IPsHF1OxSTgrt8NrKu6M5238ps/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6IPsHF1OxSTgrt8NrKu6M5238ps/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/6IPsHF1OxSTgrt8NrKu6M5238ps/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6IPsHF1OxSTgrt8NrKu6M5238ps/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=f5Hz2HAbv9k:dn37eaw_9OI:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=f5Hz2HAbv9k:dn37eaw_9OI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=f5Hz2HAbv9k:dn37eaw_9OI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=f5Hz2HAbv9k:dn37eaw_9OI:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=f5Hz2HAbv9k:dn37eaw_9OI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=f5Hz2HAbv9k:dn37eaw_9OI:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/f5Hz2HAbv9k" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Javascript/default.aspx">Javascript</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/03/15/my-jquery-plugins-fader.aspx</feedburner:origLink></item><item><title>Useful DateTime functions in JavaScript based on .NET DateTime</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/UMyadZrb2eg/useful-datetime-functions-in-javascript-based-on-net-datetime.aspx</link><pubDate>Fri, 06 Mar 2009 08:52:14 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6941766</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6941766</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/03/06/useful-datetime-functions-in-javascript-based-on-net-datetime.aspx#comments</comments><description>&lt;p&gt;A question recently on &lt;a href="http://www.stackoverflow.com" target="_blank"&gt;StackOverflow.com&lt;/a&gt; triggered me to think that it would be nice if in JavaScript I could do this:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1c28cbdc-406f-4075-83c9-7a07050087f4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;var d = new Date();
d.AddDays(1);&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;So exactly like what I can do in .NET.&amp;#160; I know a lot of people try and achieve date solutions by concatenating strings and parsing as a date, but this is not an option for me as JavaScript’s native DateTime is very powerful and due to this, there is absolutely no need to be hashing together strings.&amp;#160; So I will now paste the functionailty in C# that I based my methods on, dead simple, it is:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:64252117-7e04-4e3d-b607-a128527b0315" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    DateTime d = new DateTime();

    public void Page_Load(object sender, EventArgs e)
    {
        DateTime days = d.AddDays(1);
        DateTime hours = d.AddHours(1);
        DateTime milliseconds = d.AddMilliseconds(1);
        DateTime minutes = d.AddMinutes(1);
        DateTime months = d.AddMonths(1);
        DateTime seconds = d.AddSeconds(1);
    }&lt;/pre&gt;&lt;/div&gt;
So to exploit another JavaScript feature I will use prototype to extend the methods of the Date type inside javascript.&amp;#160; C# now has extension methods which are quite similar in what they allow you to use them like.&amp;#160; So the prototypes I want to create are as follows:

&lt;p&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AddDays &lt;/li&gt;

  &lt;li&gt;AddHours &lt;/li&gt;

  &lt;li&gt;AddMilliseconds &lt;/li&gt;

  &lt;li&gt;AddMinutes &lt;/li&gt;

  &lt;li&gt;AddMonths &lt;/li&gt;

  &lt;li&gt;AddSeconds &lt;/li&gt;
&lt;/ul&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e1171b28-3de4-43ec-9459-8e92e6383535" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    &amp;lt;script type="text/javascript"&amp;gt;

        Date.prototype.AddDays = function(days) {
            this.setDate(this.getDate() + days);
            return this;
        }

        Date.prototype.AddHours = function(hours) {
            this.setHours(this.getHours() + hours);
            return this;
        }

        Date.prototype.AddMilliseconds = function(milliseconds) {
            this.setMilliseconds(this.getMilliseconds() + milliseconds);
            return this;
        }

        Date.prototype.AddMinutes = function(minutes) {
            this.setMinutes(this.getMinutes() + minutes, this.getSeconds(), this.getMilliseconds());
            return this;
        }

        Date.prototype.AddMonths = function(months) {
            this.setMonth(this.getMonth() + months, this.getDate());
            return this;
        }

        Date.prototype.AddSeconds = function(seconds) {
            this.setSeconds(this.getSeconds() + seconds, this.getMilliseconds());
            return this;
        }

        Date.prototype.AddYears = function(years) {
            this.setFullYear(this.getFullYear() + years);
            return this;
        }
    
    &amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Excellent, nice clean, precise code.&amp;#160; So with this I can now do the following:&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:6f7080cf-e07d-472a-8f41-75339b44564c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;        &amp;lt;script type="text/javascript"&amp;gt;
            var d = new Date();
            
            var output = d.AddDays(1).toString() + "&amp;lt;br/&amp;gt;" +
            d.AddHours(1).toString() + "&amp;lt;br/&amp;gt;" +
            d.AddMilliseconds(1).toString() + "&amp;lt;br/&amp;gt;" +
            d.AddMinutes(1).toString() + "&amp;lt;br/&amp;gt;" +
            d.AddMinutes(1).toString() + "&amp;lt;br/&amp;gt;" +
            d.AddMonths(1).toString() + "&amp;lt;br/&amp;gt;" +
            d.AddSeconds(1).toString() + "&amp;lt;br/&amp;gt;" +
            d.AddYears(1).toString() + "&amp;lt;br/&amp;gt;";

            document.write(output);
        
        &amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;With the output of&lt;/p&gt;

&lt;p&gt;Sat Mar 07 2009 08:41:09 GMT+0000 (GMT Standard Time) 
  &lt;br /&gt;Sat Mar 07 2009 09:41:09 GMT+0000 (GMT Standard Time) 

  &lt;br /&gt;Sat Mar 07 2009 09:41:09 GMT+0000 (GMT Standard Time) 

  &lt;br /&gt;Sat Mar 07 2009 09:42:09 GMT+0000 (GMT Standard Time) 

  &lt;br /&gt;Sat Mar 07 2009 09:43:09 GMT+0000 (GMT Standard Time) 

  &lt;br /&gt;Tue Apr 07 2009 09:43:09 GMT+0100 (GMT Daylight Time) 

  &lt;br /&gt;Tue Apr 07 2009 09:43:10 GMT+0100 (GMT Daylight Time) 

  &lt;br /&gt;Wed Apr 07 2010 09:43:10 GMT+0100 (GMT Daylight Time)&lt;/p&gt;

&lt;p&gt;Obviously if you want to subtract values from a date you would provide negative values into the methods, i.e. DateTime.AddDays(-10);&lt;/p&gt;

&lt;p&gt;Cheers for now,&lt;/p&gt;

&lt;p&gt;Andy&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6941766" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/R1dVngzelruD2IY87MGbQshnc5s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/R1dVngzelruD2IY87MGbQshnc5s/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/R1dVngzelruD2IY87MGbQshnc5s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/R1dVngzelruD2IY87MGbQshnc5s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=UMyadZrb2eg:Odrcvqj2TYE:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=UMyadZrb2eg:Odrcvqj2TYE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=UMyadZrb2eg:Odrcvqj2TYE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=UMyadZrb2eg:Odrcvqj2TYE:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=UMyadZrb2eg:Odrcvqj2TYE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=UMyadZrb2eg:Odrcvqj2TYE:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/UMyadZrb2eg" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/03/06/useful-datetime-functions-in-javascript-based-on-net-datetime.aspx</feedburner:origLink></item><item><title>Nice quick JQuery plugin</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/6m2EKuH6yCw/nice-quick-jquery-plugin.aspx</link><pubDate>Thu, 05 Mar 2009 20:10:37 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6939438</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6939438</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/03/05/nice-quick-jquery-plugin.aspx#comments</comments><description>&lt;p&gt;I think I am thinking too much about how to write a good blog post.&amp;#160; I think I need to master letting my brain flow while intercepting the output and tweaking things.&amp;#160; Well I have not yet mastered it, but I shall continue to try.&amp;#160; I was asked today to create a simple JQuery plug in which showed an html element containing a links title and this should be able to be styled and also follow the mouse whilst in hover state.&amp;#160; It is kinda like a pimped up tooltip.&amp;#160; The only thing out of the ordinary I did was hijack the rel attribute of the link as, if I continued to use the title attribute I got the default browser tooltip which overlaid my DHTML div.&amp;#160; I was thinking about creating my own attribute to add to the tag, but then again this would probably fail XHTML Validation.&amp;#160; This makes me wonder because from what I have read the new and upcoming version of the ASP.NET Ajax library introduce different attributes to the HTML.&amp;#160; Not sure if this is due to be released with the next iteration of the HTML standard.&lt;/p&gt;  &lt;p&gt;Write to my plug in.&amp;#160; Here is the actual code I wrote for the plug in itself:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:089a49fb-60a2-4e27-962f-332caaf4a0e9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;        jQuery.fn.popupLinkHelper = function(options) {
            var element = document.createElement("div");
            $(element).addClass(options.popupCssClass).hide();
            document.body.appendChild(element);

            return this.each(function() {
                $(this).hover(function() {
                    $(element).show();
                    $(element).html($(this).attr("rel"));
                    $(this).mousemove(function(e) {
                        $(element).css({
                            "position": "absolute",
                            "top": e.pageY + options.offsetY,
                            "left": e.pageX + options.offsetX
                        });
                    });
                }, function() {
                    $(element)
                });
            });
        };&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;To give an example using CSS I used the following CSS class to spruce up the popup:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5a459445-102b-44ee-a541-bdbdfb401ee5" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;        .popup
        {
            width: 150px;
            padding: 10px;
            background-color: #3366CC;
            border: black 2px solid;
            color: White;
        }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;To trigger this code I use a notation publicised on the JQuery plug in authoring page.&amp;#160; As well I threw in some configuration options to as to be able to have more flexibility with it in the future:&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e7299a17-e8e2-4baf-bd6e-e11eb0d04d14" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    &amp;lt;script type="text/javascript"&amp;gt;
        $(function() {
            var options = {
                offsetX: 50,
                offsetY: 0,
                popupCssClass: "popup"
            };
            $("a.pol").popupLinkHelper(options);
        });
    &amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To test the following out I simply created a ul li block using the class pol (Pop out link – :-P) to identify those which I would target with the plug in.&lt;/p&gt;

&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:438b1792-00e8-414e-b371-256332ef0879" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;    &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;a href="#" rel="This is example 1" class="pol"&amp;gt;Example Link 1&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_4EAE8194.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="194" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_73CBCC00.png" width="620" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Cheers for now:&lt;/p&gt;

&lt;p&gt;Andrew,&lt;/p&gt;

&lt;p&gt;P.S. Cross Browser Transparent Rounded Corners which is compatible with IE 6 – This is like Rocking Horse Muck, so hard to find lol.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6939438" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ew4VNK8a8pyv-BOeGggj93SoaDg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ew4VNK8a8pyv-BOeGggj93SoaDg/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/Ew4VNK8a8pyv-BOeGggj93SoaDg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ew4VNK8a8pyv-BOeGggj93SoaDg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=6m2EKuH6yCw:LpX0FFIBsAQ:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=6m2EKuH6yCw:LpX0FFIBsAQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=6m2EKuH6yCw:LpX0FFIBsAQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=6m2EKuH6yCw:LpX0FFIBsAQ:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=6m2EKuH6yCw:LpX0FFIBsAQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=6m2EKuH6yCw:LpX0FFIBsAQ:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/6m2EKuH6yCw" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Javascript/default.aspx">Javascript</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/03/05/nice-quick-jquery-plugin.aspx</feedburner:origLink></item><item><title>IIS and Virtual Directories and their usefulness</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/lJW2JHY6RDk/iis-and-virtual-directories-and-their-usefulness.aspx</link><pubDate>Fri, 27 Feb 2009 09:14:39 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6930366</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6930366</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/02/27/iis-and-virtual-directories-and-their-usefulness.aspx#comments</comments><description>&lt;p&gt;I had a requirement of late where by I wanted to share a Master Page over many physical sub sites, i.e.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Main Website (www.mainsite.com)      &lt;ul&gt;       &lt;li&gt;Sub Site 1 (www.subsite1.com) &lt;/li&gt;        &lt;li&gt;Sub Site 2 (www.subsite2.com) &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;etc… &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It was at this point when I thought of virtual directories and really just, again, stood back and admired the work which must have gone into such a methodology and the output which is so simple to use and yet so powerful.&amp;#160; If you have not used Virtual Directories before or you have heard of them but not quite GOT what they are about or their purpose then you may find this post useful.&lt;/p&gt;  &lt;p&gt;Ignoring the master pages for now, say that you want to share a common CSS style sheet across many different websites, with the style sheet residing inside a main website.&amp;#160; So here is an example folder structure of the main website or a snippet:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;wwwroot      &lt;ul&gt;       &lt;li&gt;www.mainsite.com          &lt;ul&gt;           &lt;li&gt;assets              &lt;ul&gt;               &lt;li&gt;css                  &lt;ul&gt;                   &lt;li&gt;sharedStyle.css &lt;/li&gt;                 &lt;/ul&gt;               &lt;/li&gt;             &lt;/ul&gt;           &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ok, now I zip over to my other physical web site in IIS called www.subsite1.com and before I do anything, I right click and add a virtual directory.&amp;#160; I give it an alias of assets and point it at the physical path of the above assets folder inside the www.mainsite.com website folder.&amp;#160; Now once you have done this, you will see a folder with a shortcut icon, i.e. Virtual.&amp;#160; &lt;/p&gt;  &lt;p&gt;What does this mean?&amp;#160; Well if you then create a simple html page, and you want to include the css, your css line would be the same as the one used for the www.mainsite.com .&lt;/p&gt;  &lt;p&gt;www.mainsite.com –&amp;gt; /assets/css/sharedStyle.css&lt;/p&gt;  &lt;p&gt;www.subsite1.com –&amp;gt; /assets/css/sharedStyle.css&lt;/p&gt;  &lt;p&gt;If you were to go inside the folder for www.subsite1.com inside windows explorer, all you would see is this simple html page you made, and not the actual folder you are referencing, so it is virtual in every sense, albeit 1, of the word.&lt;/p&gt;  &lt;p&gt;So if you need to change any common styles, for the many websites which used the above style sheet in my example you have consolidated the changes to one single location.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/image_607D9FDC.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="130" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/image_thumb_268E5CF0.png" width="233" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6930366" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NICJnelLlLXSwFkObwXPkAnXjXs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NICJnelLlLXSwFkObwXPkAnXjXs/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/NICJnelLlLXSwFkObwXPkAnXjXs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NICJnelLlLXSwFkObwXPkAnXjXs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=lJW2JHY6RDk:dqRKrGS-SBk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=lJW2JHY6RDk:dqRKrGS-SBk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=lJW2JHY6RDk:dqRKrGS-SBk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:KwTdNBX3Jqk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=lJW2JHY6RDk:dqRKrGS-SBk:KwTdNBX3Jqk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:l6gmwiTKsz0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=l6gmwiTKsz0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?i=lJW2JHY6RDk:dqRKrGS-SBk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewRea?a=lJW2JHY6RDk:dqRKrGS-SBk:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewRea?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/lJW2JHY6RDk" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/IIS/default.aspx">IIS</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/02/27/iis-and-virtual-directories-and-their-usefulness.aspx</feedburner:origLink></item><item><title>Comparing Byte Arrays in C# and more specifically using the .NET 3.5 Framework</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/_mhWKg19_AQ/comparing-byte-arrays-in-c-and-more-specifically-using-the-net-3-5-framework.aspx</link><pubDate>Fri, 20 Feb 2009 11:17:38 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6917675</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6917675</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/02/20/comparing-byte-arrays-in-c-and-more-specifically-using-the-net-3-5-framework.aspx#comments</comments><description>&lt;p&gt;I was looking for a simple way of comparing two byte arrays and it is not as 123 as you may think as methods which you may assume would return true, DO NOT.&amp;#160; I found a solution that does exactly what I need and is part of the framework, and I found it on the link below.&amp;#160; It also contains examples at the beginning which may surprise you:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.tatham.oddie.com.au/2008/07/01/comparing-byte-arrays-in-c-or-at-least-trying-to/" target="_blank"&gt;http://blog.tatham.oddie.com.au/2008/07/01/comparing-byte-arrays-in-c-or-at-least-trying-to/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To summarize the method I am speaking of is the following:&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:77c1b741-64b7-4ef8-9551-a6005501991c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public static bool SequenceEqual&amp;lt;TSource&amp;gt;(this System.Collections.Generic.IEnumerable&amp;lt;TSource&amp;gt; first, System.Collections.Generic.IEnumerable&amp;lt;TSource&amp;gt; second)
    Member of System.Linq.Enumerable

Summary:
Determines whether two sequences are equal by comparing the elements by using the default equality comparer for their type.&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And it was from a comment may by a guy calling himself &lt;strong&gt;RichB &lt;/strong&gt;in the blog post above.&amp;#160; Great find!&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Andrew&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6917675" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tFB732Crnr5XWeroxZ7Ig_xVjZg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tFB732Crnr5XWeroxZ7Ig_xVjZg/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/tFB732Crnr5XWeroxZ7Ig_xVjZg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tFB732Crnr5XWeroxZ7Ig_xVjZg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=5SCxaff0"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=rRN7g18f"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=rRN7g18f" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=2P3iiz3y"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=Qvx7uEPq"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=Qvx7uEPq" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=LCCk0r40"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=L1RG6X1E"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=L1RG6X1E" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=yf0sBKv2"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=yf0sBKv2" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=A4mxJjsm"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=PBELG6gc"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=PBELG6gc" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=jvnnC1YJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/_mhWKg19_AQ" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/C_2300_/default.aspx">C#</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/02/20/comparing-byte-arrays-in-c-and-more-specifically-using-the-net-3-5-framework.aspx</feedburner:origLink></item><item><title>IDE Features I find useful – Visual Studio</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/adzSI8Ya0GM/ide-features-i-find-useful-visual-studio.aspx</link><pubDate>Thu, 19 Feb 2009 16:04:01 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6916934</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6916934</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/02/19/ide-features-i-find-useful-visual-studio.aspx#comments</comments><description>&lt;p&gt;This is a short but one of many of a series of blog posts I would like to make which mention some of the useful features of different IDEs which I make use of.&amp;#160; This one is for Visual Studio:&lt;/p&gt;  &lt;h3&gt;Full Screen&lt;/h3&gt;  &lt;p&gt;View –&amp;gt; Full Screen (Shift + Alt + Enter)&lt;/p&gt;  &lt;p&gt;I love this feature, so say you have a certain layout set up for a particular type of project you are i.e. testing or deving etc… and you feel you would prefer some more space to code or design with, just hit Full Screen mode and you have it, then when you exit Full Screen mode, you layout persists.&amp;#160; Extremely useful&lt;/p&gt;  &lt;h3&gt;//TODO : bla bla bla (TASK LIST)&lt;/h3&gt;  &lt;p&gt;This is a feature which Visual Studio automatically recognizes and places in your Task List.&amp;#160; May be you are reviewing someones work and instead of rtackling each point as your come across it, you are able to go through all of it making the relevant //TODO: DELETE UNUSED CODE!!&amp;#160; then once finished Visual Studio has compiled a nice ordered task list for you to tackle.&amp;#160; Great organisational feature I reckon.&lt;/p&gt;  &lt;h3&gt;Bookmarks&lt;/h3&gt;  &lt;p&gt;View –&amp;gt; Other Windows –&amp;gt; Bookmark Window&lt;/p&gt;  &lt;p&gt;I find this feature extremely handy in a couple of immediate situations:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I am tracking down a procedure in code and it spans several classes, so I want to be able to jump quickly to the relevant parts so I can analyze. &lt;/li&gt;    &lt;li&gt;I am dealing with a single but extremely long code file and to preserve my sanity I set book marks while&lt;em&gt;&amp;#160;&lt;/em&gt;I scan down the code.&amp;#160; This way I am able to jump back and fourth to parts when i need. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;You can also organize your book marks into folders.&amp;#160; I mean you could follow a procedural approach and really go deep with these and use every time you code.&amp;#160; I would say overkill but if you get used to something and it works, why stop?&lt;/p&gt;  &lt;h3&gt;Encapsulate Variables&lt;/h3&gt;  &lt;p&gt;For example, right click on a private variable and encapsulate.&amp;#160; I think this is an extremely handy feature BUT, I do prefer the one inside Net Beans which I have detailed here: &lt;a href="http://www.andrewrea.co.uk/2009/01/17/NetBeansIDEFeatureIWouldLikeToSeeInsideVisualStudio.aspx" target="_blank"&gt;Net Beans Encapsulation Feature&lt;/a&gt;.&amp;#160; I know you can get this functionality with Refactor program etc… but I would like to focus on out of the box things, oh and ignoring the extensibility lol if I am allowed to say that :-)&lt;/p&gt;  &lt;h3&gt;Conditional Breakpoints&lt;/h3&gt;  &lt;p&gt;I like the way I can set conditional break points based on the context of the currently running code, so that I can dig into exactly what I require.&amp;#160; For example, If I place a breakpoint inside a for iteration, I can state that i only want the break point to be hit when the counter, lets say x, is 3 .&amp;#160; &lt;/p&gt;  &lt;h3&gt;Split Screen Design/Markup and Split Horizontal Screen View&lt;/h3&gt;  &lt;p&gt;I think the first is new in Visual Studio 2008, and I do no actually have much use for it, as I very rarely look at the design for a web application in the GUI, but for the likes of WPF and windows development it is a really good feature and one which i am sure many people would not like to loose.&lt;/p&gt;  &lt;p&gt;The second is when for example you drag an editor tab to the right or left and Visual Studio gives you the option to create another window horizontally next the the original.&amp;#160; This is good when you need to write code with immediate reference to another context.&lt;/p&gt;  &lt;h3&gt;prop tab tab&lt;/h3&gt;  &lt;p&gt;If you type prop and then hit the tab key twice you are very conveniently given a property stub like the following:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:65dae356-2554-4e7e-89d5-e22b3fe9152a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="c#"&gt;public int MyProperty { get; set; }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The type and the property name will be like a snippet where by you can tab into and out of each whilst editing, and when complete hit return and repeat the process.&amp;#160; It is not very useful how ever if you want to design components and you need to raise property changed events and such things.&amp;#160; I have no doubt this could be achieved through reflection but me personally I would simply use the complete property syntax if required.&lt;/p&gt;

&lt;h3&gt;Export Template&lt;/h3&gt;

&lt;p&gt;File –&amp;gt; Export Template&lt;/p&gt;

&lt;p&gt;This is a nice tool, where you can export either a project template or export an item template.&amp;#160; For example lets say I create a new MVC application and add references to the Microsoft Patterns and Practices Enterprise Library.&amp;#160; I would then like to export this, so i have the option of creating a new MVC site which already contains all the references I need for the EntLib.&lt;/p&gt;

&lt;p&gt;The second option for the Item Template, for example, lets say you create a custom web control and it will require control state and also notification of post backs.&amp;#160; You could override the two methods for the saving and loading of control state and implement the methods for the IPostBackDataHandler.&amp;#160; Export this ItemTemplate and in future you can now create web control&amp;#160; with the above already present saving you time.&amp;#160; Check out my post which details what i am talking about here : &lt;a href="http://www.andrewrea.co.uk/2009/01/17/DevelopingASPNETCustomControlsMethodSingleResponsibilityAndAnEasierWayToManageLargeDataForms.aspx" target="_blank"&gt;Custom ASP.NET Components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Funny yet I suppose still valid point: One place i used to work they actually exported a template for an ENUM!!&amp;#160; Is this necessary and productive or just sheer lazy.&amp;#160; Can I create a file and type an enum shell just as fast? hmmm I suppose I am adding one extra step doing it my way so in those terms it is more productive.&amp;#160; &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6916934" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xjbEz5Z1Xwm4rtcf79asP6QJgBc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xjbEz5Z1Xwm4rtcf79asP6QJgBc/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/xjbEz5Z1Xwm4rtcf79asP6QJgBc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xjbEz5Z1Xwm4rtcf79asP6QJgBc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=cyxnti4w"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=drR7PYbK"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=drR7PYbK" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=s0nEBuOD"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=ljdoBQZH"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=ljdoBQZH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=00SGslEM"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=M2ragPgk"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=M2ragPgk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=lzP1WaC2"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=lzP1WaC2" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=ZmZl4wRM"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=ym0FW75t"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=ym0FW75t" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=c87xjtbT"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/adzSI8Ya0GM" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/02/19/ide-features-i-find-useful-visual-studio.aspx</feedburner:origLink></item><item><title>CascadingDropDownExtender setting SelectedValue</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/FjsMrJxYLFc/cascadingdropdownextender-setting-selectedvalue.aspx</link><pubDate>Tue, 27 Jan 2009 11:09:07 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6861412</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6861412</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/01/27/cascadingdropdownextender-setting-selectedvalue.aspx#comments</comments><description>&lt;p&gt;I had a situation recently where:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I needed a cascading drop down interface &lt;/li&gt;    &lt;li&gt;I needed it to execute on the client &lt;/li&gt;    &lt;li&gt;I needed to reload the parent and child items' selection. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The Cascading DropDownList Extender is an excellent control as are its siblings inside the AjaxControlToolkit.&amp;#160; At first I was scouring the outputted JavaScript that it uses inline with the ServiceMethod to find a method by which I could programmatically set the selected index, which in turn should trigger the data retrieval.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;quot;All other things being equal, &lt;em&gt;the simplest solution&lt;/em&gt; is the &lt;em&gt;best&lt;/em&gt;.&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Occam's_razor"&gt;Occam's razor&lt;/a&gt;&lt;/p&gt;  &lt;h4&gt;It was at this point I saw that the Cascading DropDownList extender actually has a SelectedValue property.&amp;#160; I could have kicked myself when i saw it, as really I should have researched the control more and its capabilities and limitations.&amp;#160; Ever heard of the 7 P's - British SAS lol ?&lt;/h4&gt;  &lt;p&gt;So I integrated it with a control I built.&amp;#160; The control was a Region, County, TownCity and Area selection in respective order, so as to bring more structure to clients addresses for a project I am currently on.&amp;#160; Similar to a previous post where I create a &lt;a title="ASP.NET Custom Composite Controls" href="http://www.andrewrea.co.uk/2009/01/17/DevelopingASPNETCustomControlsMethodSingleResponsibilityAndAnEasierWayToManageLargeDataForms.aspx"&gt;composite control&lt;/a&gt; I declare the control extenders inside this custom composite control and control which I render dependant on other properties which are set.&amp;#160; &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:812469c5-0cb0-4c63-8c15-c81123a09de7:01916f08-aaab-4436-84d5-a35888fbe20d" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;        private void CreateRegion()
        {
            DropDownListRegion = new DropDownList();
            DropDownListRegion.ID = this.ID + "_DropDownListRegion";
            CascadingDropDownRegion = new CascadingDropDown();
            CascadingDropDownRegion.ID = this.ID + "_CascadingDropDownRegion";
            CascadingDropDownRegion.Category = REGION_CATEGORY;
            CascadingDropDownRegion.EmptyText = REGION_EMPTYTEXT;
            CascadingDropDownRegion.EmptyValue = "0";
            CascadingDropDownRegion.LoadingText = REGION_LOADINGTEXT;
            CascadingDropDownRegion.PromptText = REGION_PROMPTTEXT;
            CascadingDropDownRegion.PromptValue = "0";
            CascadingDropDownRegion.ServiceMethod = REGION_SERVICE_METHOD;
            CascadingDropDownRegion.ServicePath = SERVICE_PATH;
            CascadingDropDownRegion.TargetControlID = DropDownListRegion.ID;
            if (RegionID != 0)
                CascadingDropDownRegion.SelectedValue = RegionID.ToString();
            Controls.Add(DropDownListRegion);
            Controls.Add(CascadingDropDownRegion);


            if (UseAddressLevel == AddressLevel.Region)
            {
                RequiredFieldValidatorRegion = new RequiredFieldValidator();
                RequiredFieldValidatorRegion.ID = this.ID + "_RequiredFieldValidatorRegion";
                RequiredFieldValidatorRegion.ControlToValidate = DropDownListRegion.ID;
                RequiredFieldValidatorRegion.InitialValue = "0";

                ValidatorCalloutExtenderRegion = new ValidatorCalloutExtender();
                ValidatorCalloutExtenderRegion.ID = this.ID + "_ValidatorCalloutExtenderRegion";
                ValidatorCalloutExtenderRegion.TargetControlID = RequiredFieldValidatorRegion.ID;

                Controls.Add(RequiredFieldValidatorRegion);
                Controls.Add(ValidatorCalloutExtenderRegion);
            }
        }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/CascadingDropDownExtendersettingSelected_105EE/image_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/CascadingDropDownExtendersettingSelected_105EE/image_thumb.png" width="604" height="346" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the whole thing above is a control, but the amount of collapsible extenders displayed is control by an enum called AddressLevel.&amp;#160; How it works is simply like this, if you only require the Town and City, it is this level with which you set it, what happens then is that the area will not be displayed and also the TownAndCity will gain validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Line 16&lt;/strong&gt; of the code above will set selected index based on whether the RegionID has been set.&amp;#160; I find it so handy and useful that I can strongly type my .NET controls to work with the control extenders as it just adds a greater level to the UI experience.&amp;#160; Strongly Typing Javascript is also a good IDEA and something which I want to touch on in later posts aswell.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Andrew&lt;/p&gt;

&lt;p&gt;P.S. setting the selected index for multiple cascading dropdownlists will work so its parent gets populated and set's the selected value using client side code, the child cascading dropdownlist will wait for this event, then populate and THEN check for the presence of the selected value in its items and again use client side to set the selected index.&amp;#160; After that it &lt;strong&gt;CASCADES&lt;/strong&gt;!! lol&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6861412" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wd10voXT2NrgFaA92fAx6y9cblk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wd10voXT2NrgFaA92fAx6y9cblk/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/wd10voXT2NrgFaA92fAx6y9cblk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wd10voXT2NrgFaA92fAx6y9cblk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=IleZt8sG"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=URW3mvaG"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=URW3mvaG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=Gb9CVjzo"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=ObmXcWEv"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=ObmXcWEv" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=IDpScJmL"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=ynw62GqB"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=ynw62GqB" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=TufofwYW"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=TufofwYW" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=xyzlJO6B"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=5pWh52r5"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=5pWh52r5" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=WvtWJG3R"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/FjsMrJxYLFc" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/C_2300_/default.aspx">C#</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/01/27/cascadingdropdownextender-setting-selectedvalue.aspx</feedburner:origLink></item><item><title>NetBeans IDE Feature I would like to see inside Visual Studio</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/KSRS8iY77AM/netbeans-ide-feature-i-would-like-to-see-inside-visual-studio.aspx</link><pubDate>Sat, 17 Jan 2009 13:15:08 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6842839</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6842839</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/01/17/netbeans-ide-feature-i-would-like-to-see-inside-visual-studio.aspx#comments</comments><description>&lt;p&gt;I am currently inside the NetBeans IDE which is my IDE of choice at the moment for my Java development.&amp;#160; I thought I would mention a refactoring feature I would like to see inside Visual Studio &amp;quot;Out of the Box.&amp;quot;&amp;#160; It is with regards to the encapsulation of fields.&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Yes you can create a class diagram and encapsulate a field &lt;/li&gt;    &lt;li&gt;Yes you can right click in code view and encapsulate a field &lt;/li&gt;    &lt;li&gt;Yes you can download, purchase or create a plug in to do the following &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;BUT, I would like to see two things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The following functionality out of the box ready &lt;/li&gt;    &lt;li&gt;The ability to encapsulate a selection of fields or to be able to select the fields you would like to encapsulate inside a nice GUI Dialogue. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Some may say lazy, others may say more productive.&amp;#160; In NetBeans I can go to the refactor menu and click encapsulate fields and I am presented with a nice dialogue where I can select the fields I would like to encapsulate and also a few more properties to describe the encapsulation I desire for each field.&amp;#160; Just saves time in my view.&lt;/p&gt; &lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/NetBeansIDEFeatureIwouldliketoseeinsideV_B6B2/image_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/NetBeansIDEFeatureIwouldliketoseeinsideV_B6B2/image_thumb.png" width="604" height="372" /&gt;&lt;/a&gt;   &lt;p&gt;I am greedy lol, what I would also like to see form the NetBeans dialogue above is also to open it up after refactoring and being able to edit.&amp;#160; That would be really useful.&amp;#160; I am going to download Visual Studio 2010 and see what is new and going on lol.&amp;#160; It can be found here:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&amp;amp;displaylang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Cheers,&lt;/p&gt;  &lt;p&gt;Andrew&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6842839" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ivWYxwRVFOsO11YPBcdIFKSuPVg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ivWYxwRVFOsO11YPBcdIFKSuPVg/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/ivWYxwRVFOsO11YPBcdIFKSuPVg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ivWYxwRVFOsO11YPBcdIFKSuPVg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=5bYfx35X"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=DMDHiKok"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=DMDHiKok" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=y1PSnT3b"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=OLfTjYWM"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=OLfTjYWM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=3vLJAwpz"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=gxWcotHh"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=gxWcotHh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=v6t8EO4M"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=v6t8EO4M" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=dmwViNGA"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=1cw2RlwD"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=1cw2RlwD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=xsZMUW33"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/KSRS8iY77AM" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/C_2300_/default.aspx">C#</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/01/17/netbeans-ide-feature-i-would-like-to-see-inside-visual-studio.aspx</feedburner:origLink></item><item><title>Developing ASP.NET Custom Controls, Method Single Responsibility and an easier way to manage large data forms</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/LJ3T4nHJOgY/developing-asp-net-custom-controls-method-single-responsibility-and-an-easier-way-to-manage-large-data-forms.aspx</link><pubDate>Sat, 17 Jan 2009 12:03:19 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6842734</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6842734</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/01/17/developing-asp-net-custom-controls-method-single-responsibility-and-an-easier-way-to-manage-large-data-forms.aspx#comments</comments><description>&lt;p&gt;&lt;a title="Download Files" href="http://www.andrewrea.co.uk/PageInformationControl.rar"&gt;You can download the files here.&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Until a few weeks ago I did not know about a feature called Control State.&amp;#160; I knew of course about ViewState but not Control State.&amp;#160; I would love to know everything about everything in this game i.e. computing, but as you will agree that is extremely difficult to do.&amp;#160; Another ting I have found myself doing in the past is for example using a client side script helper, e.g. calendar date picker, to populate a textbox.&amp;#160; This looks a lot nicer, helps the user and reduces validation errors.&amp;#160; Now getting this value was a case of accessing the Request data for that specific control.&amp;#160; i.e.&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:812469c5-0cb0-4c63-8c15-c81123a09de7:0dfdb80b-a3d8-4ae2-bf7d-f0dacab2e640" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;Request.Form[MyTextBox.UniqueID]&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Because we used a client side script to populate the control the server side TextChanged event would not get fired so we could not unfortunately&amp;#160; do this:&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:812469c5-0cb0-4c63-8c15-c81123a09de7:443649c3-992d-40ab-9d67-94b9b46074e8" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;MyTextBox.Text&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;So, on this occasion a situation arose where by I had to create a few controls, being a custom &lt;strong&gt;HierarchialDataSource&lt;/strong&gt;, a custom &lt;strong&gt;HierarchialDataSourceControl&lt;/strong&gt; and also a nice custom &lt;strong&gt;TreeView&lt;/strong&gt; with valid CSS.&amp;#160; I opted to create my own as opposed to &lt;a title="ASP.NET 2.0 CSS Friendly Control Adapters 1.0" target="_blank" href="http://www.asp.net/CssAdapters/"&gt;CSS Control Adapters&lt;/a&gt; simply because I require some really bespoke features, plus I love learning how to make these things lol.&lt;/p&gt;

&lt;p&gt;Now I am not going into these controls on this post but rather features of them, meaning the &lt;strong&gt;Control State&lt;/strong&gt; and &lt;strong&gt;IPostBackDataHandler&lt;/strong&gt; interface.&amp;#160; The control I want to make today involves 4 fields of which one will be a date field which will use the Ajax Control Toolkit Calendar Extender.&amp;#160; The fields will be &lt;strong&gt;Title, Firstname, Lastname and Date of Birth&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In title I have also stated&amp;#160; &amp;quot;Method Single Responsibility&amp;quot; and my reason for this is because only the other day I was listening to one of Scott Hanselman's pod casts on which he was speaking to Robert C. Martin or &amp;quot;Uncle Bob&amp;quot; as he is known in the programming world.&amp;#160; He stated that Single Responsibility should also be applied to methods as well or reason for change.&amp;#160; It was stated that lots of methods with smaller amounts of code wrapped around a single responsibility was easier to read, debug and maintain that fewer methods with bloated amounts of code which would undoubtedly contain lots of indentations.&amp;#160; So I am applying this, and wonder why I have never done this before, but this is all a learning curve.&lt;/p&gt;

&lt;p&gt;Ok the first thing we will do on this control is create the fields and properties we require.&amp;#160; We will also create another class inside the control with the exact fields and properties as we have for the control, so copy and paste job; this will be used to control the state of the control in a much more strongly typed fashion, in fact truly strongly typed.&amp;#160; So here is the start of the control:&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:812469c5-0cb0-4c63-8c15-c81123a09de7:87020a40-934a-4530-830b-90cef5c41b14" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#:firstline[1]"&gt;   public class PageInformationControl
    {
        #region Fields and Properties
        private string title;
        /// &amp;lt;summary&amp;gt;
        /// The person's title
        /// &amp;lt;/summary&amp;gt;
        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        private string firstname;
        /// &amp;lt;summary&amp;gt;
        /// The person's firstname
        /// &amp;lt;/summary&amp;gt;
        public string Firstname
        {
            get { return firstname; }
            set { firstname = value; }
        }

        private string lastname;
        /// &amp;lt;summary&amp;gt;
        /// The person's lastname
        /// &amp;lt;/summary&amp;gt;
        public string Lastname
        {
            get { return lastname; }
            set { lastname = value; }
        }

        private DateTime dateOfBirth;
        /// &amp;lt;summary&amp;gt;
        /// The person's date of birth
        /// &amp;lt;/summary&amp;gt;
        public DateTime DateOfBirth
        {
            get { return dateOfBirth; }
            set { dateOfBirth = value; }
        }

        #endregion

        #region StateObject

        /// &amp;lt;summary&amp;gt;
        /// An object to store the state of the object between postbacks
        /// &amp;lt;/summary&amp;gt;
        [Serializable]
        protected class PageInformationControlControlState
        {
            private string title;

            public string Title
            {
                get { return title; }
                set { title = value; }
            }

            private string firstname;

            public string Firstname
            {
                get { return firstname; }
                set { firstname = value; }
            }

            private string lastname;

            public string Lastname
            {
                get { return lastname; }
                set { lastname = value; }
            }

            private DateTime dateOfBirth;

            public DateTime DateOfBirth
            {
                get { return dateOfBirth; }
                set { dateOfBirth = value; }
            }
        }

        #endregion
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Next we need to add the Base Class and also the Interface we are going to be using.&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:812469c5-0cb0-4c63-8c15-c81123a09de7:3a34968e-78f4-400d-8b17-1a3b4c45f7ab" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c"&gt;    public class PageInformationControl : CompositeControl,IPostBackDataHandler
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Next we want to do the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Override the base OnInit method and register a couple of instructions with the page &lt;/li&gt;

  &lt;li&gt;Implement the IPostBackDataHandler, this relies on the point above, &lt;strong&gt;i.e. otherwise the interface methods will not be called.&lt;/strong&gt; &lt;/li&gt;

  &lt;li&gt;Override&lt;strong&gt; &lt;/strong&gt;two methods of the base class being 

    &lt;ol&gt;
      &lt;li&gt;SaveControlState &lt;/li&gt;

      &lt;li&gt;LoadControlSate &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Inside the OnInit method we will tell the ASP.NET Page that this control requires two things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Control State &lt;/li&gt;

  &lt;li&gt;It also needs to be informed of PostBacks so it can alter and update its state &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the override OnInt event:&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:812469c5-0cb0-4c63-8c15-c81123a09de7:eb9a9eab-3bf0-42b2-acba-45074ec8848e" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            //To instruct the page to call the methods require to manage Control State
            Page.RegisterRequiresControlState(this);
            //Required so that the IPostBackDataHandler are invoked.
            Page.RegisterRequiresPostBack(this);
        }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Followed by the overridden methods and implemented ones:&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d323e6b2-069e-4c9c-867f-2219c6105cea" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;        protected override object SaveControlState()
        {
            return base.SaveControlState();
        }

        protected override void LoadControlState(object savedState)
        {
            base.LoadControlState(savedState);
        }

        #region IPostBackDataHandler Members

        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            throw new NotImplementedException();
        }

        public void RaisePostDataChangedEvent()
        {
            throw new NotImplementedException();
        }

        #endregion&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;OK, that is kind of the shell of our control, next we need the interface components which will be the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A DropDownList for the Title of a person &lt;/li&gt;

  &lt;li&gt;A TextBox for the Person's Firstname &lt;/li&gt;

  &lt;li&gt;A TextBox for the Person's Lastname &lt;/li&gt;

  &lt;li&gt;A TextBox for the Person's DateOfBirth 
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;It is this last one which we will use the AjaxControlToolkit and add a calendar extender.&amp;#160; This will populate the textbox from the client side yet you will see how you can strongly type your way to the value.&lt;/strong&gt; &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;An AjaxControlToolkit TextBoxWatermarkExtender for the Firstname field so the client knows what to enter &lt;/li&gt;

  &lt;li&gt;An AjaxControlToolkit TextBoxWatermarkExtender for the LastName field so the client knows what to enter &lt;/li&gt;

  &lt;li&gt;An AjaxControlToolkit TextBoxWatermarkExtender for the DateOfBirth field so the client knows what to enter &lt;/li&gt;

  &lt;li&gt;An AjaxControlToolkit Calendar extender for the DateOfBirthField so we can get good data. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE: If you have not done so already, you need to add the AjaxControlToolkit assembly to your project as a reference. You can find it here: &lt;a title="http://www.asp.net/ajax/" target="_blank" href="http://www.asp.net/ajax/"&gt;Ajax Control Toolkit at asp.net/ajax&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we will declare them as protected members.&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:812469c5-0cb0-4c63-8c15-c81123a09de7:2cb545b0-4f48-4844-9cdf-0d51efd0dacc" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;
        #region User interface

        protected DropDownList DropDownListTitle;
        protected TextBox TextBoxFirstName;
        protected TextBox TextBoxLastName;
        protected TextBox TextBoxDob;
        protected AjaxControlToolkit.TextBoxWatermarkExtender WatermarkFirstname;
        protected AjaxControlToolkit.TextBoxWatermarkExtender WatermarkLastName;
        protected AjaxControlToolkit.TextBoxWatermarkExtender WatermarkTextBoxDob;
        protected AjaxControlToolkit.CalendarExtender CalendarDob;

        #endregion&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Next is quite a long run.&amp;#160; We want to do the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Override the CreateChildControls method &lt;/li&gt;

  &lt;li&gt;Create a virtual method which starts the control generation &lt;/li&gt;

  &lt;li&gt;Create virtual methods for handling each part of the user interface, but using the method in the above point to call them in the correct order. &lt;/li&gt;

  &lt;li&gt;I have also put in a method which generates a CSS friendly wrapper for each control so as to avoid a table layout. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In each method I will specify the ID of each of the controls to get a real feel for the control.&amp;#160; I will also do this so that we can easily follow how i apply the control extenders to the controls.&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:812469c5-0cb0-4c63-8c15-c81123a09de7:09a7dd7a-2f0c-427d-b737-6f1d3111a108" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;        protected override void CreateChildControls()
        {
            Controls.Clear();
            CreateControlHierarchy();
            ClearChildViewState();
        }

        protected virtual void CreateControlHierarchy()
        {
            CreateTitle();
            CreateFirstName();
            CreateLastName();
            CreateDateOfBirth();
        }

        #region Single Responsibility UI Creation Methods

        protected virtual void CreateTitle()
        {
            Control wrapper = GetCssFriendlyControlWrapper();

            DropDownListTitle = new DropDownList();

            string[] titles = new string[] { "Mr", "Mrs", "Ms", "Miss", "Dr", "Prof" };

            foreach (string s in titles)
            {
                ListItem titleItem = new ListItem(s);
                DropDownListTitle.Items.Add(titleItem);
            }

            ListItem baseItem = new ListItem("Please select title");
            DropDownListTitle.Items.Insert(0, baseItem);

            wrapper.Controls.Add(DropDownListTitle);

            Controls.Add(wrapper);
        }

        protected virtual void CreateFirstName()
        {
            Control wrapper = GetCssFriendlyControlWrapper();

            TextBoxFirstName = new TextBox();
            TextBoxFirstName.ID = this.ID + "_TextBoxFirstName";

            WatermarkFirstname = new AjaxControlToolkit.TextBoxWatermarkExtender();
            WatermarkFirstname.ID = this.ID + "_WatermarkFirstname";
            WatermarkFirstname.WatermarkText = "Firstname";
            WatermarkFirstname.TargetControlID = TextBoxFirstName.ID;

            wrapper.Controls.Add(TextBoxFirstName);
            wrapper.Controls.Add(WatermarkFirstname);

            Controls.Add(wrapper);
        }

        protected virtual void CreateLastName()
        {
            Control wrapper = GetCssFriendlyControlWrapper();

            TextBoxLastName = new TextBox();
            TextBoxLastName.ID = this.ID + "_TextBoxLastName";

            WatermarkLastName = new AjaxControlToolkit.TextBoxWatermarkExtender();
            WatermarkLastName.ID = this.ID + "_WatermarkLastName";
            WatermarkLastName.WatermarkText = "Lastname";
            WatermarkLastName.TargetControlID = TextBoxLastName.ID;

            wrapper.Controls.Add(TextBoxLastName);
            wrapper.Controls.Add(WatermarkLastName);

            Controls.Add(wrapper);
        }

        protected virtual void CreateDateOfBirth()
        {
            Control wrapper = GetCssFriendlyControlWrapper();

            TextBoxDob = new TextBox();
            TextBoxDob.ID = this.ID + "_TextBoxDob";

            WatermarkTextBoxDob = new AjaxControlToolkit.TextBoxWatermarkExtender();
            WatermarkTextBoxDob.ID = this.ID + "_WatermarkTextBoxDob";
            WatermarkTextBoxDob.WatermarkText = "Date of Birth (yyyy-mm-dd)";
            WatermarkTextBoxDob.TargetControlID = TextBoxDob.ID;

            CalendarDob = new AjaxControlToolkit.CalendarExtender();
            CalendarDob.ID = this.ID + "_CalendarDob.ID";
            CalendarDob.Format = "yyyy-MM-dd";
            CalendarDob.TargetControlID = TextBoxDob.ID;

            wrapper.Controls.Add(TextBoxDob);
            wrapper.Controls.Add(WatermarkTextBoxDob);
            wrapper.Controls.Add(CalendarDob);

            Controls.Add(wrapper);
        }

        protected virtual Control GetCssFriendlyControlWrapper()
        {
            return new HtmlGenericControl("div");
        }

        #endregion
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Ok we are nearly ready to test this.&amp;#160; What we need to ensure next, is that we handle postbacks correctly, and we maintain state.&amp;#160; We are going to make use of the state object which we made above.&amp;#160; One alternative is to use a HashTable for example but I like to have a strongly typed version.&lt;/p&gt;

&lt;p&gt;So final few things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SaveControlState &lt;/li&gt;

  &lt;li&gt;LoadControlState &lt;/li&gt;

  &lt;li&gt;LoadPostData &lt;/li&gt;

  &lt;li&gt;RaisePostDataChangedEvent 
    &lt;ul&gt;
      &lt;li&gt;Although I am not demoing this event in this post, this can be used for example in conjunction with custom EventArgs and maybe create a Changed Event, where subscribers can access your data when the subscribed event is fired &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9e67e2be-fc2c-4ad7-892b-a1bf306d187a" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;      protected override object SaveControlState()
        {
            //Create an instance of the state object and fill it with the 
            //contents of the properties in the controls
            PageInformationControlControlState state = new PageInformationControlControlState
            {
                DateOfBirth = this.DateOfBirth,
                Firstname = this.Firstname,
                Lastname = this.Lastname,
                Title = this.Title
            };
            return state;
        }

        protected override void LoadControlState(object savedState)
        {
            //If the saved state is null, just return
            if (savedState == null)
                return;

            //Cast the savedState as your state object
            PageInformationControlControlState state = (PageInformationControlControlState)savedState;

            //Repopulate your properties after postback
            Title = state.Title;
            Firstname = state.Firstname;
            Lastname = state.Lastname;
            DateOfBirth = state.DateOfBirth;
        }

        #region IPostBackDataHandler Members

        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            //Make sure you controls have been created
            EnsureChildControls();
            //Fill the properties using the post data.
            Title = postCollection[DropDownListTitle.UniqueID];
            Firstname = postCollection[TextBoxFirstName.UniqueID];
            Lastname = postCollection[TextBoxLastName.UniqueID];
            DateTime outDateTime;
            if (DateTime.TryParse(postCollection[TextBoxDob.UniqueID], out outDateTime))
                DateOfBirth = outDateTime;

            return true;
        }

        public void RaisePostDataChangedEvent()
        {
            //throw an updated event
        }

        #endregion&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;OK so we are now ready to create a test, were by I will add this new control to the screen and also a button to raise a postback and a textarea which will display an aggregation of the data formatted in a tidy way.&amp;#160; On thing I have done at this point is add the reference to the control inside the web.config.&amp;#160; I have started off with an ASP.NET WebApplication, if you are using a normal ASP.NET Website and hence using the App_Code folder just omit the assembly attribute but makesure you give your control a namespace inside the App_Code folder and that it relates to what you are about to put into the web.config.&amp;#160; The following is inline with my program properties, and it is the first control reference:&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:812469c5-0cb0-4c63-8c15-c81123a09de7:38feefc8-c42a-479e-952d-f8e78e495602" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;		&amp;lt;pages&amp;gt;
			&amp;lt;controls&amp;gt;
				&amp;lt;add tagPrefix="eapps" namespace="WebApplication1.Controls" assembly="WebApplication1"/&amp;gt;
				&amp;lt;add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&amp;gt;
				&amp;lt;add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/&amp;gt;
			&amp;lt;/controls&amp;gt;
		&amp;lt;/pages&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;I will now create the web display:&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:812469c5-0cb0-4c63-8c15-c81123a09de7:2cafb6d9-775d-44fb-ac19-5c4beb104597" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;&amp;lt;%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %&amp;gt;

&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;
&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&amp;gt;
&amp;lt;head runat="server"&amp;gt;
    &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;form id="form1" runat="server"&amp;gt;
    &amp;lt;asp:ScriptManager ID="ScriptManager1" runat="server"&amp;gt;
    &amp;lt;/asp:ScriptManager&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;eapps:PageInformationControl ID="information1" runat="server" /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;asp:Button ID="Button1" runat="server" Text="Test PostBack" 
        onclick="Button1_Click" /&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;asp:TextBox ID="TextBoxTest" runat="server" TextMode="MultiLine" Rows="6" 
        Columns="10" Width="239px"&amp;gt;&amp;lt;/asp:TextBox&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which gives a nice desgin time layout.&amp;#160; I will make a post about DesignTimeDesigning which is a cool topic and leads you into Windows Forms if you want to go that far, you don't have to like, BUT, it shows you the power of integration that is at your finger tips and can lead to commercial control development and may be an income dependant on the popularity and effectiveness of your controls.&amp;#160; As you will see form the graphic below you need to add a Script Manager to your page prior to running the code otherwise it will tell you the same thing lol.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/Dev.NETCustomControlsMethodSingleRespons_6582/image_2.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/Dev.NETCustomControlsMethodSingleRespons_6582/image_thumb.png" width="604" height="311" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we will populate the TextBox you see above with the data from our control in a formatted fashion when the Test postback button is clicked. &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:812469c5-0cb0-4c63-8c15-c81123a09de7:336d1ca9-feaa-4d5e-bac4-8bc27eccfa48" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            StringBuilder sb1 = new StringBuilder();

            sb1.AppendFormat("Title : {0}", information1.Title);
            sb1.AppendLine();
            sb1.AppendFormat("Firstname : {0}", information1.Lastname);
            sb1.AppendLine();
            sb1.AppendFormat("Lastname : {0}", information1.Firstname);
            sb1.AppendLine();
            //Notice the next part.  It is nice and strongly typed even though the
            //textBox is populated using clientside code.
            //I am formatting the date as I do not want the Time part
            sb1.AppendFormat("Date of Birth : {0}", information1.DateOfBirth.ToString("yyyy-MM-dd"));
            sb1.AppendLine();

            TextBoxTest.Text = sb1.ToString();

            sb1 = null;
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;All that is left is to run the code.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/Dev.NETCustomControlsMethodSingleRespons_6582/image_4.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/Dev.NETCustomControlsMethodSingleRespons_6582/image_thumb_1.png" width="604" height="296" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/Dev.NETCustomControlsMethodSingleRespons_6582/image_6.png"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/Dev.NETCustomControlsMethodSingleRespons_6582/image_thumb_2.png" width="604" height="296" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Making controls this way, may seem long winded but at the end you will get a reusable, portable control.&amp;#160; You can extend it, you can improve it, you can change it etc...&amp;#160; My favourite part about it is the fact that you can access postdata from you control in a strongly typed fashion from the C# server side layer.&amp;#160; &lt;/p&gt;

&lt;p&gt;Extensions I can think of straight away involves validation and also integrating the Ajax Control Toolkit Validator Callout.&lt;/p&gt;

&lt;p&gt;&lt;a title="Download Files" href="http://www.andrewrea.co.uk/PageInformationControl.rar"&gt;You can download the files here.&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6842734" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2zgOSUKoK7v2OnX-fWt4VBj-dWQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2zgOSUKoK7v2OnX-fWt4VBj-dWQ/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/2zgOSUKoK7v2OnX-fWt4VBj-dWQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2zgOSUKoK7v2OnX-fWt4VBj-dWQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=JBRHuy2V"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=6Bf1Y8t1"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=6Bf1Y8t1" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=V6yU4hjY"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=ZO1QSPOe"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=ZO1QSPOe" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=BYhTe6NW"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=7G3FgMb8"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=7G3FgMb8" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=mxIRK1g2"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=mxIRK1g2" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=ogKx7ueN"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=KCUNgtZM"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=KCUNgtZM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=eIMCDaq6"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/LJ3T4nHJOgY" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/C_2300_/default.aspx">C#</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/01/17/developing-asp-net-custom-controls-method-single-responsibility-and-an-easier-way-to-manage-large-data-forms.aspx</feedburner:origLink></item><item><title>A nice Java Static String function I can now port into C# using Extension Methods</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/O4grKaGzMzY/a-nice-java-static-string-function-i-can-now-port-into-c-using-extension-methods.aspx</link><pubDate>Fri, 16 Jan 2009 17:48:10 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6839995</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6839995</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/01/16/a-nice-java-static-string-function-i-can-now-port-into-c-using-extension-methods.aspx#comments</comments><description>&lt;p&gt;I have just been playing around making a small networking application using Java when i came across a small and dead simple function which I thought, &amp;quot;hey that is useful,&amp;quot; and &amp;quot;oh that would now fit .NET Extension Methods.&amp;quot;&amp;#160; So straight away lol and got my console up and had a play, and i know it may seem a bit trivial, but it is just a bit tidier than other methods you could use.&amp;#160; In all I just like the simple function of the .... function.&amp;#160; Working in a case sensitive language, it seems quite relevant to differentiate.&lt;/p&gt;  &lt;p&gt;Anyway, enough blabbering, the function is called &lt;strong&gt;equalsIgnoreCase(String inValue)&lt;/strong&gt; and to use in C# simply create a string extension method like so, with an implementation following:&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:812469c5-0cb0-4c63-8c15-c81123a09de7:270d8265-dc6a-4f2a-81e8-be3bf6a98023" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;    public static class StringExtensions
    {
        public static bool EqualsIgnoreCase(this string value, string compare)
        {
            return (compare.ToLower() == value.ToLower());
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&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; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:53794f63-5f1a-4a45-805e-b8a9d905050e" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;            Console.WriteLine("QuIt".EqualsIgnoreCase("quit"));&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The output is True obviously :-)&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Andrew&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6839995" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/VmTgGQbOGmhw0rbd6s4JjUdkHyk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VmTgGQbOGmhw0rbd6s4JjUdkHyk/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/VmTgGQbOGmhw0rbd6s4JjUdkHyk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/VmTgGQbOGmhw0rbd6s4JjUdkHyk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=PnjU0skN"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=HWyqs8qx"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=HWyqs8qx" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=k64u9n6Y"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=2UlvQm5a"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=2UlvQm5a" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=C16Y6rRL"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=19XnYk06"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=19XnYk06" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=SUM7JqnK"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=SUM7JqnK" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=MQlIwMJn"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=QFG0X9nr"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=QFG0X9nr" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=5ggkUPOR"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/O4grKaGzMzY" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/C_2300_/default.aspx">C#</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/01/16/a-nice-java-static-string-function-i-can-now-port-into-c-using-extension-methods.aspx</feedburner:origLink></item><item><title>Reviewing my choice for ORM</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/jKVKuc2zUt4/reviewing-my-choice-for-orm.aspx</link><pubDate>Fri, 16 Jan 2009 08:28:25 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6838333</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6838333</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2009/01/16/reviewing-my-choice-for-orm.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;UPDATE 2009-01-27:&amp;#160; Choosing a Service model over a domain model inside NetTiers for the Component Layer can also achieve this functionality, but is definitely good to know and great to work with ObjectDataSources.&amp;#160; Reduces the code required for a lot of tasks dramatically.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Of late I have been dabbling with CodeSmith and also the templates for NetTiers, also making my own templates which is fun, but does demand a lot of time to generate re-usable templates.&amp;#160; Well to me anyway.&amp;#160; Now I do like NetTiers, all apart from the Web Layer which are UI controls and also Data controls.&amp;#160; I enjoy making strong use of ObjectDataSources to highly reduce code and improve pages, and one of the things that struck me was, well where are the parameter-less constructors, which is what I need to use the object against an ObjecDataSource.&lt;/p&gt;  &lt;p&gt;This actually is no big hurdle for a couple of reasons but mainly because NetTiers creates such a detailed Domain Model.&amp;#160; So what I need and also how to make light work of this using Code Smith again but with my own template.&lt;/p&gt;  &lt;p&gt;I need 5 base methods which will encapsulate the basic CRUD operations oh and the object is RestaurantType, not an enum but a type, only because the client will want to add more down the line and I do not want to rebuild the assembly for such a trivial addition.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;IList&amp;lt;RestaurantType&amp;gt; GetRestaurantTypes(int index, int pageSize, string sort);&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;int GetRestaurantTypesCount(int index, int pageSize, string sort);&lt;/strong&gt;       &lt;ol&gt;       &lt;li&gt;Although this count method accepts the same parameters, it does not use them, it is simply to comply with the rule that the ObjectDataSource's Select Count method must have the same method signature and the Select method itself. &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;void AddRestaurantType(RestaurantType restaurantType)&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;void UpdateRestaurantType(RestaurantType restaurantType)&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;void DeleteRestaurantType(RestaurantType restaurantType)&lt;/strong&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Another nice tip here is to decorate your class and the methods with Data Attributes which identify the class and also the methods as suitable for binding against.&amp;#160; Only the first, third, fourth and fifth method need decorating as the count method is not applicable, so CRUD:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create : [DataObjectMethod(DataObjectMethodType.Insert)] &lt;/li&gt;    &lt;li&gt;Read : [DataObjectMethod(DataObjectMethodType.Select)] &lt;/li&gt;    &lt;li&gt;Update : [DataObjectMethod(DataObjectMethodType.Update)] &lt;/li&gt;    &lt;li&gt;Delete : [DataObjectMethod(DataObjectMethodType.Delete)] &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Finally the class itself is also decorated with the following:&lt;/p&gt;  &lt;p&gt;[DataObject] &lt;/p&gt;  &lt;p&gt;So here is the code for the simple data object with which I can bind an ObjectDataSource to.&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:812469c5-0cb0-4c63-8c15-c81123a09de7:4e8f74c0-ebf4-4867-bee8-9ebd620e0693" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;   [DataObject]
    public class CustomRestaurantTypeDataSource
    {
        public static TransactionManager CreateTransaction()
        {
            TransactionManager transactionManager = null;
            if (DataRepository.Provider.IsTransactionSupported)
            {
                transactionManager = DataRepository.Provider.CreateTransaction();
                transactionManager.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);
            }
            return transactionManager;
        }

        [DataObjectMethod(DataObjectMethodType.Select)]
        public IList&amp;lt;RestaurantType&amp;gt; GetRestaurantTypes(int index, int pageSize, string sort)
        {
            int count = -1;
            TList&amp;lt;RestaurantType&amp;gt; restaurantTypes = DataRepository.RestaurantTypeProvider.GetPaged(index / pageSize, pageSize, out count);
            return restaurantTypes.ToList();
        }

        public int GetRestaurantTypesCount(int index, int pageSize, string sort)
        {
            int count = -1;
            DataRepository.RestaurantTypeProvider.GetPaged(out count);
            return count;
        }

        [DataObjectMethod(DataObjectMethodType.Insert)]
        public void AddRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Insert(tm, restaurantType);
                tm.Commit();
            }
        }

        [DataObjectMethod(DataObjectMethodType.Update)]
        public void UpdateRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Update(tm, restaurantType);
                tm.Commit();
            }
        }

        [DataObjectMethod(DataObjectMethodType.Delete)]
        public void DeleteRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Delete(tm, restaurantType);
                tm.Commit();
            }
        }
    }&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;I have then used this on my ObjectDataSource like the following:&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:812469c5-0cb0-4c63-8c15-c81123a09de7:3ebc4ed9-a707-43cb-8e22-3aa857c34323" class="wlWriterSmartContent"&gt;&lt;pre name="code" class="c#"&gt;    &amp;lt;asp:ObjectDataSource ID="RestaurantTypeDataSource" runat="server" 
        DataObjectTypeName="TM.Entities.RestaurantType" 
        DeleteMethod="DeleteRestaurantType" EnablePaging="True" 
        MaximumRowsParameterName="pageSize" 
        OldValuesParameterFormatString="original_{0}" 
        SelectCountMethod="GetRestaurantTypesCount" SelectMethod="GetRestaurantTypes" 
        StartRowIndexParameterName="index" 
        TypeName="TM.WebSite.CodeFiles.CustomRestaurantTypeDataSource" 
        UpdateMethod="UpdateRestaurantType"&amp;gt;
        &amp;lt;SelectParameters&amp;gt;
            &amp;lt;asp:Parameter DefaultValue="0" Name="index" Type="Int32" /&amp;gt;
            &amp;lt;asp:Parameter DefaultValue="10" Name="pageSize" Type="Int32" /&amp;gt;
            &amp;lt;asp:Parameter Name="sort" Type="String" /&amp;gt;
        &amp;lt;/SelectParameters&amp;gt;
    &amp;lt;/asp:ObjectDataSource&amp;gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In one of my next posts I will show how to make a pager control.&amp;#160; I do like the ASP.NET Pager control but I really feel it lacks one thing, and that being a &lt;strong&gt;PageChangedEvent&lt;/strong&gt;.&amp;#160; In the pager I will make, you will be able to set the &lt;strong&gt;TotalNumberOfPages&lt;/strong&gt; and also subscribe to the &lt;strong&gt;PageChanged&lt;/strong&gt; Event.&amp;#160; I feel this is quite useful and we could also write in code to handle any &lt;strong&gt;IPageableContainer&lt;/strong&gt;s brought in with the .NET 3.5 wave.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Andrew&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6838333" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/u6HIs5ihk2PTMPcSVnIUsxO08EU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/u6HIs5ihk2PTMPcSVnIUsxO08EU/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/u6HIs5ihk2PTMPcSVnIUsxO08EU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/u6HIs5ihk2PTMPcSVnIUsxO08EU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=avciAfbA"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=GVyczK6G"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=GVyczK6G" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=AHuZvQDt"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=C3tcTboM"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=C3tcTboM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=PQKMbRfe"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=0d9idnsd"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=0d9idnsd" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=Hnl9XrR8"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=Hnl9XrR8" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=3lDVUrgX"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=BOMxQ6TX"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=BOMxQ6TX" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=3uIQrh7U"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/jKVKuc2zUt4" height="1" width="1"/&gt;</description><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2009/01/16/reviewing-my-choice-for-orm.aspx</feedburner:origLink></item><item><title>Catching the exception from the ObjectDataSource Inserted Event</title><link>http://feedproxy.google.com/~r/AndrewRea/~3/La2Nb1HvLm8/catching-the-exception-from-the-objectdatasource-inserted-event.aspx</link><pubDate>Mon, 17 Nov 2008 15:59:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6743937</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6743937</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2008/11/17/catching-the-exception-from-the-objectdatasource-inserted-event.aspx#comments</comments><description>&lt;p&gt;One thing I was puzzled over today was that I could see the Exception property of the ObjectDataSourceStatusEventArgs but I could not seem to cast it into the Exception I was expecting.&amp;#160; After a little mooching around, and debugging the actual type of the Exception property I found that it is actually of the type:&lt;/p&gt;  &lt;pre&gt;System.Reflection.TargetInvocationException&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Which in turns holds a property called InnerException.&amp;#160; This is the Exception property that I needed to cast.&amp;#160; &lt;/p&gt;

&lt;pre&gt;        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ArticleDataSourceInserted(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, ObjectDataSourceStatusEventArgs e)
        {
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.Exception != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
            {
                System.Reflection.TargetInvocationException exc= (System.Reflection.TargetInvocationException)e.Exception;

}

}&lt;/pre&gt;

&lt;p&gt;Oh and also, make sure that you indicate that the Exception has been handled, assuming that is has ofcourse.&amp;#160; This is a boolean property of the ObjectDataSourceStatusEventArgs.&lt;/p&gt;

&lt;pre&gt;e.ExceptionHandled = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Andrew&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6743937" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/31UVLJiwB3URxjF8BzQLeDU_RNs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/31UVLJiwB3URxjF8BzQLeDU_RNs/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/31UVLJiwB3URxjF8BzQLeDU_RNs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/31UVLJiwB3URxjF8BzQLeDU_RNs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=W2lRbxvq"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=9bhY6y8d"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=9bhY6y8d" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=XYDzhCux"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=43" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=KhimJVTp"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=KhimJVTp" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=Ip8irbgb"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=sVHncFN7"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=sVHncFN7" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=Jwxcis6L"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=Jwxcis6L" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=6qu4MTJK"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=54" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=1gGihqdC"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?i=1gGihqdC" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/AndrewRea?a=VxhgWyUB"&gt;&lt;img src="http://feeds.feedburner.com/~f/AndrewRea?d=129" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewRea/~4/La2Nb1HvLm8" height="1" width="1"/&gt;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Visual+C_2300_/default.aspx">Visual C#</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Business+Objects/default.aspx">Business Objects</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Web+Controls/default.aspx">Web Controls</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Win+Forms/default.aspx">Win Forms</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Win+Forms+C_2300_/default.aspx">Win Forms C#</category><feedburner:origLink>http://weblogs.asp.net/andrewrea/archive/2008/11/17/catching-the-exception-from-the-objectdatasource-inserted-event.aspx</feedburner:origLink></item></channel></rss>
