DataGrid和CheckBox的混合使用

我们知道 DataGrid 是非常强大的一个 ASP.NET 组件 , 我们可以用它表示非常丰富的信息 . 在论坛里经常可以看见一些网友问一些关于该控件的问题 , 我虽不是什么高手但是对 DataGrid 还是有一些了解 , 加上我比较喜欢学习所以我今天就将 DataGrid 和 CheckBox 的组合使用做一个简单的描述 . 我们可能在写程序的时候都遇到这种情况 : 需要选择一个列表的所有项或者取消所有项的选择来删除这些列以及如何给用户一个提示信息是否要删除 ( 改功能我在相关文档里描述过了 ), 我也遇到这个问题 . 我解决它有 2 个方案分别描述如下 :

解决方案一 :

1. 使用一个页面的 CheckBox 来完成这项艰巨的任务 ( 夸张了 ), 由于这个方法非常简单所以我也就不写代码只是做一个简单的描述就可以了 . 我们在我们页面上的 DataGrid 的上面或者下面放置一个 CheckBox 控件 , 最好用 Table 来控制位置这样看起来更加清楚 . 我们可以将这个 CheckBox 的 AutoPostBack 设置成 true. 这样我们可以让它提交服务器事件 . 很显然我们想要利用服务器事件来实现这个功能 , 后面就是遍历 DataGrid 的所有行来和 CheckBox 的 Checked 的选择相一致 .

2. 依然是使用服务器的事件来完成我们的工作 , 这次有些不同我们将这个 CheckBox 放到 DataGrid 中对应 CheckBox 的列的页眉上 (header). 我们给这个模板列的题头上添加一个 CheckBox 控件利用它来完成和 1 中相同的工作 , 只是过程稍微有些不同 . 首先我们需要一个 DataGrid 来表现我们的程序 , 该 DataGrid 在 Html 页上的代码如下 :

 1<asp:datagrid id="grdServer" runat="server">
 2<columns>
 3<asp:templatecolumn>
 4<headertemplate>
 5<asp:checkbox autopostback="True" id="chkAllServer" runat="server"></asp:checkbox>
 6</headertemplate>
 7<itemtemplate>
 8<asp:checkbox id="chkDelServer" runat="server"></asp:checkbox>
 9</itemtemplate>
10</asp:templatecolumn>
11<asp:boundcolumn datafield="au_id" headertext="  编号  "></asp:boundcolumn>
12
13//  只显示主要的下面的不写了  ……  在  grdClient  中有绑定的详细列 
14
15</columns></asp:datagrid>

我们给 HerderTemple 添加了一个 chkAllServer 其中 Server 说明它是调用服务器端事件的 . 我们为了给这个控件添加事件必须在创建 DataGridItem 的时候给它添加事件代码如下 :

private void grdServer_ItemCreated( object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) {

if (e.Item.ItemType == ListItemType.Header){

CheckBox chk = (CheckBox)e.Item.FindControl("chkAllServer");

// 给页眉上的 CheckBox 添加出发事件

chk.CheckedChanged += new EventHandler(chk_CheckedChanged);

}

}

事件处理程序如下所示 :

// 得到指定 DataGrid 的题头的 CheckBox 对象

private CheckBox GetHeaderCheckBox(DataGrid grd){

CheckBox chk = null ;

foreach (DataGridItem i in grd.Controls[0].Controls){

if (i.ItemType == ListItemType.Header){

chk = (CheckBox)i.FindControl("chkAllServer");

break ;

}

}

return chk;

}

private void chk_CheckedChanged( object sender, System.EventArgs e) {

CheckBox chk = this .GetHeaderCheckBox( this .grdServer);

foreach (DataGridItem i in this .grdServer.Items){

CheckBox inChk = (CheckBox)i.FindControl("chkDelServer");

inChk.Checked = chk.Checked;

}

}

该事件处理程序将 DataGrid 里面的所有的 CheckBox 的 Checked 变的和题头的 CheckBox 的 Checked 的状态一样 .

解决方案二 :

这个方案对应上面的服务器事件主要是描述客户端的事件 . 同样也有两个小的稍有不同的办法 .

1. 和方案一的 1 一样 , 但是他是支持客户端的选中脚本至于脚本的内容下面 2 中会详细介绍 .

2. 和解决方案一一样我们将 CheckBox 依然放在 Header 里面 , 稍有不同的是我们这次使用的是客户端脚本 . 为了实现这个功能我们在页面上放一个 DataGrid 如下 :

 1<asp:datagrid id="grdClient" runat="server">
 2<columns>
 3<asp:templatecolumn>
 4<headertemplate>
 5<asp:checkbox id="chkAll" runat="server"></asp:checkbox>
 6</headertemplate>
 7<itemtemplate>
 8<asp:checkbox id="chkDelete" runat="server"></asp:checkbox>
 9</itemtemplate>
