The FormField Control
I'll use the FormField control as an example of a rendered custom Web control. You'll find this control to be extremely useful in any Web application and you'd very likely use it heavily within a single page. As I explained before, it is for that reason that I've chosen to develop this control as a rendered Web control, which is one that directly writes to the HTML rendering engine; making the control very efficient. This control will serve well in any Web Form (or other Web controls) where data-entry is performed. The control replaces the need to drop a separate label, textbox, and sometimes a button on Web Forms several times support fields used for data-entry. The label and textbox are common everywhere, but the button is an added extra for this control. The control can display a button to the left of the textbox. This button will raise an event to the code-behind that can be trapped by whatever page uses the control. This feature, along with some interesting properties that we'll go over soon, will give the FormField control some really cool functionality. Figure 2
shows what the finished control will look like in a standard layout.
|Figure 2: The FormField control in a finished stage.|
Now you can start to create the class that will become your FormField control. This class will inherit from the System.Web.UI.WebControls.WebControl class, one of two classes that [non-inherited] custom Web controls inherit from. The other is the Control class but it does not provide the styling properties that you want for your control.
Public Class FormField
public class FormField : WebControl
I'll discuss styling later but for now your next step is to add some properties to your control.
In the interest of space, I will not go into the property details here but the final downloadable code has every property fully documented, specifying the category they fall into and their description, provided to each property via the attributes discussed earlier. The properties that you'll add to this control will determine how the control renders its contents and what kind of behavior it provides to the Web Form using it. At the end of this section, I'll give you a quick list of functionality the final control has. Details on all of this is just too much for this article, but I will tell you that in the process of adding functionality to this and the control that follows, I'll demonstrate a variety of features you can give your Web controls. This should give you a good reference to use when building more controls in the future. Table 1 lists three properties that I'll refer to during the development that follows.
Table 1: These three properties are among many used in the FormField control.
This property gets or sets the caption text that will display in the FormField control.
This property gets or sets the caption for the button that will display in the FormField control.
Like it's counterpart in the standard Textbox control, this property gets or sets the value that gets entered or displayed in the textbox that will be part of the FormField control.
Since this is going to be a rendered control, the next step is to jump right into the method that provides the rendering engine that you'll write to.
method, which you need to override, has only one argument of the type System.Web.UI.HtmlTextWriter. This argument, which you'll call output
, is the entry point into the Html rendering engine. To write HTML (or any other) text using this object, you could use this snippet.
output.write("<input type='text' id='txt1'>");
This code would write out the text between the quotes directly without any other process in between. This kind of direct access makes rendered controls very efficient for rendering speed. While your control will write output using this object, your control won't write literal text as shown in the code snippet above. Instead, the HtmlTextWriter object provides many methods that help you create valid HTML, so you'll take advantage of that.
Speaking of HTML, now's a good time to describe what kind of HTML you want to render for the FormField control. Remember the FormField control will be made up of three parts: a caption, a textbox, and a button. Essentially, the HTML will give the control a <span>
tag, an <input type='text'>
tag, and an <input type='submit'>
tag. I'll walk you through that and then we'll build upon it. Listing 1
shows the VB .NET code that will render the HTML for the three sections of your custom control in its simplest form. Listing 2
shows the same process in C#.
Here's a piece of HTML that will help you analyze this code:
This is essentially the piece of code that the first five code lines of the Render
method create. You want the label to use the "span" tag for the caption of the FormField control. This basic HTML tag contains literal text and can apply any styling you desire to that text.
Note that the third, fourth, and fifth lines in the code in the listing uses the RenderBeginTag
method of the HtmlTextWriter object to render a "span" tag. Then it renders the caption text from the Caption
property, and closes the tag using the RenderEndTag
method. You don't need to specify which tag need to close because the rendering engine keeps track for you automatically. The first two lines in the code use the HtmlTextWriter.AddAttribute
method to add custom attributes that will get rendered with the "span" tag.
In the sample HTML above, the "span" tag contains id
attributes. You add these attributes using the AddAttribute
method in conjunction with an HtmlTextWriterAttribute
enum value. Every call to AddAttribute
gets "stacked" and the attributes all get added to whatever is the next tag rendered with RenderBeginTag
. That clears the attribute stack and the task starts again. You can see this demonstrated in the listing code where the id
attributes get added to the three tags being rendered, leading this article to an important topic for naming rendered controls.