ASP.NET Custom Controls Series
ASP.NET Custom Controls
- Part 1 In this - the first of many parts - we will look at what a custom control
is and how it differs from user controls, as well as classes that our custom controls
can derive from. In the article we will also implement a simple custom control.
ViewState
One of the unsung heroes of ASP.NET is ViewState. ViewState allows a control to maintain its state over one or more postbacks. You can think of ViewState as a state bag. Essentially, it's a dictionary whereby the key is the name of the property. This isn't set in stone - you can use whatever name you want but best practice is to give the entry the same name as the publicly visible property.
< /p>
All corresponding values of the keys used to access a particular dictionary entry are objects. As result, they need to be casted to the relevant type/value type.
ViewState is stored in a hidden field within the rendered markup and uses the LosFormatter class for serialization. The hidden field __VIEWSTATE represents the base 64 encoded string representation of an object graph for the state of all the controls in the control tree.
As control developers we don't need to do anything to utilize ViewState - we get that for free when we derive from System.Web.UI.Control. The control lifecycle calls the method SaveViewState which is called just after the PreRender method to save the ViewState dictionary. Upon postback there is a method, LoadViewState, called earlier within the control lifecycle. This essentially allows us to resume where the previous requests processing was finished.
ViewState can be switched off by the developer by setting the EnableViewState property to false for a particular control. When server pages contain many server controls the ViewState may become fairly large in size - this can affect serialization/deserialization performance. We will discuss the control lifecycle in the next part of this series.
Access to ViewState is free
As we ultimately derive from System.Web.UI.Control we get access to the ViewState property. When you create a new key/value pair to store in the ViewState, a call to the Add method of the System.Web.UI.StateBag class is made, which adds the entry to a Dictionary.
Listing 1: Storing the value of Text in the ViewState
In Listing 1 the key for the value of the Text property is Text. To retrieve the value associated with that key from the StateBag dictionary, we cast the object to a string using the as keyword, which is described later on.
Note: as I mentioned earlier, be wary about how much you use ViewState as it can bloat the page size. You may also want to think about the conversion from string attribute values to specific types as ViewState is optimized for only a subset of available value/reference types. Creating type converters will increase performance (type converters are also popular in WPF) when the ASP.NET parser parses your server markup.
Unboxing reference types
Unboxing is something that gives rise to many performance analysts - that's because it can be very expensive when used excessively.
We need to cover a little about casting at this moment in time so you can cast safer, and faster. The below example (Listing 2) - where o is not a string - will raise an InvalidCastException.
Listing 2: Casting can be expensive
In Listing 2 the cast would have been successful if we were casting to whatever o was, or one of its base types. Since we weren't, an exception is raised which is fairly expensive.
The C# language has an as keyword that allows an exception free casting. The as operator checks to see whether we can cast from one reference type to another. If we can, the cast succeeds. Otherwise, instead of raising an exception, the cast returns null.
Listing 3: Using the as keyword to perform reference type casting
As I've already explained, o cannot be casted to a string, so the value of s in Listing 2.3 will be null.
Control Rendering
The rendering of a custom control relates to the markup that we want to generate. For example, if we are creating a custom control that displays tabular data, we might want to render a table.
There are a few things about rendering that should be known. The first is that the intended markup can be created by using strings, like in "<div>..." but this lacks compiler type safety so we generally choose to go with enumeration types like System.Web.UI.HtmlTextWriterTag. The latter approach is not as efficient as the first approach - where everything is simply a string - but we benefit from reduced mistyping. If you feel that you are creating a control and you really need to skip the lookup enum, then use the string approach.
Note: if you are going to use the string approach, be aware of concatenation (strings are immutable) and favour the System.Text.StringBuilder class when many concatenations are going to be made.
Rendering
If we take the example from part 1 of this series - where we rendered a simple label - we didn't really do much with regards to the way it was rendered. Now we will go ahead and change a few of the defaults to give you an idea of the various bits we can override within the control framework.
Listing 4: Rendering a modified SimpleLabel control
There are a few things in Listing 4 then deserve a mention. The first is that we derive from System.Web.UI.WebControls.WebControl and not System.Web.UI.Control. As a result, we get a whole load of properties for free like CssClass, BorderStyle, etc. We also have quite a few new things that we can override since their definition is virtual - these include defining the outer tag that the underlying HtmlTextWriter stream renders. In the previous example, we use the h1 tag instead of the span tag.
Figure 1: Properties that we have inherited from System.Web.UI.WebControls.WebControl

Where has the Render method gone? We are still calling the Render method of the System.Web.UI.Control class, but via the RenderContents method. The RenderContents method calls its base class' Render method passing the HtmlTextWriter stream object as the parameter. In the RenderContents method we can generate any output before the Render method, which writes content to be rendered by the browser.
All HTML rendered is HTML 4.0. If you want to render markup that is compliant with a previous HTML standard - like HTML 3.2 - you can do so by using the Html32TextWriter class.
Summary
In this article, we have briefly explained both ViewState and rendering. Please research the various rendering methods that the System.Web.UI.Control and System.Web.UI.WebControls.WebControls classes expose. In the next part we will look at the control lifecycle and events within custom controls.
About Granville Barnett
 |
Sorry, no bio is available
This author has published 32 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
Introducing RadScrollablePanel for Windows Forms
read more
Introducing SharePoint 2010 Training at U2U
read more
Using WCF with SQL Azure and Telerik OpenAccess
read more
The Underground at PDC
read more
New content providers for the RadEditor and RadFileExplorer controls
read more
The ESRI Dev Summit 2010 hosted in Palms Springs CA is open for registration.
read more
MVC or Web Forms? A Dying Question
read more
Designer Support for One-Way navigations in Entity Framework 4
read more
How to display data from different tables using one data source
read more
Visual Studio 2010 Extension Manager
read more
|
|
Please login to rate or to leave a comment.