10</asp:templatecolumn>
11<asp:boundcolumn datafield="au_id" headertext="  编号  "></asp:boundcolumn>
12<asp:boundcolumn datafield="name" headertext="  姓名  "></asp:boundcolumn>
13<asp:boundcolumn datafield="phone" headertext="  电话  "></asp:boundcolumn>
14<asp:boundcolumn datafield="address" headertext="  地址  "></asp:boundcolumn>
15<asp:boundcolumn datafield="city" headertext="  城市  "></asp:boundcolumn>
16<asp:boundcolumn datafield="state" headertext="  状态  "></asp:boundcolumn>
17<asp:boundcolumn datafield="zip" headertext="  邮编  "></asp:boundcolumn>
18</columns>
19</asp:datagrid>

为了实现客户端脚本的功能我们还要为页面添加 Javascript 脚本 , 脚本代码如下 :

 1<script language="javascript">
 2
 3function SelectAll (chkVal, idVal) { 
 4
 5var thisfrm = document.forms[0]; 
 6
 7//  查找  Forms  里面所有的元素 
 8
 9for (i=0; i<thisfrm.length; i++) { 
10
11//  查找模板头中的  CheckBox 
12
13if (idVal.indexOf ('chkAll') != -1) { 
14
15if(chkVal == true) { 
16
17thisfrm.elements[i].checked = true; 
18
19} 
20
21else { 
22
23thisfrm.elements[i].checked = false; 
24
25} 
26
27} // if 
28
29//  如果除题头以外的项没有全选上则取消题头的选择 
30
31else if (idVal.indexOf ('chkDelete') != -1) { 
32
33if(thisfrm.elements[i].checked == false) { 
34
35thisfrm.elements[1].checked = false; 
36
37} 
38
39} 
40
41} // for 
42
43} 
44
45//  删除判断 
46
47function confirmDelete (thisfrm) { 
48
49for (i=0; i<thisfrm.length; i++) { 
50
51if (thisfrm.elements[i].name.indexOf('chkDelete') !=-1) { 
52
53if(thisfrm.elements[i].checked) { 
54
55return confirm ('  你是否想要删除选择的记录  ?') 
56
57} 
58
59} 
60
61} 
62
63} 
64
65</script>

为了可以让这些控件和这些脚本联系上我们还需要在服务器端写如下的代码 :

private void grdClient_ItemDataBound( object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) {

if (e.Item.ItemType == ListItemType.Header){

CheckBox chk = (CheckBox)e.Item.FindControl("chkAll");

chk.Attributes.Add("onclick","javascript:return SelectAll(this.checked,this.id)");

}

else if (e.Item.ItemType == ListItemType.Item){

CheckBox chk = (CheckBox)e.Item.FindControl("chkDelete");

chk.Attributes.Add("onclick","javascript:return SelectAll(this.checked,this.id)");

}

}

为了绑定这两个 DataGrid 我们写了如下的绑定方法 :

private void BindData(){

string commandText = "SELECT au_id, au_lname+au_fname as name, phone, address, city, state, zip FROM authors";

DataView dv = SqlHelper.ExecuteDataset(ConfigurationSettings.AppSettings["ConnectString"],CommandType.Text,commandText).Tables[0].DefaultView;

this .grdClient.DataSource = dv;

this .grdClient.DataBind();

this .grdServer.DataSource = dv;

this .grdServer.DataBind();

}

上面的代码可以看出我使用了 Microsoft.ApplicationBlocks.Data 命名空间里的 SqlHelper, 这个 dll 你可以从微软的网站上下载得到它的源码 .

最后就是在页面加载的时候把我们的删除确认事件加载到客户端以及绑定我们的数据了 , 代码如下 :

private void Page_Load( object sender, System.EventArgs e) {

// 在此处放置用户代码以初始化页面

this .btnDelete.Attributes.Add("onclick", "return confirmDelete (this.form);");

if (! this .IsPostBack){

this .BindData();

}

}

至于如何删除数据我想大家可能都知道我在这里就不说了 , 如果需要这个工程的源代码请发邮件到 [email protected] 所取 , 希望有更好办法的同志可以继续 . 学习交流请联系上面 email 对应的 MSN! 文章中的错误请大家批评指正 , 谢谢 !

Published At
Categories with Web编程
Tagged with
comments powered by Disqus