<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" 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/"><channel><title>Andrew Rea : Custom Controls</title><link>http://weblogs.asp.net/andrewrea/archive/tags/Custom+Controls/default.aspx</link><description>Tags: Custom Controls</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Programmatic WebControls – Variations of design</title><link>http://weblogs.asp.net/andrewrea/archive/2009/03/17/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 xmlns:wfw="http://wellformedweb.org/CommentAPI/">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;</description><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Data+Bound+Controls/default.aspx">Data Bound Controls</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/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></item><item><title>A Custom DropDownList using an Enum Type as a DataSource</title><link>http://weblogs.asp.net/andrewrea/archive/2008/11/03/a-custom-dropdownlist-using-an-enum-type-as-a-datasource.aspx</link><pubDate>Mon, 03 Nov 2008 22:31:19 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6718566</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6718566</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2008/11/03/a-custom-dropdownlist-using-an-enum-type-as-a-datasource.aspx#comments</comments><description>&lt;p&gt;First off, I have to again express my admiration at the job Microsoft have done at building the core ASP.NET Web Form Controls.&amp;nbsp; I think they are sometimes taken for granted.&amp;nbsp; &lt;/p&gt; &lt;p&gt;This post is about making a control which derives from the DropDownList and uses a Enum as a Data Source.&amp;nbsp; A little more though, you can transform the text with the use of Regular Expressions.&amp;nbsp; I had a scenario where by I need a static set of Enum Values in the database to correspond with foreign keys in another table.&amp;nbsp; So for example, say you have a table called Cars and it has a TransmissionID field which is linked to another table called TransmissionType.&amp;nbsp; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;u&gt;TransmissionType&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;TransmissionTypeID&lt;/p&gt; &lt;p&gt;TransmissionTypeName&lt;/p&gt; &lt;p&gt;The values for exmaple in this table could be Manual Drive, Automatic Drive.&amp;nbsp; Now, I know that these values will not change, and the point is made stronger when the number of types is great and static or will not be changed that often at all.&amp;nbsp; So that I can communicate these values back to the database and take advantage of the C# Enum Type I create an Enum called TransmissionType.&lt;/p&gt;&lt;pre&gt;pubilc &lt;span style="color: #0000ff"&gt;enum&lt;/span&gt; TransmissionType{
	ManualDrive = 1,
	AutomaticDrive = 2
}&lt;/pre&gt;
&lt;p&gt;Notice the format of the text between the enum names and the table fields i.e. Enum is CamelCase and the field values have a space to make good language and sense.&amp;nbsp; Now I want to assign this enum as the DataSource to a DropDownList and even more than that I want the actual value of the enum to be the value of the ListItems in the DropDownList.&lt;/p&gt;
&lt;p&gt;You can simply bind a list of Enums to a DropDownList and it will render but will not contain the value of each of the Enum Names, assuming you have values.&amp;nbsp; I simply created a quick ASP.NET Server Control, derived it from the DropDownList and added a few more bits:&lt;/p&gt;
&lt;p&gt;1. Define a private collection of ListItems&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; ListItemCollection collection;&lt;/pre&gt;&lt;/blockquote&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;2. Define a custom property in the control called EnumType&lt;/p&gt;&lt;pre&gt;        [Bindable(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        [Category("&lt;span style="color: #8b0000"&gt;Behaviour&lt;/span&gt;")]
        [Localizable(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EnumType
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                String s = (String)ViewState["&lt;span style="color: #8b0000"&gt;EnumType&lt;/span&gt;"];
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ((s == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) ? String.Empty : s);
            }

            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState["&lt;span style="color: #8b0000"&gt;EnumType&lt;/span&gt;"] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }&lt;/pre&gt;
&lt;p&gt;3. Define a custom property in the control called TextTransaformationPattern&lt;/p&gt;&lt;pre&gt;        [Bindable(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        [Category("&lt;span style="color: #8b0000"&gt;Behaviour&lt;/span&gt;")]
        [Localizable(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
        [DefaultValue("&lt;span style="color: #8b0000"&gt;[A-Z]&lt;/span&gt;")]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TextTransaformationPattern
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                String s = (String)ViewState["&lt;span style="color: #8b0000"&gt;TextTransaformationPattern&lt;/span&gt;"];
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ((s == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) ? String.Empty : s);
            }

            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState["&lt;span style="color: #8b0000"&gt;TextTransaformationPattern&lt;/span&gt;"] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }&lt;/pre&gt;
&lt;p&gt;4. Define a custom property in the control called TextTransaformationReplacement&lt;/p&gt;&lt;pre&gt;        [Bindable(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        [Category("&lt;span style="color: #8b0000"&gt;Behaviour&lt;/span&gt;")]
        [Localizable(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
        [DefaultValue("&lt;span style="color: #8b0000"&gt; $0&lt;/span&gt;")]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TextTransaformationReplacement
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                String s = (String)ViewState["&lt;span style="color: #8b0000"&gt;TextTransaformationReplacement&lt;/span&gt;"];
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ((s == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) ? String.Empty : s);
            }

            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState["&lt;span style="color: #8b0000"&gt;TextTransaformationReplacement&lt;/span&gt;"] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;5.Instantiate the collection in the OnInit Event Handler, add the List Items whilst formatting the names to give a slightly better effect and also enabling the value of the enum to go into the value of the ListItem.&lt;/p&gt;&lt;pre&gt;        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnInit(EventArgs e)
        {
            &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnInit(e);
            collection = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ListItemCollection();

            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; s &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Enum.GetNames(Type.GetType(EnumType)))
            {
                ListItem li = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ListItem(
                    Regex.Replace(s, TextTransaformationPattern, TextTransaformationReplacement),
                    ((&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;)Enum.Parse(Type.GetType(EnumType), s)).ToString());
                collection.Add(li);
            }
        }&lt;/pre&gt;
&lt;p&gt;6.Override the ListItemCollection getter and return our new list of ListItems.&lt;/p&gt;&lt;pre&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; ListItemCollection Items
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; collection;
            }
        }&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The need for the regular expressions is just one way I came up with to format the text in a way which avoided the Camel Case look.&amp;nbsp; In the regular expression replace I simply tell it to replace the Matched Element with a space and the Matched Element i.e. $0 so CamelCase becomes Camel Case.&amp;nbsp; Probably better to trim the string also to take away the first space, but anyway you get the idea.&amp;nbsp; Implementation includes using the AssemblyQualifiedName i.e. "MyNameSpace.Type, MyAssembly."&amp;nbsp; An example implementation is below:&lt;/p&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;EnumDropDownList&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"EnumDropDownList1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"server"&lt;/span&gt; 
            &lt;span style="color: #ff0000"&gt;EnumType&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"uk.co.andrewrea.commerce.DeliveryMethod,uk.co.andrewrea.commerce"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;TextTransaformationReplacement&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;" $0"&lt;/span&gt;
            &lt;span style="color: #ff0000"&gt;TextTransaformationPattern&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"[A-Z]"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;EnumDropDownList&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style="color: #0000ff"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I am sure you could cache the values to make better for performance but it was a nice fix for some of the FormView Elements I am working with.&amp;nbsp; You can also enable the DropDownList to work with the Bind method in mark up by say creating a Property which gets and sets the selectedValue property of the DropDownList and use the Bind Method there.&amp;nbsp; I will modify the control and make another post about using the DropDownList and the Bind within say a FormView next.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/ACustomDropDownListusinganEnumTypeasaDat_13CB6/image_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/ACustomDropDownListusinganEnumTypeasaDat_13CB6/image_thumb.png" width="317" height="155"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This is based on the following Enum:&lt;/p&gt;&lt;pre&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;enum&lt;/span&gt; InventoryStatus
    {
        InStock = 1,
        BackOrder = 2,
        PreOrder = 3,
        SpecialOrder = 4,
        Discontinued = 5,
        CurrentlyUnavailable = 6
    }&lt;/pre&gt;
&lt;p&gt;The output in html is then the following:&lt;/p&gt;&lt;pre&gt;InventoryStatus:
  
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;select&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ctl00$ContentPlaceHolder1$FormView1$ddlInventoryStatus"&lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;&lt;span style="color: #ff0000"&gt;id&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"ctl00_ContentPlaceHolder1_FormView1_ddlInventoryStatus"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt; &lt;span style="color: #ff0000"&gt;selected&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"selected"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; In Stock&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"2"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; Back Order&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"3"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; Pre Order&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"4"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; Special Order&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; Discontinued&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;"6"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; Currently Unavailable&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  
  
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;select&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here is the full code:&lt;/p&gt;
&lt;p&gt;Cheers,&lt;/p&gt;
&lt;p&gt;&lt;br&gt;Andrew&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ComponentModel;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Linq;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Text;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web.UI;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web.UI.WebControls;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Text.RegularExpressions;

&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; uk.co.andrewrea.web.ui.control
{
    [DefaultProperty("&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;")]
    [ToolboxData("&lt;span style="color: #8b0000"&gt;&amp;lt;{0}:EnumDropDownList runat=server&amp;gt;&amp;lt;/{0}:EnumDropDownList&amp;gt;&lt;/span&gt;")]
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; EnumDropDownList : DropDownList
    {
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; ListItemCollection collection;


        [Bindable(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        [Category("&lt;span style="color: #8b0000"&gt;Appearance&lt;/span&gt;")]
        [DefaultValue("&lt;span style="color: #8b0000"&gt;&lt;/span&gt;")]
        [Localizable(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Value
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                String s = (String)ViewState["&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;"];
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ((s == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) ? String.Empty : s);
            }

            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState["&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;"] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }

        [Bindable(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        [Category("&lt;span style="color: #8b0000"&gt;Behaviour&lt;/span&gt;")]
        [Localizable(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EnumType
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                String s = (String)ViewState["&lt;span style="color: #8b0000"&gt;EnumType&lt;/span&gt;"];
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ((s == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) ? String.Empty : s);
            }

            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState["&lt;span style="color: #8b0000"&gt;EnumType&lt;/span&gt;"] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }

        [Bindable(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        [Category("&lt;span style="color: #8b0000"&gt;Behaviour&lt;/span&gt;")]
        [Localizable(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
        [DefaultValue("&lt;span style="color: #8b0000"&gt;[A-Z]&lt;/span&gt;")]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TextTransaformationPattern
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                String s = (String)ViewState["&lt;span style="color: #8b0000"&gt;TextTransaformationPattern&lt;/span&gt;"];
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ((s == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) ? String.Empty : s);
            }

            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState["&lt;span style="color: #8b0000"&gt;TextTransaformationPattern&lt;/span&gt;"] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }

        [Bindable(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        [Category("&lt;span style="color: #8b0000"&gt;Behaviour&lt;/span&gt;")]
        [Localizable(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]
        [DefaultValue("&lt;span style="color: #8b0000"&gt; $0&lt;/span&gt;")]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; TextTransaformationReplacement
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                String s = (String)ViewState["&lt;span style="color: #8b0000"&gt;TextTransaformationReplacement&lt;/span&gt;"];
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ((s == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) ? String.Empty : s);
            }

            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState["&lt;span style="color: #8b0000"&gt;TextTransaformationReplacement&lt;/span&gt;"] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }

        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnInit(EventArgs e)
        {
            &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnInit(e);
            collection = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ListItemCollection();

            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; s &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Enum.GetNames(Type.GetType(EnumType)))
            {
                ListItem li = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ListItem(
                    Regex.Replace(s, TextTransaformationPattern, TextTransaformationReplacement),
                    ((&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;)Enum.Parse(Type.GetType(EnumType), s)).ToString());
                collection.Add(li);
            }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; ListItemCollection Items
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; collection;
            }
        }
    }
}
&lt;/pre&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6718566" width="1" height="1"&gt;</description><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/Web+Controls/default.aspx">Web Controls</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></item><item><title>ASP.NET MVC "Pager" HTML Helper</title><link>http://weblogs.asp.net/andrewrea/archive/2008/07/01/asp-net-mvc-quot-pager-quot-html-helper.aspx</link><pubDate>Tue, 01 Jul 2008 15:26:38 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6345698</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=6345698</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2008/07/01/asp-net-mvc-quot-pager-quot-html-helper.aspx#comments</comments><description>&lt;p&gt;So I am building my own custom blog using the ASP.NET MVC Framework, and I have been working on the paging aspect.&amp;#160; I will be going into more detail how i achieved this but for now, I am publishing a HtmlHelper I have made which has helped me, believe it or not lol, in the paging.&amp;#160; The way I have designed it also is kind of decoupled, so i see no reason for its integration into many other applications.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;My implmentation of the HtmlHelper is here:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre&gt;&amp;lt;%= Html.Pager((pc.StartingIndex / pc.PageSize) ,pc.PageSize,pc.TotalRecords,&amp;quot;&lt;span style="color: #8b0000"&gt;/Home/Page&lt;/span&gt;&amp;quot;) %&amp;gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/ASP.NETMVCPagerHTMLHelper_E742/Pager_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="Pager" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/ASP.NETMVCPagerHTMLHelper_E742/Pager_thumb.png" width="572" height="118" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And the code which makes it is here.&amp;#160; The major thing is calculating the seed of the iteration based on the current page, after that you are laughing!&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;pre&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Pager(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; HtmlHelper helper, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; currentPage, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; currentPageSize, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; totalRecords, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; urlPrefix)
    {
        StringBuilder sb1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringBuilder();

        &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; seed = currentPage % currentPageSize == 0 ? currentPage : currentPage - (currentPage % currentPageSize);

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(currentPage &amp;gt; 0)
            sb1.AppendLine(String.Format(&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;a href=\&amp;quot;{0}/{1}\&amp;quot;&amp;gt;Previous&amp;lt;/a&amp;gt;&lt;/span&gt;&amp;quot;, urlPrefix, currentPage));

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(currentPage - currentPageSize &amp;gt;= 0)
            sb1.AppendLine(String.Format(&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;a href=\&amp;quot;{0}/{1}\&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt;&lt;/span&gt;&amp;quot;, urlPrefix, (currentPage - currentPageSize) + 1));

        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = seed; i &amp;lt; Math.Round((totalRecords / 10) + 0.5) &amp;amp;&amp;amp; i &amp;lt; seed + currentPageSize; i++)
        {
            sb1.AppendLine(String.Format(&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;a href=\&amp;quot;{0}/{1}\&amp;quot;&amp;gt;{1}&amp;lt;/a&amp;gt;&lt;/span&gt;&amp;quot;, urlPrefix, i + 1));
        }

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (currentPage + currentPageSize &amp;lt;= (Math.Round((totalRecords / 10) + 0.5) - 1))
            sb1.AppendLine(String.Format(&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;a href=\&amp;quot;{0}/{1}\&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt;&lt;/span&gt;&amp;quot;, urlPrefix, (currentPage + currentPageSize) + 1));

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (currentPage &amp;lt; (Math.Round((totalRecords / 10) + 0.5) - 1))
            sb1.AppendLine(String.Format(&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;lt;a href=\&amp;quot;{0}/{1}\&amp;quot;&amp;gt;Next&amp;lt;/a&amp;gt;&lt;/span&gt;&amp;quot;, urlPrefix, currentPage + 2));

        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; sb1.ToString();
    }&lt;/pre&gt;

&lt;p&gt;Hope this helps some people,&lt;/p&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=6345698" width="1" height="1"&gt;</description><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/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/Extension+Methods/default.aspx">Extension Methods</category><category domain="http://weblogs.asp.net/andrewrea/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category></item><item><title>Group Enabled Web Form Control Extensions</title><link>http://weblogs.asp.net/andrewrea/archive/2008/02/22/group-enabled-web-form-control-extensions.aspx</link><pubDate>Fri, 22 Feb 2008 12:28:49 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5839587</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=5839587</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2008/02/22/group-enabled-web-form-control-extensions.aspx#comments</comments><description>&lt;h2&gt;Contents&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;h4&gt;The Idea&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;The Control Library&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;IGroupingControl&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;GroupingEventArgs&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;GroupingManager&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;GroupingPanel&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;A picture of the library&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;The implementation&lt;/h4&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;h4&gt;The Files&lt;/h4&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;The Idea&lt;/h2&gt;  &lt;p&gt;If you would like to see the end result before reading on here it is: &lt;a title="http://www.andrewrea.co.uk/groupenabledwebformcontrols/default.aspx" href="http://www.andrewrea.co.uk/groupenabledwebformcontrols/default.aspx"&gt;http://www.andrewrea.co.uk/groupenabledwebformcontrols/default.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;My idea for this sort of control library actually came from working with the LoginView control.&amp;#160; There you can specify different controls to be shown dependant on:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Anonymous &lt;/li&gt;    &lt;li&gt;Logged &lt;/li&gt;    &lt;li&gt;Role Groups &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I found this very efficient, but it got me thinking.&amp;#160; You will no doubt come across certain times where you would like certain controls to be disabled or enabled dependant on certain conditions with in your program, may be not show certain controls and only show others.&amp;#160; My idea is to create a control set where by we have one main controlled object and child controls which subscribe to events from this controller.&lt;/p&gt;  &lt;p&gt;It will also help with greatly reducing the amount of UI code required to hide and show controls.&amp;#160; Another main concern while making these was this fact.&amp;#160; &amp;quot;GROUPS&amp;quot; it may be the case that a control will be shown in one scenario but also in another, i.e. it belongs to more than one group.&amp;#160; I liked this idea so i thought I will code it so you can have many groups assigned to one control.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Example: (Form controls in a questionnaire)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;GROUP 1: Question modifications for C# Programmers&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;GROUP 2: Question modifications for C++ Programmers&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;GROUP 3: Question modifications for Java Programmers&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;GROUP 4: Question modifications for Java Programmers and C++ Programmers&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;GROUP 5: Question modifications for C# Programmers and C++ Programmers&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;GROUP 6: Question modifications for C# Programmers and Java Programmers&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;So you get the idea, there can be any number of controls and each control can have many groups, the control library I have done which is a simple extension of the Web Forms Control Library means I could make all GROUP 4 controls disabled with one line of code etc... and subsequently enable them.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;The Control Library&lt;/h2&gt;  &lt;p&gt;As I say I have extended the web form default control library with grouping, the control library I have made consists of:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;An Interface&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;IGroupingControl &lt;/h2&gt;  &lt;pre&gt;    &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #808080"&gt;/// I have only put in three properties for the interface&lt;/span&gt;
    &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IGroupingControl
    {
        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GroupNames { &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
        &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GroupingManagerID { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
        GroupingManager GroupingManagerControl { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; }
    }&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Event Arguments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are only two at present but I feel that this could be extended much further using for example the &lt;strong&gt;Strategy Pattern.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;GroupingEventArgs&lt;/h2&gt;

&lt;pre&gt;   &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #808080"&gt;/// Contains the bare necesity of group name, and also a visible and enabled property&lt;/span&gt;
    &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; GroupingEventArgs : EventArgs
    {
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; _isEnabled;

        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; _isVisible;

        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _groupName;

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsEnabled
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _isEnabled;
            }
            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                _isEnabled = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; IsVisible
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _isVisible;
            }
            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                _isVisible = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GroupName
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _groupName;
            }
            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                _groupName = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; GroupingEventArgs(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; isEnabled, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; isVisible, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; groupName)
        {
            _isEnabled = isEnabled;
            _isVisible = isVisible;
            _groupName = groupName;
        }
    }&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;A Control Class which should be supplied to the page at the top, it is a &amp;quot;GroupingManager&amp;quot; and is used to notify all Groupings controls on the page&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;The GroupingManager&lt;/h2&gt;

&lt;pre&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; GroupingManager : UserControl
    {
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;event&lt;/span&gt; EventHandler&amp;lt;GroupingEventArgs&amp;gt; Notified;

        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnNotified(GroupingEventArgs e)
        {
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Notified != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
                Notified(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, e);
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Disable(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; groupName)
        {
            GroupingEventArgs e = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; GroupingEventArgs(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, groupName);
            e.GroupName = groupName;
            OnNotified(e);
        }
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Enable(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; groupName)
        {
            GroupingEventArgs e = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; GroupingEventArgs(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, groupName);
            e.GroupName = groupName;
            OnNotified(e);
        }
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; MakeVisible(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; groupName)
        {
            GroupingEventArgs e = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; GroupingEventArgs(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, groupName);
            e.GroupName = groupName;
            OnNotified(e);
        }
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; MakeInvisible(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; groupName)
        {
            GroupingEventArgs e = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; GroupingEventArgs(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;, groupName);
            e.GroupName = groupName;
            OnNotified(e);
        }

        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; FindPredicate(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; currentValue, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; toCompare)
        {
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (currentValue == toCompare)
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;
            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; 
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
        }
    }&lt;/pre&gt;

&lt;p&gt;The above are the core ingredients to this control library, as I say the other controls are simply inheriting from the web from controls and extending them with the interface.&amp;#160; I will paste in the code here for the GroupingPanel which will display how I achieve the functionality.&amp;#160; NB:&amp;#160; The code for the other objects is the same with the exception of changing the object name, constructor and also the base control it inherits from.&amp;#160; I think this may be a case of where the C++ rule that you can inherit from multiple classes and interfaces would be useful here.&amp;#160; Of course with C# you can only inherit from one object and multiple interfaces.&amp;#160; I say this because I could simply use the same code in another object and inherit from the base control and also my object which provides extended functionality.&amp;#160; Either way It uses an interface and here is one of the controls namely the &lt;strong&gt;GroupingPanel.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;The GroupingPanel&lt;/h2&gt;

&lt;pre&gt;    &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #808080"&gt;/// The grouping panel&lt;/span&gt;
    &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; GroupingPanel : Panel,IGroupingControl
    {
        &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// The group names which belong to the controls&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] _groupNames
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[])ViewState[&amp;quot;&lt;span style="color: #8b0000"&gt;GroupName&lt;/span&gt;&amp;quot;];
            }
        }
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; GroupingPanel()
        {
            &lt;span style="color: #008000"&gt;//&lt;/span&gt;
            &lt;span style="color: #008000"&gt;// TODO: Add constructor logic here&lt;/span&gt;
            &lt;span style="color: #008000"&gt;//&lt;/span&gt;
        }
        &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// Here I subscribe the the Grouping Manager Notified event&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;param name=&amp;quot;e&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnLoad(EventArgs e)
        {
            &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnLoad(e);
            GroupingManagerControl.Notified += &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventHandler&amp;lt;GroupingEventArgs&amp;gt;(GroupingManagerControl_Notified);
        }

        &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// This is where the magix happens&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;param name=&amp;quot;sender&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;param name=&amp;quot;e&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GroupingManagerControl_Notified(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, GroupingEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(&amp;quot;&lt;span style="color: #8b0000"&gt;Entered&lt;/span&gt;&amp;quot;);
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Array.IndexOf(_groupNames,e.GroupName) &amp;gt;= 0)
            {
                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Enabled = e.IsEnabled;
                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Visible = e.IsVisible;
            }
        }

        #region ISubscriptionControl Members
        &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// The string ID of the grouping manager&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GroupingManagerID
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; o = ViewState[&amp;quot;&lt;span style="color: #8b0000"&gt;GroupingManagerID&lt;/span&gt;&amp;quot;];
                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (o == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; String.Empty;
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ViewState[&amp;quot;&lt;span style="color: #8b0000"&gt;GroupingManagerID&lt;/span&gt;&amp;quot;].ToString();
            }
            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState[&amp;quot;&lt;span style="color: #8b0000"&gt;GroupingManagerID&lt;/span&gt;&amp;quot;] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }
        &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// This returns the grouping manager control&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; GroupingManager GroupingManagerControl
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (GroupingManager)Page.FindControl(GroupingManagerID);
            }
        }

        &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// The reason why this is of type string and not string[]&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// is because it will trhow an error trying to assign to array&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// from the string representation in the mark up which is why&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// I provide a private accesor to the data above&lt;/span&gt;
        &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GroupNames
        {
            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                ViewState[&amp;quot;&lt;span style="color: #8b0000"&gt;GroupName&lt;/span&gt;&amp;quot;] = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;.ToString().Split(',');
            }
        }

        #endregion
    }&lt;/pre&gt;

&lt;h2&gt;A Picture of the library&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/GroupEnabledWebFormControlExtensions_A679/LibraryVisualisation_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="659" alt="LibraryVisualisation" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/GroupEnabledWebFormControlExtensions_A679/LibraryVisualisation_thumb.jpg" width="664" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;The Implementation&lt;/h2&gt;

&lt;p&gt;As per the example URL at the start of this blog&amp;#160; I created buttons on the left to trigger different calls to the Grouping Manager. e.g.&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button5&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Disable Group 1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OnClick&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button5_Click&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;With the code&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; Button5_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
        {
            groupingManager1.Disable(&amp;quot;&lt;span style="color: #8b0000"&gt;Group1&lt;/span&gt;&amp;quot;);
        }&lt;/pre&gt;

&lt;p&gt;So straight away this means that it would effect the following grouping controls:&lt;/p&gt;

&lt;pre&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;GroupingPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;groupingPanel1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GroupNames&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Group1,Hybrid&amp;quot;&lt;/span&gt;
                &lt;span style="color: #ff0000"&gt;GroupingManagerID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;groupingManager1&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;GroupingPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;GroupingPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;groupingPanel2&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GroupNames&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Group1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GroupingManagerID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;groupingManager1&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button2&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;GroupingPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;GroupingPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;groupingPanel3&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GroupNames&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Group1,Hybrid&amp;quot;&lt;/span&gt;
                &lt;span style="color: #ff0000"&gt;GroupingManagerID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;groupingManager1&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button3&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;GroupingPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;GroupingPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;groupingPanel4&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GroupNames&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Group1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;GroupingManagerID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;groupingManager1&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #c71585"&gt;asp&lt;/span&gt;:&lt;span style="color: #800000"&gt;Button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button4&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Button&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #c71585"&gt;aebs&lt;/span&gt;:&lt;span style="color: #800000"&gt;GroupingPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;h3&gt;Please notice that two of the grouping panels belong to both &lt;strong&gt;Group1&lt;/strong&gt; and also &lt;strong&gt;Hybrid&lt;/strong&gt;. So this means that if I disable Group1 and then enable Hybrid, only the two controls with Hybrid in their group names will be enabled.&lt;/h3&gt;

&lt;p&gt;I hope that this library can be of some use to others and I know this could be extended way further to incorporate many more time saving / code saving ideas.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The library (&lt;a title="http://www.andrewrea.co.uk/GroupEnabledWebFormControls/Grouping.rar" href="http://www.andrewrea.co.uk/GroupEnabledWebFormControls/Grouping.rar"&gt;http://www.andrewrea.co.uk/GroupEnabledWebFormControls/Grouping.rar&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The test site (&lt;a title="http://www.andrewrea.co.uk/GroupEnabledWebFormControls/Grouping.rar" href="http://www.andrewrea.co.uk/GroupEnabledWebFormControls/GroupEnabledWebFormControls.rar"&gt;http://www.andrewrea.co.uk/GroupEnabledWebFormControls/GroupEnabledWebFormControls.rar&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Example URL (&lt;a title="http://www.andrewrea.co.uk/groupenabledwebformcontrols/default.aspx" href="http://www.andrewrea.co.uk/groupenabledwebformcontrols/default.aspx"&gt;http://www.andrewrea.co.uk/groupenabledwebformcontrols/default.aspx&lt;/a&gt;)&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5839587" width="1" height="1"&gt;</description><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/Web+Controls/default.aspx">Web Controls</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/Business+Objects/default.aspx">Business Objects</category></item><item><title>A version of a WinForms Rounded GroupBox with transparency</title><link>http://weblogs.asp.net/andrewrea/archive/2008/02/18/my-own-version-of-a-winforms-rounded-groupbox-with-transparency.aspx</link><pubDate>Mon, 18 Feb 2008 18:02:01 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5815204</guid><dc:creator>REA_ANDREW</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/andrewrea/rsscomments.aspx?PostID=5815204</wfw:commentRss><comments>http://weblogs.asp.net/andrewrea/archive/2008/02/18/my-own-version-of-a-winforms-rounded-groupbox-with-transparency.aspx#comments</comments><description>&lt;p&gt;I made something similar a while back and never did anything with it.&amp;#160; I started again today as usual because the interest took me lol.&amp;#160; So there are custom group boxes out there and I have seen a few on Code Project, but in this blog I have added a few different features simply by exposing properties of the Pen and Brush objects.&lt;/p&gt;  &lt;p&gt;Examples of my control, these are in the source I have provided below in the link:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/MyownversionofaWinFormsRoundedGroupBoxwi_E897/FormExample_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="606" alt="FormExample" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/MyownversionofaWinFormsRoundedGroupBoxwi_E897/FormExample_thumb.jpg" width="540" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;The object itself&lt;/h3&gt;  &lt;p&gt;All I have done to maintain functionality and simply extend is to inherit from the GroupBox, like below:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; WindowsForm_Examples_NET_2
{
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; partial &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; RoundedGroupBox : GroupBox
    {&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Next I added some properties to it.&amp;#160; This is the dead easy part, as all I am doing is providing exposure to the properties of the Pen and Brush as well as other things:&lt;/p&gt;

&lt;pre&gt;        &lt;span style="color: #008000"&gt;//This is the size of the text of the groupbox, e.g. _groupNameDimensions = e.Graphics.MeasureString(this.Text, this.Font);&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; SizeF _groupNameDimensions;
        &lt;span style="color: #008000"&gt;//The radius of the corners with a default value of 10&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt; _cornerRadius = 10;
        &lt;span style="color: #008000"&gt;//The leading text margin of the left side&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt; _leadingTextMargin = 25;
        &lt;span style="color: #008000"&gt;// I need a graphics path here for the corner arcs and then finally close the figure&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; GraphicsPath _roundBoxPath;
        &lt;span style="color: #008000"&gt;// The first colour of the gradient&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Color _gradientFrom = Color.Gray;
        &lt;span style="color: #008000"&gt;//The second colour of the gradient&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Color _gradientTo = Color.White;
        &lt;span style="color: #008000"&gt;//The angle of the gradient&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt; _gradientAngle = 90;
        &lt;span style="color: #008000"&gt;//The fill type, this could be Fill or Linear Gradient&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; FillType _groupFillType = FillType.Fill;
        &lt;span style="color: #008000"&gt;//The back colour.  This is the colour within the Graphics path, if you change the controls back color that will be behind the groupbox&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Color _groupBackColor = Color.White;
        &lt;span style="color: #008000"&gt;//The colour of the border&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Color _groupBorderColor = Color.Black;
        &lt;span style="color: #008000"&gt;//The width of the border&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _groupBorderWidth = 1;
        &lt;span style="color: #008000"&gt;//The dash style of the border, this can be set to Solid&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DashStyle _groupLineStyle = DashStyle.Solid;
        &lt;span style="color: #008000"&gt;//A Custom pattern for the dashes like 10,50 etc...&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt;[] _dashPattern = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt;[] { 5, 5 };&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;I encapsulate these fields so you will see the properties, I also attach the following attribute for design time purposes:&lt;/p&gt;

&lt;pre&gt;        [NotifyParentProperty(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt;[] DashPattern
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _dashPattern; }
            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; { _dashPattern = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }&lt;/pre&gt;

&lt;p&gt;I can also now attach some descriptions and even categories so that it will look tidy inside the Property Box.&amp;#160; I have not added these at this time of writing, but for this one paste into the blog I will.&lt;/p&gt;

&lt;pre&gt;        [Description(&amp;quot;&lt;span style="color: #8b0000"&gt;The custom pattern for the Group Box Border&lt;/span&gt;&amp;quot;)]
        [Category(&amp;quot;&lt;span style="color: #8b0000"&gt;GroupBox Dash&lt;/span&gt;&amp;quot;)]
        [NotifyParentProperty(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)]
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;float&lt;/span&gt;[] DashPattern
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _dashPattern; }
            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; { _dashPattern = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }&lt;/pre&gt;

&lt;p&gt;This will give you the following behaviour inside the properties window:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/MyownversionofaWinFormsRoundedGroupBoxwi_E897/RoundedCornersProperties_2.gif"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="555" alt="RoundedCornersProperties" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/MyownversionofaWinFormsRoundedGroupBoxwi_E897/RoundedCornersProperties_thumb.gif" width="351" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;Drawing the curved container&lt;/h3&gt;

&lt;p&gt;I have not gone into Maths yet as much as I should and want being a programmer so please excuse me if the route I have taken,is in any shape a long and inefficient way.&amp;#160; The approach I took was to identify the key area where I would place an arc.&amp;#160; After this I noted down the sweep angles.&amp;#160; For the purposes of this control they will always sweep a distance of 90 degrees but the starting angle will differ.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/MyownversionofaWinFormsRoundedGroupBoxwi_E897/SweepAngle_2.gif"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="256" alt="SweepAngle" src="http://weblogs.asp.net/blogs/andrewrea/WindowsLiveWriter/MyownversionofaWinFormsRoundedGroupBoxwi_E897/SweepAngle_thumb.gif" width="334" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;With reference to the above image please find the method I wrote in order to draw the container.&amp;#160; I feel I have over complicated the equations which enable the control to adapt to changes in size and also changes to the Font property of the Group Text.&lt;/p&gt;

&lt;pre&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PointF p1;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PointF p2;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PointF p3;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PointF p4;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PointF p5;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PointF p6;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PointF p7;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; PointF p8;


        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnPaint(PaintEventArgs e)
        {
            &lt;span style="color: #008000"&gt;//This will give the lines a smoother look.&lt;/span&gt;
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            &lt;span style="color: #008000"&gt;//I assign the size of the GroupBox Text property&lt;/span&gt;
            _groupNameDimensions = e.Graphics.MeasureString(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Text, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Font);
            &lt;span style="color: #008000"&gt;//Below I create the coordinates for each point, I rake into account the control margin, the radius, the size of the text and also the leading Text margin.&lt;/span&gt;
            p1 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(_leadingTextMargin &amp;gt; (_cornerRadius * 2) ? _leadingTextMargin : (_cornerRadius * 2), &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Top);
            p2 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(p1.X + _cornerRadius + _groupNameDimensions.Width, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Top);
            p3 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(p1.X + (_cornerRadius * 2) + _groupNameDimensions.Width, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Top + _cornerRadius + _groupNameDimensions.Height);
            p4 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Width - _cornerRadius - &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Right, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Top + (_cornerRadius * 2) + _groupNameDimensions.Height);
            p5 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Width - _cornerRadius - &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Right, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Height - _cornerRadius - &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Bottom);
            p6 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Left, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Height - _cornerRadius - &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Bottom);
            p7 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Left, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Top + (_cornerRadius * 2) + _groupNameDimensions.Height);
            p8 = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(_leadingTextMargin &amp;gt; (_cornerRadius * 2) ? _leadingTextMargin - _cornerRadius : _cornerRadius, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Top + _cornerRadius + _groupNameDimensions.Height);

            &lt;span style="color: #008000"&gt;// I instantiate the Graphics Path&lt;/span&gt;
            _roundBoxPath = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; GraphicsPath();

            &lt;span style="color: #008000"&gt;//I now add the arcs to the graphics path using a helper function to genrate the required rectangle, bit overkill I will admit&lt;/span&gt;
            _roundBoxPath.AddArc(GetRectangle(p1), 180F, 90F);
            _roundBoxPath.AddArc(GetRectangle(p2), 270F, 90F);
            _roundBoxPath.AddArc(GetRectangle(p3), 180F, -90F);
            _roundBoxPath.AddArc(GetRectangle(p4), 270F, 90F);
            _roundBoxPath.AddArc(GetRectangle(p5), 0F, 90F);
            _roundBoxPath.AddArc(GetRectangle(p6), 90F, 90F);
            _roundBoxPath.AddArc(GetRectangle(p7), 180F, 90F);
            _roundBoxPath.AddArc(GetRectangle(p8), 90F, -90F);
            _roundBoxPath.CloseFigure();

            &lt;span style="color: #008000"&gt;//I define a pen and conitionally assign the prroperties to it&lt;/span&gt;
            Pen p = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Pen(GroupBorderColor);
            p.DashStyle = GroupLineStyle;
            p.Width = GroupBorderWidth;
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (GroupLineStyle == DashStyle.Custom)
            {
                p.DashPattern = DashPattern;
            }
            e.Graphics.DrawPath(p, _roundBoxPath);

            &lt;span style="color: #008000"&gt;//Here I conditionally assign the way the group box should be filled with colour&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GroupFillType)
            {
                &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; FillType.Fill:
                    e.Graphics.FillPath(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SolidBrush(GroupBackColor), _roundBoxPath);
                    &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
                &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;:
                    LinearGradientBrush lgb = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; LinearGradientBrush(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Rectangle(0,0,&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Width,&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Height), GradientFrom, GradientTo, GradientAngle);
                    e.Graphics.FillPath(lgb, _roundBoxPath);
                    &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
            }
            
            &lt;span style="color: #008000"&gt;//Here I draw the group name text into the tab like shape.&lt;/span&gt;
            e.Graphics.DrawString(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Text, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Font, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SolidBrush(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ForeColor), &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PointF(_leadingTextMargin &amp;gt; (_cornerRadius * 2) ? _leadingTextMargin + _cornerRadius : (_cornerRadius * 2) + _cornerRadius, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Margin.Top + (_cornerRadius / 2)));

            &lt;span style="color: #008000"&gt;//To avoid being inconsitent I set the minimum with every time it invalidates so as to keep the tab in propeortion to the groiup box.&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.MinimumSize = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Size(Convert.ToInt32(_leadingTextMargin + _groupNameDimensions.Width +(_cornerRadius*3)), 0);
        }&lt;/pre&gt;

&lt;pre&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; RectangleF GetRectangle(PointF p)
        {
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RectangleF(p, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SizeF(_cornerRadius, _cornerRadius));
        }&lt;/pre&gt;

&lt;h3&gt;Transparency&lt;/h3&gt;

&lt;p&gt;Even though I have inherited from the groupbox control I can still make this transparent, by setting some of the styles of the form, the crucial one being SupportTransparentBackColor.&amp;#160; To avoid flickering as well when you resize the control I have set the ResizeRedraw flag.&lt;/p&gt;

&lt;pre&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; RoundedGroupBox()
        {
            InitializeComponent();
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetStyle(ControlStyles.ResizeRedraw, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetStyle(ControlStyles.DoubleBuffer, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetStyle(ControlStyles.AllPaintingInWmPaint, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetStyle(ControlStyles.UserPaint, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetStyle(ControlStyles.SupportsTransparentBackColor, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.SetStyle(ControlStyles.ContainerControl, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.BackColor = Color.Transparent;
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Width = 175;
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Height = 75;
        }&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;The Source Code&lt;/h3&gt;

&lt;p&gt;I have not yet figured out how to upload a file with Windows Live Writer yet so I have placed this file on my server.&amp;#160; Thanks for reading and hope it is of some interest.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;a title="Rounded Groupbox Example" href="http://andrewrea.co.uk/RoundedCornerGroupBox/RoundedCornerGroupBox.rar" target="_blank"&gt;http://andrewrea.co.uk/RoundedCornerGroupBox/RoundedCornerGroupBox.rar&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5815204" width="1" height="1"&gt;</description><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><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/Visual+C_2300_/default.aspx">Visual C#</category></item></channel></rss>