在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有所帮助。

(0)

相关推荐

  • asp.net 字符串、二进制、编码数组转换函数

    1.字符串转二进制数组 string content="这是做个测试!"; System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding(); byte[] byteArr = converter.GetBytes(content); 2.二进制数组转为字符串 复制代码 代码如下: System.Text.UnicodeEncoding converter = new System.Text.Unicod

  • asp.net(c#)实现从sqlserver存取二进制图片的代码

    下面说说主要实现思路: 1.存取图片 (1).将图片文件转换为二进制并直接存进sql server 复制代码 代码如下: //UploadHelper.cs /// <summary> /// 将图片转化为长二进制 /// </summary> /// <param name="photopath"></param> /// <returns></returns> public static Byte[] SetI

  • 在ASP.NET 2.0中操作数据之五十三:在Data Web控件显示二进制数据

    导言: 在前面的教程我们阐述了应用程序处理二进制数据的2种模式,以及使用FileUpload 控件从浏览器向服务器文件系统上传文件.当文件上传并存储在文件系统里时,应在相应的数据库记录里存储该文件的存储路径. 我们先来看如何为最终用户提供二进制数据.怎样展示二进制数据呢?这取决于其类型.比如图片,我们将其显示为image:如果是PDFs,Microsoft Word文档.ZIP文件或其它类型的数据,或许提供一个"Download"链接比较妥当. 在本节,我们看如何在GridView和D

  • ASP.NET实现图片以二进制的形式存入数据库

    本文以实例形式讲述了ASP.NET实现图片以二进制的形式存入数据库的方法.过去我们都是直接在数据库中存入图片文件名的,还没有试过存储整张图片到数据库中,经过一番资料查询与测试,整理出了如下的功能代码: 1.建立保存图片的表的SQL语句: USE [niunantest] GO /****** 对象: Table [dbo].[picdata] 脚本日期: 03/30/2010 14:51:58 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER

  • 在ASP.NET 2.0中操作数据之五十二:使用FileUpload上传文件

    导言: 到目前为止,我们的教程围绕的是text数据.然而,很多应用程序既需要处理text数据,也需要处理二进制数据.比如招聘网站可能需要用户上传Word或PDF格式的简历. 使用二进制数据面临一项挑战:在应用程序中如何存储二进制数据.我们必须更新添加记录的界面以支持用户上传本地电脑中的文件,并添加额外的功能以下载某条记录的相关二进制数据.本章以及接下来的3章,我们探讨如何处理这些问题.在本系列教程结束时,我们将创建一个功能完善的应用程序,它为每种类型的记录提供相关的图片和PDF小册子. 在本系列

  • asp.net实现图片以二进制流输出的两种方法

    本文实例讲述了asp.net实现图片以二进制流输出的两种方法.分享给大家供大家参考,具体如下: 方法一: System.IO.MemoryStream ms = new System.IO.MemoryStream(); System.IO.Stream str = new FileUpload().PostedFile.InputStream; System.Drawing.Bitmap map = new System.Drawing.Bitmap(str); map.Save(ms, Sy

  • 在ASP.NET 2.0中操作数据之四十九:为GridView控件添加RadioButton

    导言: GridView控件提供了大量的内置功能.它包含了一系列的域(field)来显示诸如text.images.hyperlinks和buttons.另外它支持模板(template)用于用户自定义界面.我们可以构建这样一个GridView控件,用户仅需要点击控件里的一个按钮,每一条记录行都可以选择.编辑.删除.除了控件本身内置的功能外,在某些情况下,我们添加一些额外的.控件没有内置的功能.在本章及接下来的2篇教程里我们将探讨如何优化GridView,以支持额外的功能. 本篇及接下来的教程将

  • 在ASP.NET 2.0中操作数据之五十一:从GridView的页脚插入新记录

    导言: 正如教程<概述插入.更新和删除数据>里探讨过的一样, GridView, DetailsView和FormView Web控件都有内置的修改数据的功能.当声明绑定到数据源控件时,可以快速而方便地修改数据--甚至不用写一行代码.不幸的是,只有DetailsView和FormView控件提供了内置的插入.编辑.删除功能,而 GridView控件只支持编辑.删除功能.不过,稍许努力,我们就能使GridView控件包含一个插入界面. 为了给GridView添加插入功能,我们要决定如何添加新记录

  • asp.net 上传下载输出二进制流实现代码

    复制代码 代码如下: using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls;

  • asp.net 将一个图片以二进制值的形式存入Xml文件中的实例代码

    复制代码 代码如下: try   {    int readByte = 0;        //    int bytesToRead = 100;       //数据缓冲区大小    string fileName = "../../WriteXml.xml";   //要打开的文件    //   this.textBox1.Text = string.Empty;                // 打开图片文件,利用该图片构造一个文件流    FileStream fs =

随机推荐