Table of Contents- Page 1
- Prerequisites
- Introduction
- Some Background on Controls
- Planning for Project Reuse
- Data-Bound Properties
- CSS and Other Visual Properties
- Page 2
- The Render Method
- The HTML Output by the Control
- Design-Time Support
- Page 3
- Using the Control
- Conclusion
- About the Author
Prerequisites- Familiarity with C#, VisualStudio .NET, and creating ASP.NET applications
- Basic understanding of ADO.NET and DataBinding
- Basic understanding of HTML and Cascading Style Sheets
- Download source code
Introduction Have you ever wanted to design a server control that you could use on an ASP.NET page? I was working on a page, and I needed something like the CheckBoxList control, except that I needed to have the fields separated into different groups, complete with category headings. Behind the scenes, I had a database containing the items and item categories needed to populate the control, but the standard CheckBoxList control doesn't allow you to display the checkboxes in a "categorized view". Well, there are a number of ways that you can try to solve the problem using the CheckBoxList control. I can think of two ways. You could add a CheckBoxList control, one for each category or grouping, to your ASPX page (hard-coding the categories). Alternatively, you could programmatically add CheckBoxList controls to the page at runtime, in the Page_Load method of your code-behind file. In my project, the form was supposed to let users pick any number of items that were displayed with checkboxes. For the sake of this example, let's say that the categories are car makers, and the items are car models. Since the items and categories were stored in a database, new car makes and models could be added and existing entries can be revised or deleted. I immediately ruled out hard coding the category names and CheckBoxList controls on the Web form. It would be unrealistic to assume that we would update the ASPX page and the C# code-behind file every time that a car maker was added, deleted, or renamed. Adding controls to a form at runtime comes with its own drawbacks, too. You can programmatically add a Web control to a PlaceHolder or any other container control quite easily. The trouble is that in order to read the values that a user specified, you have to "rebuild" the controls (programmatically recreate them) every time that the page loads, regardless of PostBack state or whether you are going to display the checkboxes to the user or not. This places considerable load on the server. What I really wanted was a new kind of control that I could drop on form, specify a few properties, add the data binding code, and be done. Since none of the standard Web controls seemed to fit, I decided to create my own custom server control, which I named, "CategorizedCheckBoxList". While the prospect of building a control from scratch may sound daunting, I found that it really wasn't too difficult. Some Background on Controls Web custom controls exhibit several advantages over user controls. User controls are not ideal for re-use, as their ASCX and class files must be copied into each project that consumes them. They are also handicapped by a lack of designer support in Visual Studio .NET. Drop one on a Web form and you'll see what I mean; they are represented by a generic, grey box, and the IDE offers no help in determining the control's properties. The main benefit of user controls is that they are very easy to create, and this promotes rapid application development. Web custom controls, on the other hand, can be quite appealing. There is no ASCX file for a Server Control, so they are very easy to re-use. You need only set a project reference to the DLL, and you're off to the races. Web custom controls can also be added to your VS .NET Toolbox for ultra-simple re-use. You can even install a Web custom control in the Global Assembly Cache, but a discussion of the GAC is beyond the scope of this article. But the main reason why I love Web custom controls is because they offer complete customization and design-time support. The major hurdle you must surmount to create a Web custom control is that you have to write the HTML for the control yourself. Visual Studio .NET doesn't provide you with a visual designer for Web custom controls, so you can't drag and drop items from the Toolbox onto your control. But surely, if we can learn to write C# programs, we can learn HTML, right? Planning for Project Reuse To readily facilitate easy re-use of our control, we should start out with a new Web Control Library project: 
Visual Studio .NET will create a class called WebCustomControl1.cs, which we will rename CategorizedCheckBoxList.cs. (Be sure to search and replace "WebCustomControl1" with "CategorizedCheckBoxList" in the class file.) Data-Bound Properties We need the ability to bind a data source to our control. To keep things simple, I decided that the control should accept an ADO.NET DataTable for its data source. I chose the DataTable type, because I didn't want the control to have to know much about the data or how the data was retrieved. Our control would simply need the DataTable, the names of the fields that should be used for the categories, the checkbox values, and the text that goes along with each checkbox. - DataTable
Sytem.Data.DataTable. The table that will be used as the source of the data. At a minimum, this table must contain a column with the names of the categories, a column for the values of the checkboxes, and a column for the text that will go along side of each checkbox. Our control will automatically sort the table by category, and then by the text column. - DataCategoryColumn
String. The name of the column in the table that contains the name of the category to which an item belongs. - DataValueColumn
String. The name of the column in the table that contains the values for the checkboxes. The same column name may be specified for both the DataValueColumn and the DataTextColumn properties. The DataValueColumn may contain data of any type, but if character data is used, the values may not contain commas. - DataTextColumn
String. The name of the column in the table that contains the text that will appear next to the checkboxes. We also need a way to specify the checkboxes that should be marked when the page loads. This will allow us to setup default values or use our control on forms that let users edit values that have been previously saved. I decided to use an ArrayList for this: - Selections
ArrayList containing String values. A list of the values, if any, that should be marked as selected (checked). This property can be used by the consuming page, both to specify the selected values and to retrieve a list of the selections after the Web form posts back.
CSS and Other Visual Properties By exposing additional properties for Cascading Style Sheet class selectors, the visual style of the CategorizedCheckBoxList can be controlled (no pun intended) by the ASPX page. - TableCssClass
String. The CSS class specified for the table(s) containing the checkboxes. - RowCssClass
String. The CSS class specified for each of the table rows that contain checkboxes. - CategoryCssClass
String. The CSS class specified for the table cells that contain the category headings. - CheckBoxCssClass
String. The CSS class specified for the table cells that contain the checkboxes. - TextCssClass
String. The CSS class specified for the table cells that contain the text next to the checkbox fields. I also added these properties: - TableWidth
String. The width to be used for the table(s). The number of pixels, or a percentage, including the % symbol should be supplied. - CellPadding
Integer. The cell padding to be used for the table(s). - CellSpacing
Integer. The cell spacing to be used for the table(s). - Columns
Integer. The number of columns to be used to display the checkboxes. - SharedTable
Boolean. True to display everything in a single, shared table. False to display each category in its own table (along with its items). I included this property after finding that the layout of the page can look quite strange if you have some categories with items with small amounts of text accompanying the checkboxes, and others with long text.
The Render Method >> |