在ASP.NET 2.0中操作数据之五十:为GridView控件添加Checkbox
导言:
在前面的教程里我们探讨了如何为gridview控件添加radio buttons列。当用户最多只能选择一项数据时,我们可以在用户界面里添加radio buttons列,而有时候,我们需要选择任意多项数据。比如,基于web的邮箱客户端列出了一系列的邮件,及一列checkboxes,用户可选择任意封邮件并执行相同的操作,比如移动到另一个文件夹或将之删除。
在本教程,我们将探讨如何添加checkboxes列,以及发生页面回传后如何确定到底选择了哪些checkboxes。特别的,我们将练习一个类似于基于web的邮箱客户端用户界面。实例将包含一个启用了分页功能的gridview,用于列出表products中的产品,每行记录包含一个checkbox(见图1)。当点击“delete selected products”按钮时,删除选中的产品。
图1:每个product row包含一个checkbox
第1步:添加一个启用分页的gridview控件展示产品信息
在考虑添加checkboxes列前,我们先创建一个展示产品的gridview控件并启用分页。在文件夹enhancedgridview里打开checkboxfield.aspx页面并进入设计模式,从工具箱拖一个gridview到页面,设其id为products。下一步,将其绑定到一个名为productsdatasource的objectdatasource控件。该objectdatasource控件使用productsbll类,调用getproducts()方法返回数据。因为本例的gridview控件是只读的,在update, insert和delete选项卡的下拉列表里选“(none)”。
图2:创建一个名为productsdatasource的objectdatasource控件
图3:设置该objectdatasource控件调用getproducts()方法获取数据
图4:在update, insert和delete选项卡的下拉列表里选“(none)”。
完成设置后,visual studio会自动为相关数据域(data fields)创建boundcolumns及一个checkboxcolumn。就像我们在前面的教程做的那样,将除了 productname, categoryname和unitprice外的其它boundfields删除,并将相关headertext属性设置为“product”, “category”和“price”。将unitprice boundfield格式化为货币形式。在智能标签里选择“enable paging”启用gridview的分页功能。
为了在用户界面里可以删除选中的产品,在gridview下面添加一个button web控件,设其id为deleteselectedproducts,text属性为“delete selected products”。在本例中我们不会直接从数据库删除数据,而是显示一条消息,说明要删除的是什么产品。因此,在按钮下面添加一个label web控件,设其id为deleteresults,清空其text属性, 将visible和enableviewstate属性都设为false。
做完上述修改后,gridview, objectdatasource, button和label的声明代码应和下面的差不多:
<p> <asp:gridview id="products" runat="server" autogeneratecolumns="false" datakeynames="productid" datasourceid="productsdatasource" allowpaging="true" enableviewstate="false"> <columns> <asp:boundfield datafield="productname" headertext="product" sortexpression="productname" /> <asp:boundfield datafield="categoryname" headertext="category" readonly="true" sortexpression="categoryname" /> <asp:boundfield datafield="unitprice" dataformatstring="{0:c}" headertext="price" htmlencode="false" sortexpression="unitprice" /> </columns> </asp:gridview> <asp:objectdatasource id="productsdatasource" runat="server" oldvaluesparameterformatstring="original_{0}" selectmethod="getproducts" typename="productsbll"> </asp:objectdatasource> </p> <p> <asp:button id="deleteselectedproducts" runat="server" text="delete selected products" /> </p> <p> <asp:label id="deleteresults" runat="server" enableviewstate="false" visible="false"></asp:label> </p>
花几分钟在浏览器里观看页面(见图5),你可以看到前10个产品的name, category以及price。
图5:显示前10个产品的name, category以及price
第2步:添加一个checkboxes列
由于asp.net 2.0 包含一个checkboxfield,我们也许自然会想到用它来为gridview控件添加一个checkboxes列。然而,并不是那样回事。因为checkboxfield是专门设计来与布尔数据域(boolean data field)打交道。
也就是说,当数据域的值可以用来判断是否选中了checkbox时,checkboxfield才派地上用场。checkboxfield不能正确的包含一列未选中的checkboxes。
作为替换,我们必须添加一个模板,并在其itemtemplate模式里添加一个checkbox web控件。我们要在gridview控件products里添加一个模板,并放在最左边。在gridview的智能标签里点“编辑模板”,在itemtemplate模式里添加一个checkbox web控件,设其id为productselector。
图6:在模板的itemtemplate模式里添加一个名为productselector的checkbox web控件
添加模板和checkbox web控件后,每一行记录将包含一个checkbox按钮,如图7所示:
图7:每个产品行包含一个checkbox按钮
第3步:页面回传后确定点击了哪些checkboxes按钮
现在我们已经创建了一个checkboxes列,但在页面发生回传后还不能确定点击了哪些checkboxes按钮,但当点击“delete selected products”按钮时,我们需要确定要删除的是哪些产品,也即点击了哪些checkboxes按钮。
我们可以运用gridview的rows属性访问其数据行(data rows),编程访问该记录行的checkbox控件,根据其checked属性来判断是否选中了该按钮。
为名为deleteselectedproducts的button web控件的click事件创建一个事件处理器,添加如下代码:
protected void deleteselectedproducts_click(object sender, eventargs e) { bool atleastonerowdeleted = false; // iterate through the products.rows property foreach (gridviewrow row in products.rows) { // access the checkbox checkbox cb = (checkbox)row.findcontrol("productselector"); if (cb != null && cb.checked) { // delete row! (well, not really...) atleastonerowdeleted = true; // first, get the productid for the selected row int productid = convert.toint32(products.datakeys[row.rowindex].value); // "delete" the row deleteresults.text += string.format( "this would have deleted productid {0}<br />", productid); } } // show the label if at least one row was deleted... deleteresults.visible = atleastonerowdeleted; }
gridview控件的rows属性返回构成gridview数据行的gridviewrow实例集合。而foreach()循环将遍历集合中的每一个实例。在一个gridviewrow对象中,我们通过使用row.findcontrol("controlid")的形式来访问该行记录的checkbox按钮。如果选择了该按钮,从datakeys集合里获取与该行记录相对应的productid值。
在本例,我们仅仅是在label控件deleteresults里显示相关提示信息,而在实际的应用程序中,我们应该调用productsbll类的deleteproduct(productid)方法。
添加完上述事件处理器后,点击“delete selected products”按钮,将会显示那些被选中的产品的productid值。
图8:当点击“delete selected products”时,将列出所选产品的productid值
第4步:添加“check all”和“uncheck all”按钮
如果用户想删除当前页面上的所有产品,则必须点击每行的checkbox按钮,稍
显麻烦。我们可以添加一个“check all”按钮,当点击该按钮时可以选中页面上的所有checkbox按钮。反之,添加一个“uncheck all”按钮。
在页面上添加2个button web控件,放在gridview的上面。设第一个的id为checkall,text属性为“check all”; 设第二个的id为uncheckall,text属性为“uncheck all”,如下:
<asp:button id="checkall" runat="server" text="check all" /> <asp:button id="uncheckall" runat="server" text="uncheck all" />
接着,在后台代码类(code-behind class)里创建一个名为togglecheckstate(checkstate)的方法。调用该方法时,其遍历gridview控件products的rows集合,根据传入的参数checkstate对每个checkbox的checked属性赋值。
private void togglecheckstate(bool checkstate) { // iterate through the products.rows property foreach (gridviewrow row in products.rows) { // access the checkbox checkbox cb = (checkbox)row.findcontrol("productselector"); if (cb != null) cb.checked = checkstate; } }
然后,为button控件checkall和uncheckall创建click事件处理器,在checkall的click事件处理器中,仅仅简单的调用togglecheckstate(true); 在uncheckall的事件处理器中,调用togglecheckstate(false),如下:
protected void checkall_click(object sender, eventargs e) { togglecheckstate(true); } protected void uncheckall_click(object sender, eventargs e) { togglecheckstate(false); }
当点击“check all”按钮时,引发页面回传,并选中所有的checkbox按钮;点击“uncheck all”时,弃选所有的checkbox按钮。图9为点击“check all”按钮后的界面。
图9:点“check all”按钮选择所有的checkbox
注意:如果要全选或弃选checkbox按钮的话,我们也可以通过点击标题行(header row)的checkbox来实现,并且在页面发生回转后才能生效。完全使用客户端脚本(client-side script)来执行全选或弃选checkbox按钮,那将是一种更爽的用户体验。
总结:
当用户需要在gridview里任意的选择记录时,我们可以添加一列checkbox按按钮。正如本章探究的那样,在gridview里添加一个模板,再在模板里添加一个checkbox web控件。如果使用web控件(对比上一章,我们直接在模板里注入代码),在页面发生回转后,asp.net自动的记得选中了或没选中哪些checkbox控件。我们也可以编程访问这些checkbox,判断是否选中了某个checkbox,或改变其checked状态。
祝编程快乐!
作者简介
本系列教程作者 scott mitchell,著有六本asp/asp.net方面的书,是4guysfromrolla.com的创始人,自1998年以来一直应用 微软web技术。大家可以点击查看全部教程《[翻译]scott mitchell 的asp.net 2.0数据教程》,希望对大家的学习asp.net有所帮助。
推荐阅读
-
在ASP.NET 2.0中操作数据之四十九:为GridView控件添加RadioButton
-
在ASP.NET 2.0中操作数据之五十:为GridView控件添加Checkbox
-
在ASP.NET 2.0中操作数据之六十四:GridView批量添加数据
-
在ASP.NET 2.0中操作数据之六十八:为DataTable添加额外的列
-
在ASP.NET 2.0中操作数据之十二:在GridView控件中使用TemplateField
-
在ASP.NET 2.0中操作数据之五十:为GridView控件添加Checkbox
-
在ASP.NET 2.0中操作数据之四十九:为GridView控件添加RadioButton
-
在ASP.NET 2.0中操作数据之六十四:GridView批量添加数据
-
在ASP.NET 2.0中操作数据之六十八:为DataTable添加额外的列