Peppy Custom Panel Control

This post is also dedicated to my companies prestigious client.

My team was facing a very peculiar problem with this peppy custom panel container control which one of my team member created from Control class (i.e. System.Web.UI.Control) instead of Panel class (i.e. System.Web.UI.WebControls.Panel).
The reason for choice was that the default markup generated by the Panel class was in the form of tables and since my client deals in Mobile Web portal and the browsers of devices are very very harsh on developers. You make a small mistake or a small smarteness will cost you a hard kick on your butt…i could use words which are even worse to tell you how sensitive these mobile browsers are :)  So, i need the markup in the form of “DIVS” instead of “TABLES”.

So, in order to generate the markup in the form of DIVS my friend created it using the Control class and Overrided the CreateChildControl method in it and finally, injected the necessary DIV to create a parent control with some attributes in the form of CSS classes passed by the consumer page or user control using this controls property holding the attributes in the form of NameValue pair.

After this thoughtfull yet messy code(i am sure this friend of mine will definately kill me after reading this article :) ) it almost worked fine in every situation and just then it showed up with some bright colors almost at the verge of development cycle in other words, it broke into millions of pieces. :(

So the pseudocode goes like this:
==================================
public NameValuePair[] CustomAttributes
{
 //Contains the attributes passed by the consumer page/user control
}
 
protected override CreateChildControl()
{
 //Created the required div over here
 
 //looped through the CustomAttributes and added to the div above
 // looped through "this.Controls" collection 
 //and added each control to the div above(This is the real mess) 
}

 The above control works fine as long as this parent control contains static controls like: (Label, textboxes etc.). The control struggles when a control like CheckBoxList is placed under its hood. Obviously now the user will try to gather the selected checkboxes values and just then the control breaks. On PostBack when the page tries to gather the checkbox values by looping through this.items (i.e. ListItems) the count of ListItems comes out to be 0 (yes, ZERO).

Oops, forgot to tell you the CheckBoxList is also a custom control derived from Asp.Net CheckBoxList. This control was also overriden to get the markup in the form of DIVS. So, this.Items in last para will give you the ListItems of checkboxlist.

So, in a nut shell these are a kind of custom adapters written for adaptive rendering of the controls depending on the device type.

 Coming back to the point, I can’t tell you the exact reason for this count zero, I think we had to do something related to the viewstate while adding the individual control to the parent DIV in the CreateChildControl method.

Alright enough of problem statement, now lets come straight to the solution, After a lot of ignorance today i took up the task of clearing this mess. Poor this Custom Panel here i come yoooo man :) hahaha

Here comes the magic code….

namespace custom.ServerControls
{
    [ParseChildren(false),
      ToolboxData("<{0}:CustomPanel runat=\"server\"></{0}:CustomPanel>")]
    public class CustomPanel : Panel
    {          
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.WriteLine("<div style=\"border:5px solid black;\">");
             //Its safe to write your custom code here
             writer.WriteLine(”<img src=”"your icon image source”" />”)
   
            //Calling base class(i.e. System.Web.UI.WebControls.Panel)
            //RenderContents method
            base.RenderContents(writer);
            writer.WriteLine("</div>");
        }
    }
}

There is the main part of the code! We simply override the RenderContents method! What this does instead of jumping ahead and just inputing the panel controls into the panel control, we instead snatch it before it finishes and add some of our own custom code!

It’s a simple htmltextwriter object so it’s really easy to use.

You take writer and use the writeline method to add the begining code. Don’t worry this won’t edit the contents of writer. I know it seems odd a little but writeline doesn’t effect the htmltextwriter at all, it just injects code into the page where the panel control is at.

So by this solution two of most significant problems are solved:

  1. My friend don’t have to create the custom panel from Control class as done above,
  2. The view state issue of the child controls will be handled by the panel class along with the EnableViewState = “true” property of the page,
  3. Since Control class does not provide Attributes propert for adding custom attributes to the panel like: CSS class etc. for which my friend has created the NameValuePair array property in the pseudocode above. As the current control is derived directly from Panel class the Attributes property will be available directly.  :)

Cheers !!! Enjoy!!! :)

kick it on DotNetKicks.com

Shout it

pimp it

Umesh Mehra

Lead Engineer, Global Logic, Noida, India

More Posts