An Extensive Examination of the DataGrid Web Control: Part 11
By Scott Mitchell
The Eleventh Part in a Multi-Part Series
This article is the eleventh piece of a multi-part series on using the DataGrid Web control that will span
several months. The ASP.NET DataGrid Web control, which displays database information in an HTML table, is
highly versatile. The basics of the DataGrid were discussed in Part 1;
information on specifying display properties of the DataGrid was discussed in
Part 2. In Part 3
we examined how to associate custom events with the DataGrid.
In Part 4 we looked at how to extend
Part 3 to provide custom sorting on the results of a DataGrid. In
Part 5 we examined how to use templates to further customize
the DataGrid's appearance. Part 6 examined how to use the
DataGrid's built-in editing capabilities, while Part 7 looked at
customizing the editing interface using the EditItemTemplate. In Part 8
we looked at how to add client-side code to a ButtonColumn's client-side onclick event.
In Part 9 we examined how to enhance the DataGrid's editing
interface by having the editing interface's TextBox receive focus when the page is loaded.
In Part 10 we looked at how to (automatically) add filtering
buttons so that one can filter the data in a DataGrid. In this eleventh part, we'll examine how to
create a DataGrid Web control with a column of related radio buttons - a task much more difficult than
you might think!
ASP.NET Data Web Controls Kick Start is author Scott
Mitchell's most recent book, which thoroughly examines three of the most commonly
used ASP.NET Web controls: the DataGrid, DataList, and Repeater. These three Web controls
can be difficult to master due to their numerous features and capabilities. With this book, you'll
quickly become an expert, learning the gritty details and true capabilities of each.
This 400+ page book explores the topics in this article series in much greater depth, along with
examining various topics and techniques not covered here.
Scott Mitchell is the editor and founder of 4GuysFromRolla.com, author of the An Extensive Examination
of the DataGrid Web Control article series, and author of numerous other ASP and ASP.NET
books.
Introduction
There are many real-world situations in which you might like to create a DataGrid that has a column of
radio buttons that serve to allow the user to select a particular row. For example, if you wanted to
create some sort of online voting application, you might want to use a DataGrid to display the voting
options with a radio button next to each option, so that the user can choose one and only one option.
Many developers who want to add this sort of functionality think that it is a trivial task, involving merely
the addition of a TemplateColumn whose ItemTemplate has a RadioButton Web control. As we will see in
this article, the task is not nearly this simple. Specifically, we will look at why using a TemplateColumn
with a RadioButton Web control won't cut the mustard, and then we'll examine a free custom DataGrid Column
control from Andy Smith's MetaBuilders.com Web site, which
easily allows for adding a column of radio buttons to a DataGrid.
Why the TemplateColumn Approach Won't Work
The intuitive way to provide a radio button column in a DataGrid is to use a TemplateColumn where the
ItemTemplate has a RadioButton control. (We examined the TemplateColumn in Part 5.)
This could be accomplished using the following DataGrid markup:
The above code will create a column that has a radio button in each row, yes, but due to the way that
the DataGrid names its containing controls, the user will be able to select multiple radio buttons.
(Don't believe me? Try it out in the live demo.) Clearly, being
able to select multiple radio buttons breaks the semantics of the radio button metaphor.
When the Web browser is confronted with a series of radio buttons, it considers radio buttons with the
same name attribute to be of the same group of radio buttons. That is, if you have a
number of radio buttons on a Web page with the same name attribute, the user will only
be allowed to select one of those same named radio buttons.
The ASP.NET RadioButton Web control provides a
GroupName property, that specifically sets the resulting radio button's HTML markup to have
the name attribute specified by this property. Therefore, if you need to plop down a related
series of RadioButton Web controls, you can simply give all of the RadioButton Web controls the same
GroupName property value, which will result in radio button HTML markup where each radio
button has the same name attribute, which will result in the user only being able to select
one of the related radio buttons.
However, as you can see in the DataGrid example I provided, even though the GroupName is
the same for all RadioButton Web controls in the column, the user can still select more than one distinct
radio button. To see why this is, let's take a look at the HTML markup produced by the ASP.NET Web
page when the above DataGrid example is used (you can take my word that the below HTML is the HTML markup
produced, or you can visit the live demo and do a View/Source):
<table cellspacing="0" cellpadding="4" ...>
<tr align="Center" ...>
<td> </td><td>FAQ ID</td><td>FAQ Description</td>
</tr><tr>
<td>
<input id="dgPopularFAQs__ctl2_NeitherDoesThis"
type="radio"
name="dgPopularFAQs:_ctl2:ThisDoesntWork"
value="NeitherDoesThis" />
</td><td>144</td><td>Where can I host my ASP Web ...</td>
</tr><tr style="background-color:White;">
<td>
<input id="dgPopularFAQs__ctl3_NeitherDoesThis"
type="radio"
name="dgPopularFAQs:_ctl3:ThisDoesntWork"
value="NeitherDoesThis" />
</td><td>115</td><td>I am using Access and ...</td>
</tr><tr>
<td>
<input id="dgPopularFAQs__ctl4_NeitherDoesThis"
type="radio"
name="dgPopularFAQs:_ctl4:ThisDoesntWork"
value="NeitherDoesThis" />
</td><td>161</td><td>How can I convert a Recordset ...</td>
</tr>
...
The above HTML markup has been shortened considerable for brevity, and is only showing a small subset
of the resulting HTML table rows produced by the DataGrid. However, the important part is still
noticeable from this sample, and that is that the name property of each of the radio buttons
is unique, even though we set the GroupName property to the same value (ThisDoesntWork)!
This is because the DataGrid is being built up row-by-row it prepends the rows ID property
to the GroupName property, using a colon as a delimiter. Then, it prepends the DataGrid's
ID property, and this is what the radio button's name attribute is assigned.
As you can see, the name for the first FAQ is: dgPopularFAQs:_ctl2:ThisDoesntWork,
which, more generally, is: DataGrid ID:DataGridItem ID:GroupName.
Ensuring that Each Radio Button's name Attribute is Identical
So how can we make sure that each radio button's name attribute is assigned the same value
when the DataGrid prepends the DataGridItem and DataGrid ID properties to the name
attribute? The only way that I have found to accomplish this is to use a custom DataGrid column class
from which you can explicitly override the naming of the name attribute. (If you know of
an easier way, please do let me know.)
What is a Custom DataGrid Column Class?
The DataGrid has a number of built-in columns, many of which we have examined throughout this
article series. Some of these include the BoundColumn, the TemplateColumn, and the ButtonColumn.
A custom DataGrid column class is one that you create yourself. They're fairly easy to create,
especially if you have a development tool like Visual Studio .NET (although this isn't a requirement).
For more information on creating your own custom DataGrid column class, be sure to read John Dyer's
Creating a Custom DataGridColumn Class.
Rather than writing our own custom DataGrid column class to perform this renaming, let's use one that
is already written, is 100% free, and includes complete source code. I am talking about Andy Smith's
excellent RowSelectorColumn control, which you can try out and download from
http://metabuilders.com/Tools/RowSelectorColumn.aspx.
Once you download the control, copy the control (the DLL file in the bin\Release directory
of the downloaded ZIP file) to your Web application's /bin directory. Then, you can
use Andy's control by simply adding:
to the top of your ASP.NET Web pages that use the control.
Let's now turn our attention to using the RowSelectorColumn in an ASP.NET Web page! We'll look at
creating a column of radio buttons, as well as a column of checkboxes, using the RowSelectorColumn in
Part 2!