扩展GridView(四)——每行复选框的全选与取消全选_[Asp.Net教程]
					GridView既强大又好用。为了让它更强大、更好用,我们来写一个继承自GridView的控件。 
[源码下载] 
http://files.cnblogs.com/webabcd/yycontrols.rar 
GridView(四)——每行复选框的全选与取消全选 
介绍 
平时使用GridView的时候经常要给每行加一个复选框,然后还需要放置一个单独的全选复选框,通过单击它来让这些复选框全选或取消全选,每次实现这样的功能都要写一段javascript,麻烦,所以扩展它。 
控件开发 
1、新建一个继承自GridView的类。 
复制C#代码保存代码/// 
/// 继承自GridView
/// 
[ToolboxData(@"<{0}:SmartGridView runat='server'>{0}:SmartGridView>")]
public class SmartGridView : GridView
{
}
2、新建一个JavaScriptConstant类,把我们要用到的javascript存在一个常量里 
复制C#代码保存代码using System;
using System.Collections.Generic;
using System.Text;
namespace YYControls.SmartGridView
{
 /// 
 /// javascript
 /// 
 public class JavaScriptConstant
 {
 internal const string jsCheckAll = @"
";
 }
}
3、新建一个CheckboxAll类,有两个属性 
复制C#代码保存代码using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Web.UI;
namespace YYControls.SmartGridView
{
 /// 
 /// CheckboxAll 的摘要说明。
 /// 
 [ToolboxItem(false)]
 public class CheckboxAll
 {
 private string _checkboxAllID;
 /// 
 /// 模板列全选复选框ID
 /// 
 public string CheckboxAllID
 {
 get { return _checkboxAllID; }
 set { _checkboxAllID = value; }
 }
 private string _checkboxItemID;
 /// 
 /// 模板列项复选框ID
 /// 
 public string CheckboxItemID
 {
 get { return _checkboxItemID; }
 set { _checkboxItemID = value; }
 }
 /// 
 /// ToString()
 /// 
 /// 
 public override string ToString()
 {
 return "CheckboxAll";
 }
 }
}
4、新建一个继承自CollectionBase的类CheckboxAlls 
复制C#代码保存代码using System.Collections;
using System.ComponentModel;
using System.Web.UI;
namespace YYControls.SmartGridView
{
 /// 
 /// CheckboxAlls 的摘要说明。
 /// 注意要继承自CollectionBase
 /// 
 [
 ToolboxItem(false),
 ParseChildren(true)
 ]
 public class CheckboxAlls : CollectionBase
 {
 /// 
 /// 构造函数
 /// 
 public CheckboxAlls()
 : base()
 {
 }
 /// 
 /// 实现IList接口
 /// 获取或设置指定索引处的元素。
 /// 
 /// 要获得或设置的元素从零开始的索引
 /// 
 public CheckboxAll this[int index]
 {
 get
 {
 return (CheckboxAll) base.List[index];
 }
 set
 {
 base.List[index] = (CheckboxAll) value;
 }
 }
 /// 
 /// 实现IList接口
 /// 将某项添加到 System.Collections.IList 中。
 /// 
 /// 要添加到 System.Collections.IList 的 System.Object。
 public void Add(CheckboxAll item)
 {
 base.List.Add(item);
 }
 /// 
 /// 实现IList接口
 /// 从 System.Collections.IList 中移除特定对象的第一个匹配项。
 /// 
 /// 要从 System.Collections.IList 移除的 System.Object
 public void Remove(int index)
 {
 if (index > -1 && index < base.Count)
 {
 base.List.RemoveAt(index);
 }
 }
 }
}
5、在继承自GridView的类中加一个复杂对象属性,该复杂对象就是第4步创建的那个CheckboxAlls 
复制C#代码保存代码private CheckboxAlls _checkboxAlls;
/// 
/// 复选框组集合 一个组由一个 全选复选框 和多个 项复选框组成
/// 
[
PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Description("复选框组集合 一个组由一个 全选复选框 和多个 项复选框组成"),
Category("扩展")
]
public virtual CheckboxAlls CheckboxAlls
{
 get
 {
 if (_checkboxAlls == null)
 {
 _checkboxAlls = new CheckboxAlls();
 }
 return _checkboxAlls;
 }
}
6、声明一些内部属性 
复制C#代码保存代码/// 
/// 隐藏字段的ID,用于存每组的全选复选框ID
/// 
protected string HiddenCheckboxAllID
{
 get { return "hdn_checkboxAll"; }
}
/// 
/// 隐藏字段的ID,用于存每组的项复选框ID
/// 
protected string HiddenCheckboxItemID
{
 get { return "hdn_checkboxItem"; }
}
/// 
/// 组分隔符,一个 全选复选框 和其对应的n个 项复选框 为一个组
/// 
protected char GroupSeparator
{
 get { return ','; }
}
/// 
/// 项分隔符,项复选框 每个项之间的分隔符
/// 
protected char ItemSeparator
{
 get { return '|'; }
}
7、声明几个私有变量 
复制C#代码保存代码/// 
/// 用于存每组的全选复选框ID
/// 
private string _checkAllIDString;
/// 
/// 用于存每的项复选框ID
/// 
private string _checkItemIDString;
/// 
/// 每行有一个组的所有项复选框
/// 
private Dictionary _checkItemIDDictionary = new Dictionary();
8、在继承自GridView的那个类的构造函数内加一个RowDataBound事件的处理,在该事件内给我们声明的那些私有变量赋值。 
复制C#代码保存代码/// 
/// 构造函数
/// 
public SmartGridView()
 : base()
{
 // 新增“SmartGridView_RowDataBound”事件处理
 this.RowDataBound += new GridViewRowEventHandler(SmartGridView_RowDataBound);
}
/// 
/// RowDataBound事件
/// 
/// sender
/// e
protected void SmartGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
 SmartGridView sgv = (SmartGridView) sender;
 if (e.Row.RowType == DataControlRowType.DataRow)
 {
 // GridViewRow的每个TableCell
 for (int i = 0; i < e.Row.Cells.Count; i++)
 {
 // TableCell里的每个Control
 for (int j = 0; j < e.Row.Cells[i].Controls.Count; j++)
 {
 if (e.Row.Cells[i].Controls[j] is CheckBox)
 {
 // 给Control增加一个客户端onclick
 ((CheckBox) e.Row.Cells[i].Controls[j]).Attributes.Add("onclick", "ClickCheckItem()");
 // 给_checkItemIDDictionary赋值
 if (_checkItemIDDictionary.Count == 0 || !_checkItemIDDictionary.ContainsKey(i))
 {
 _checkItemIDDictionary.Add(i, ((CheckBox) e.Row.Cells[i].Controls[j]).ClientID);
 }
 else
 {
 string s;
 _checkItemIDDictionary.TryGetValue(i, out s);
 _checkItemIDDictionary.Remove(i);
 _checkItemIDDictionary.Add(i, s + this.ItemSeparator + ((CheckBox) e.Row.Cells[i].Controls[j]).ClientID);
 }
 break;
 }
 }
 }
 }
 else if (e.Row.RowType == DataControlRowType.Header)
 {
 // GridViewRow的每个TableCell
 for (int i = 0; i < e.Row.Cells.Count; i++)
 {
 // TableCell里的每个Control
 for (int j = 0; j < e.Row.Cells[i].Controls.Count; j++)
 {
 if (e.Row.Cells[i].Controls[j] is CheckBox)
 {
 // 给Control增加一个客户端onclick
 ((CheckBox) e.Row.Cells[i].Controls[j]).Attributes.Add("onclick", "ClickCheckAll(this)");
 // 给_checkAllIDString赋值
 if (String.IsNullOrEmpty(this._checkAllIDString))
 {
 this._checkAllIDString += ((CheckBox) e.Row.Cells[i].Controls[j]).ClientID;
 }
 else
 {
 this._checkAllIDString += this.GroupSeparator + ((CheckBox) e.Row.Cells[i].Controls[j]).ClientID;
 }
 break;
 }
 }
 }
 }
}
9、重写GridView的OnPreRender方法,以实现每行复选框的全选与取消全选的功能。 
复制C#代码保存代码/// 
/// OnPreRender
/// 
/// 
protected override void OnPreRender(EventArgs e)
{
 base.OnPreRender(e);
 // 给_checkItemIDString赋值
 _checkItemIDString = "";
 foreach (KeyValuePair kvp in _checkItemIDDictionary)
 {
 _checkItemIDString += this.GroupSeparator + kvp.Value;
 }
 if (_checkItemIDString.StartsWith(this.GroupSeparator.ToString()))
 {
 _checkItemIDString = _checkItemIDString.Remove(0, 1);
 }
 // 注册实现 每行复选框的全选与取消全选 功能的JavaScript
 if (!Page.ClientScript.IsClientScriptBlockRegistered("JsCheckAll"))
 {
 Page.ClientScript.RegisterClientScriptBlock(
 this.GetType(),
 "JsCheckAll", JavaScriptConstant.jsCheckAll.Replace("[AllName]", this.HiddenCheckboxAllID).Replace("[ItemName]", this.HiddenCheckboxItemID).Replace("[GroupSeparator]", this.GroupSeparator.ToString()).Replace("[ItemSeparator]", this.ItemSeparator.ToString())
 );
 }
 // 注册实现 每行复选框的全选与取消全选 功能的两个隐藏字段
 Page.ClientScript.RegisterHiddenField(this.HiddenCheckboxAllID, this._checkAllIDString);
 Page.ClientScript.RegisterHiddenField(this.HiddenCheckboxItemID, this._checkItemIDString);
}
控件使用 
添加这个控件到工具箱里,然后拖拽到webform上,在模板列的头模板处添加一个复选框,在模板列的项模板处添加一个复选框,设置控件的CheckboxAlls属性即可。CheckboxAllID是模板列全选复选框ID;CheckboxItemID是模板列项复选框ID。 
ObjData.cs 
复制C#代码保存代码using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
/// 
/// OjbData 的摘要说明
/// 
public class OjbData
{
 public OjbData()
 {
 //
 // TOD 在此处添加构造函数逻辑
 //
 }
 [DataObjectMethod(DataObjectMethodType.Select, true)]
 public DataTable Select()
 {
 DataTable dt = new DataTable();
 dt.Columns.Add("no", typeof(string));
 dt.Columns.Add("name", typeof(string));
 for (int i = 0; i < 30; i++)
 {
 DataRow dr = dt.NewRow();
 dr[0] = "no" + i.ToString().PadLeft(2, '0');
 dr[1] = "name" + i.ToString().PadLeft(2, '0');
 dt.Rows.Add(dr);
 }
 return dt;
 }
}
Default.aspx 
复制ASPX代码保存代码<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 SmartGridView测试
 
转自【webabcd-.NET】