您的位置:首页 > 编程语言 > ASP

在ASP.NET的datagrid中使用radio button的历程

2008-04-01 16:03 323 查看
<!-- Countries for selection -->
<asp:DataGrid id="countriesGrid" runat="server"
DataKeyField="ID" AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<!--
Draw attention at this control.
We would like to use radio-buttons to
select single country from the list.
-->
<asp:RadioButton id="selectRadioButton"
runat="server" GroupName="country" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="Country" HeaderText="Country"
HeaderStyle-Font-Bold="True" />
<asp:BoundColumn DataField="Capital" HeaderText="Capital"
HeaderStyle-Font-Bold="True" />
</Columns>
</asp:DataGrid>

Now, bind to the
DataGrid
some data and run your ASP.NET application. Try to click at the radio buttons in the Countries list. You can select one country!... and another one... and another... Hmm-m! Didn't we really want to get this effect?

Where is a mistake? We have specified
GroupName
for the
RadioButton
s to treat them as from the single group, haven't we? Look at the piece of HTML code that has been generated from our web form. You will see something like this:

<!-- Countries for selection -->
<table cellspacing="0" rules="all" border="1" id="countriesGrid"
style="border-collapse:collapse;">
<tr>
<td> </td>
<td style="font-weight:bold;">Country</td>
<td style="font-weight:bold;">Capital</td>
</tr>
<tr>
<td><input id="countriesGrid__ctl2_selectRadioButton"
type="radio" name="countriesGrid:_ctl2:country"
value="selectRadioButton" /></td>
<td>USA</td>
<td>Washington</td>
</tr>
<tr>
<td><input id="countriesGrid__ctl3_selectRadioButton"
type="radio" name="countriesGrid:_ctl3:country"
value="selectRadioButton" /></td>
<td>Canada</td>
<td>Ottawa</td>
</tr>
<!-- etc. -->

The '
name
' attributes of the radio-buttons are different. Why? Here is the answer.

When rendering
RadioButton
control, ASP.NET uses concatenation of
GroupName
and
UniqueID
for the value of '
name
' attribute. So, this attribute depends on the
UniqueID
of the control which depends on the owner's
UniqueID
etc. It is the standard solution of ASP.NET to avoid naming collisions. As the value of the '
name
' attribute of the
<input type="radio" />
is used for identification of postback data of the radio-button group when the from is submitting, ASP.NET developers decided to isolate radio-button groups within the bounds of the single owner control (i.e., any two radio-buttons from the same group can not have different direct owners), otherwise it can occur that you will use two third party controls that both contain radio-button groups with the same
GroupName
- in this case, all radio-buttons will be treated as from the single group and that will bring undesirable behavior.

Now you have understood the cause of error, but how to implement the feature we want? In the next section, I'll provide you the solution.

Solution of the problem

To solve the problem I have stated above, I've created a new
GroupRadioButton
web control derived from the
RadioButton
.

In this control, I have changed the rendering method so that '
name
' attribute of the resulting HTML radio-button now depends on the
GroupName
only.

Another one modification is postback data handling (
IPostBackDataHandler
interface has been overridden).

Other functionality of the
GroupRadioButton
is equivalent to
RadioButton
.

See the source code of the
GroupRadioButton
for details.

Using the code

Now, let's modify the initial form. Use the following script for the Countries list:

<%@ Register TagPrefix="vs" Namespace="Vladsm.Web.UI.WebControls"
Assembly="GroupRadioButton" %>
...
<!-- Countries for selection -->
<asp:DataGrid id="countriesGrid" runat="server" DataKeyField="ID"
AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<vs:GroupRadioButton id="selectRadioButton"
runat="server" GroupName="country" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="Country" HeaderText="Country"
HeaderStyle-Font-Bold="True" />
<asp:BoundColumn DataField="Capital" HeaderText="Capital"
HeaderStyle-Font-Bold="True" />
</Columns>
</asp:DataGrid>

Add reference to the
GroupRadioButton
assembly, bind data for the
countriesGrid
, and execute this form. You will find that all radio-buttons are in the single group (i.e., user can check only one of them).

It remained only to show how to determine which of the countries have been selected:


Collapse
using Vladsm.Web.UI.WebControls;
...
private void selectButton_Click(object sender, System.EventArgs e)
{
// for each grid items...
foreach(DataGridItem dgItem in countriesGrid.Items)
{
// get GroupRadioButton object...
GroupRadioButton selectRadioButton =
dgItem.FindControl("selectRadioButton") as GroupRadioButton;

// if it is checked (current item is selected)...
if(selectRadioButton != null && selectRadioButton.Checked)
{
// sample data that was boud to the countriesGrid
DataTable dataSource = DataSource.CreateSampleDataSource();

// get country corresponding to the current item...
DataRow row =
dataSource.Rows.Find(countriesGrid.DataKeys[dgItem.ItemIndex]);

// ...and show selected country information
selectedCountryInfo.Text =
String.Format("Selected country: {0}, Capital: {1}",
row["Country"], row["Capital"]);

return;
}
}

// there are no selected countries
selectedCountryInfo.Text = String.Empty;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: