GridViewID="Products"runat="server"AutoGenerateColumns="False"
DataKeyNames="ProductID"DataSourceID="ProductsDataSource"
AllowPaging="True"EnableViewState="False">
BoundFieldDataField="ProductName"HeaderText="Product"
SortExpression="ProductName"/>
BoundFieldDataField="CategoryName"HeaderText="Category"
ReadOnly="True"SortExpression="CategoryName"/>
BoundFieldDataField="UnitPrice"DataFormatString="{0:
c}"
HeaderText="Price"HtmlEncode="False"
SortExpression="UnitPrice"/>
GridView>
ObjectDataSourceID="ProductsDataSource"runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts"TypeName="ProductsBLL">
ObjectDataSource>
ButtonID="DeleteSelectedProducts"runat="server"
Text="DeleteSelectedProducts"/>
LabelID="DeleteResults"runat="server"EnableViewState="False"
Visible="False">
Label>
花几分钟在浏览器里观看页面(见图5),你可以看到前10个产品的name,category以及price。
图5:
显示前10个产品的name,category以及price
第2步:
添加一个Checkboxes列
由于ASP.NET2.0包含一个CheckBoxField,我们也许自然会想到用它来为GridView控件添加一个Checkboxes列。
然而,并不是那样回事。
因为CheckBoxField是专门设计来与布尔数据域(Booleandatafield)打交道。
也就是说,当数据域的值可以用来判断是否选中了checkbox时,CheckBoxField才派地上用场。
CheckBoxField不能正确的包含一列未选中的checkboxes。
作为替换,我们必须添加一个模板,并在其ItemTemplate模式里添加一个CheckBoxWeb控件。
我们要在GridView控件Products里添加一个模板,并放在最左边。
在GridView的智能标签里点“编辑模板”,在ItemTemplate模式里添加一个CheckBoxWeb控件,设其ID为ProductSelector。
图6:
在模板的ItemTemplate模式里添加一个名为ProductSelector的CheckBoxWeb控件
添加模板和CheckBoxWeb控件后,每一行记录将包含一个CheckBox按钮,如图7所示:
图7:
每个产品行包含一个CheckBox按钮
第3步:
页面回传后确定点击了哪些Checkboxes按钮
现在我们已经创建了一个checkboxes列,但在页面发生回传后还不能确定点击了哪些Checkboxes按钮,但当点击“DeleteSelectedProducts”按钮时,我们需要确定要删除的是哪些产品,也即点击了哪些Checkboxes按钮。
我们可以运用GridView的Rows属性访问其数据行(datarows),编程访问该记录行的CheckBox控件,根据其Checked属性来判断是否选中了该按钮。
为名为DeleteSelectedProducts的ButtonWeb控件的Click事件创建一个事件处理器,添加如下代码:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protectedvoidDeleteSelectedProducts_Click(objectsender,EventArgse)
{
boolatLeastOneRowDeleted=false;
//IteratethroughtheProducts.Rowsproperty
foreach(GridViewRowrowinProducts.Rows)
{
//AccesstheCheckBox
CheckBoxcb=(CheckBox)row.FindControl("ProductSelector");
if(cb!
=null&&cb.Checked)
{
//Deleterow!
(Well,notreally...)
atLeastOneRowDeleted=true;
//First,gettheProductIDfortheselectedrow
intproductID=
Convert.ToInt32(Products.DataKeys[row.RowIndex].Value);
//"Delete"therow
DeleteResults.Text+=string.Format(
"ThiswouldhavedeletedProductID{0}
",productID);
}
}
//ShowtheLabelifatleastonerowwasdeleted...
DeleteResults.Visible=atLeastOneRowDeleted;
}
GridView控件的Rows属性返回构成GridView数据行的GridViewRow实例集合。
而foreach()循环将遍历集合中的每一个实例。
在一个GridViewRow对象中,我们通过使用row.FindControl("controlID")的形式来访问该行记录的CheckBox按钮。
如果选择了该按钮,从DataKeys集合里获取与该行记录相对应的ProductID值。
在本例,我们仅仅是在Label控件DeleteResults里显示相关提示信息,而在实际的应用程序中,我们应该调用ProductsBLL类的DeleteProduct(productID)方法。
添加完上述事件处理器后,点击“DeleteSelectedProducts”按钮,将会显示那些被选中的产品的ProductID值。
图8:
当点击“DeleteSelectedProducts”时,将列出所选产品的ProductID值
第4步:
添加“CheckAll”和“UncheckAll”按钮
如果用户想删除当前页面上的所有产品,则必须点击每行的checkbox按钮,稍
显麻烦。
我们可以添加一个“CheckAll”按钮,当点击该按钮时可以选中页面上的所有checkbox按钮。
反之,添加一个“UncheckAll”按钮。
在页面上添加2个ButtonWeb控件,放在GridView的上面。
设第一个的ID为CheckAll,Text属性为“CheckAll”;设第二个的ID为UncheckAll,Text属性为“UncheckAll”,如下:
?
1
2
3
ButtonID="CheckAll"runat="server"Text="CheckAll"/>
ButtonID="UncheckAll"runat="server"Text="UncheckAll"/>
接着,在后台代码类(code-behindclass)里创建一个名为ToggleCheckState(checkState)的方法。
调用该方法时,其遍历GridView控件Products的Rows集合,根据传入的参数checkState对每个CheckBox的Checked属性赋值。
?
1
2
3
4
5
6
7
8
9
10
11
privatevoidToggleCheckState(boolcheckState)
{
//IteratethroughtheProducts.Rowsproperty
foreach(GridViewRowrowinProducts.Rows)
{
//AccesstheCheckBox
CheckBoxcb=(CheckBox)row.FindControl("ProductSelector");
if(cb!
=null)
cb.Checked=checkState;
}
}
然后,为button控件CheckAll和UncheckAll创建Click事件处理器,在CheckAll的Click事件处理器中,仅仅简单的调用ToggleCheckState(true);在UncheckAll的事件处理器中,调用ToggleCheckState(false),如下:
?
1
2
3
4
5
6
7
8
9
protectedvoidCheckAll_Click(objectsender,EventArgse)
{
ToggleCheckState(true);
}
protectedvoidUncheckAll_Click(objectsender,EventArgse)
{
ToggleCheckState(false);
}
当点击“CheckAll”按钮时,引发页面回传,并选中所有的checkbox按钮;点击“UncheckAll”时,弃选所有的checkbox按钮。
图9为点击“CheckAll”按钮后的界面。
图9:
点“CheckAll”按钮选择所有的Checkbox
注意:
如果要全选或弃选checkbox按钮的话,我们也可以通过点击标题行(headerrow)的checkbox来实现,并且在页面发生回转后才能生效。
完全使用客户端脚本(client-sidescript)来执行全选或弃选checkbox按钮,那将是一种更爽的用户体验。
总结:
当用户需要在GridView里任意的选择记录时,我们可以添加一列checkbox按按钮。
正如本章探究的那样,在GridView里添加一个模板,再在模板里添加一个CheckBoxWeb控件。
如果使用Web控件(对比上一章,我们直接在模板里注入代码),在页面发生回转后,ASP.NET自动的记得选中了或没选中哪些CheckBox控件。
我们也可以编程访问这些CheckBox,判断是否选中了某个CheckBox,或改变其checked状态。