SP.NET is a terrific platform for Web applications. That does not mean that tricky coding is always one or two clicks away within a dockable and resizable Visual Studio .NET dialog box. Tricky solutions require tricky coding, just the kind of features that a wizard-driven environment and a general-purpose framework can't provide. In this article, we'll tackle five ASP.NET features that require wicked and creative code.
Have you ever heard about the "real programmer?" The real programmer is someone who makes a living putting one keyword after the next, abiding by some sort of syntax and semantics. Being strongly results-oriented, the real programmer gained a reputation for hating all the bells and whistles that inevitably surround any software technology. Wizards, black box components, and data binding? No, thank you. The real programmer makes a point of writing hundreds of lines of code to get full control over each execution step.
Frankly, I've found myself in the position of the real programmer more than once, especially regarding data binding. As a real programmer, I never used old Visual Basic data-bound controls. If you ever experienced the data-bound controls of early versions of Visual Basic, you know why. But the advent of the .NET Framework changed things quite a bit. The .NET Framework comes with a powerful data binding mechanism implemented for both Windows Forms and Web Forms.
Unfortunately but reasonably, the set of ASP.NET data-bound controls just don't cover all possible scenarios; you can have automatic binding between a data source and a list of check boxes or radio buttons. But if you're looking for a data-bound bulleted or numbered list of strings, prepare to face disappointment.
I'm not sure how you feel about that, but I craved a BulletList control for a while. Then, I made the decision to build it myself. Quite surprisingly, it wasn't too difficult. It is probably a task within the reach of any programmer and not just "real programmers."
1. Building a Bulleted List Control
control can be built starting from the WebControl
class. This class provides a default implementation for several handy UI properties, such as Font
. By inheriting from WebControl, you don't have to worry about common UI-related properties and can focus on the more specific attributes of the control.
control needs at least four properties, as listed in Table 1
Table 1: These are the properties of the BulletList control.
Indicates the type of bulleted list. Feasible values are defined in the BulletList enumeration: UL or OL.
Gets and sets the data source associated with the control
Gets and sets the name of the data source field to be used to fill the list
The collection of strings that represents the items added to the list
property has a double role. For one thing, it is the internal buffer in which the data-bound information is parked before it is rendered to HTML. Because the property is marked as public, you can also use it to manually add strings of text to the list. This code snippet shows how to add extra items at the bottom of the list created after the data source.
list.Items.Add("Plus this one!");
and the DataTextField
properties let you extract a particular column of data out of an ADO.NET container. The use of these properties is in no way different from analogous properties defined in other list-bound classes (e.g., CheckBoxList). The typical use you can make of them is shown in this next snippet.
// Run the query
string cmd = "SELECT * FROM employees";
string conn = "SERVER=...;DATABASE=...;UID=...;";
adapter = new SqlDataAdapter(cmd, conn);
// Bind the control
DataTable table = new DataTable();
bList.DataSource = table;
The control also needs to override the DataBind
method inherited from the Control
class. When the DataBind
method is called, the control loads the bound data source into the Items string collection. During the Render
method (another overridden method), the control builds the bullet list, mixing together HTML tags and text strings. In HTML, you can have two types of lists: the classic bulleted list or a numbered list. In the former case, you create it using the <ul>
tag; for the latter case, use the <ol>
tag. Nested within those elements, there is one <li>
tag per each item to display.
The control's programming interface allows you to choose the type of bulleted list through the following enum type:
public enum BulletType
A value of type BulletType
is assigned to the BulletListType
property. An enum type cannot be a collection of strings; only basic types can be used, such as int or double. By giving the entries in the enumeration the same mnemonic names of HTML tags, you can easily associate each of them with the correct string using the ToString
method. Listing 1
shows how to render the BulletList control to HTML, based on the value of the BulletListType
The full source code of the BulletList control is shown in Listing 2
. Notice the technique used to generate the HTML for the control. The Render methodthe procedure that calls into the CreatePanel
method shown abovegets an HTML TextWriter
object from the .NET Framework and sends text to it. You can implement the Render method in such a way that the code simply outputs text to the stream; alternatively, you can use a temporary instance of a control, configure it through properties, and then render it. The gain is that you end up with code far easier to read and maintain. This technique is frequently used within ASP.NET itself.
|To add IntelliSense support to the HTML view of the visual designer, you need to provide the schema of the control: an XSD file.|
Regarding Listing 1
, the technique based on temporary controls might seem overkill. The following code would have worked great as well. Judge for yourself.
foreach(string elem in Items)
shows the BulletList control in action based on this next bit of code.
<%@ Register TagPrefix="expo"
<form runat="server" ID="Form1">
<expo:BulletList runat="server" id="bList"