众所周知,datagridview控件是CS架构中用的比较频繁的一个控件,里面提供了checkbox列的功能,可是却没有在列头给出checkbox控件用于全选/全部取消所有行的功能,确实是个遗憾,这里就通过绘制实现这个功能.
该程序参考codeproject上的程序,网址如下:
http://www.codeproject.com/KB/grid/CheckBoxHeaderCell.aspx 向其致敬!
一.创建一个表,里面包含bit字段,datagridview的DataGridViewCheckBoxColumn列会自动将其转换成checkbox列
见表语句如下,数据库名为testDB
CREATE TABLE [dbo].[UserInfo] (
[RID] [varchar] (32) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[username] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,
[gendar] [bit] NULL
) ON [PRIMARY]
二.主要代码
datagridviewCheckboxHeaderEventArgs类,用在在checkbox单击事件中提供类头checkbox的选择状态
Code
1 //定义包含列头checkbox选择状态的参数类
2 class datagridviewCheckboxHeaderEventArgs : EventArgs
3 {
4 private bool checkedState = false;
5
6 public bool CheckedState
7 {
8 get { return checkedState; }
9 set { checkedState = value; }
10 }
11 }
datagridviewCheckboxHeaderCell类,这是个关键列,用于绘制列头checkbox和创建鼠标单击事件
Code
1 //定义继承于DataGridViewColumnHeaderCell的类,用于绘制checkbox,定义checkbox鼠标单击事件
2 class datagridviewCheckboxHeaderCell : DataGridViewColumnHeaderCell
3 {
4 Point checkBoxLocation;
5 Size checkBoxSize;
6 bool _checked = false;
7 Point _cellLocation = new Point();
8 System.Windows.Forms.VisualStyles.CheckBoxState _cbState =
9 System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
10 public event datagridviewcheckboxHeaderEventHander OnCheckBoxClicked;
11
12
13 //绘制列头checkbox
14 protected override void Paint(System.Drawing.Graphics graphics,
15 System.Drawing.Rectangle clipBounds,
16 System.Drawing.Rectangle cellBounds,
17 int rowIndex,
18 DataGridViewElementStates dataGridViewElementState,
19 object value,
20 object formattedValue,
21 string errorText,
22 DataGridViewCellStyle cellStyle,
23 DataGridViewAdvancedBorderStyle advancedBorderStyle,
24 DataGridViewPaintParts paintParts)
25 {
26 base.Paint(graphics, clipBounds, cellBounds, rowIndex,
27 dataGridViewElementState, value,
28 formattedValue, errorText, cellStyle,
29 advancedBorderStyle, paintParts);
30 Point p = new Point();
31 Size s = CheckBoxRenderer.GetGlyphSize(graphics,
32 System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
33 p.X = cellBounds.Location.X +
34 (cellBounds.Width / 2) - (s.Width / 2) - 1;//列头checkbox的X坐标
35 p.Y = cellBounds.Location.Y +
36 (cellBounds.Height / 2) - (s.Height / 2);//列头checkbox的Y坐标
37 _cellLocation = cellBounds.Location;
38 checkBoxLocation = p;
39 checkBoxSize = s;
40 if (_checked)
41 _cbState = System.Windows.Forms.VisualStyles.
42 CheckBoxState.CheckedNormal;
43 else
44 _cbState = System.Windows.Forms.VisualStyles.
45 CheckBoxState.UncheckedNormal;
46 CheckBoxRenderer.DrawCheckBox
47 (graphics, checkBoxLocation, _cbState);
48 }
49
50
51
52 /// <summary>
53 /// 点击列头checkbox单击事件
54 /// </summary>
55 protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
56 {
57
58 Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y);
59 if (p.X >= checkBoxLocation.X && p.X <=
60 checkBoxLocation.X + checkBoxSize.Width
61 && p.Y >= checkBoxLocation.Y && p.Y <=
62 checkBoxLocation.Y + checkBoxSize.Height)
63 {
64 _checked = !_checked;
65
66
67 //获取列头checkbox的选择状态
68 datagridviewCheckboxHeaderEventArgs ex = new datagridviewCheckboxHeaderEventArgs();
69 ex.CheckedState = _checked;
70
71 object sender = new object();//此处不代表选择的列头checkbox,只是作为参数传递。应该列头checkbox是绘制出来的,无法获得它的实例
72
73 if (OnCheckBoxClicked != null)
74 {
75 OnCheckBoxClicked(sender, ex);//触发单击事件
76 this.DataGridView.InvalidateCell(this);
77 }
78
79 }
80 base.OnMouseClick(e);
81 }
82
83 }
还要定义和事件相关的委托:
//定义触发单击事件的委托
public delegate void datagridviewcheckboxHeaderEventHander(object sender, datagridviewCheckboxHeaderEventArgs e);
另外是界面操作代码:
Code
1 /// <summary>
2 /// 加载数据
3 /// </summary>
4 private void btnLoadData_Click(object sender, EventArgs e)
5 {
6 DataTable dtTemp = new DataTable();
7
8 using (SqlConnection con = new SqlConnection("server=.;uid=sa;pwd=sa;database=testdb;"))
9 {
10 SqlDataAdapter sa = new SqlDataAdapter("select * from userinfo", con);
11 sa.Fill(dtTemp);
12 }
13
14 this.dataGridView1.DataSource = dtTemp;
15 }
16
17
18 /// <summary>
19 /// 在checkbox列显示列头checkbox
20 /// </summary>
21 /// <param name="sender"></param>
22 /// <param name="e"></param>
23 private void button1_Click(object sender, EventArgs e)
24 {
25
26 datagridviewCheckboxHeaderCell ch = new datagridviewCheckboxHeaderCell();
27 ch.OnCheckBoxClicked += new datagridviewcheckboxHeaderEventHander(ch_OnCheckBoxClicked);//关联单击事件
28
29
30 //第三列为DataGridViewCheckBoxColumn
31 DataGridViewCheckBoxColumn checkboxCol = this.dataGridView1.Columns[2] as DataGridViewCheckBoxColumn;
32 checkboxCol.HeaderCell = ch;
33 checkboxCol.HeaderCell.Value = string.Empty;//消除列头checkbox旁出现的文字
34 }
35
36 /// <summary>
37 /// 单击事件
38 /// </summary>
39 private void ch_OnCheckBoxClicked(object sender, datagridviewCheckboxHeaderEventArgs e)
40 {
41 foreach (DataGridViewRow dgvRow in this.dataGridView1.Rows)
42 {
43 if (e.CheckedState)
44 {
45 dgvRow.Cells[2].Value = true;
46 }
47 else
48 {
49 dgvRow.Cells[2].Value = false;
50 }
51 }
52 }
此功能在客户端的实现代码(javascript实现)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script language="javascript" type="text/javascript">
// 判断多选是否与选中项(没有选中的返回false)
function slcNo_click()
{
if (document.form1.checkboxname.length)
{
for (var i=0;i<document.form1.checkboxname.length;i++)
{
if(document.form1.checkboxname[i].checked)
{
return true;
}
}
}
else
{
if(document.form1.checkboxname.checked)
{
return true;
}
}
alert("请选择后再操作!");
return false;
}
// 鼠标经过改变行的颜色
if (!objbeforeItem)
{
var objbeforeItem=null;
var objbeforeItembackgroundColor=null;
}
function ItemOver(obj)
{
if(objbeforeItem)
{
objbeforeItem.style.backgroundColor = objbeforeItembackgroundColor;
}
objbeforeItembackgroundColor = obj.style.backgroundColor;
objbeforeItem = obj;
obj.style.backgroundColor = "#B9D1F3";
}
//
// 多选的全选与取消
function checkJs(boolvalue)
{
if(document.all.checkboxname.length>1)
{
for(var i=0;i<document.all.checkboxname.length;i++)
{
document.all.checkboxname[i].checked = boolvalue;
}
}
else
document.all.checkboxname.checked = boolvalue;
}
//
// 只有全部选中时“全选”选中
function SingleCheckJs()
{
var flag1=false;
var flag2=false;
if (document.form1.checkboxname.length)
{
//
for (var i=0;i<document.form1.checkboxname.length;i++)
{
if(document.form1.checkboxname[i].checked)
flag1 = true;
else
flag2 = true;
}
}
else
{
if(document.form1.checkboxname.checked)
flag1 = true;
else
flag2 = true;
}
//
if(flag1==true&&flag2==false)
document.getElementById("chk").checked = true;
else
document.getElementById("chk").checked = false;
}
//
</script>
</head>
<body>
<SCRIPT LANGUAGE="JavaScript">
var s = "";
s += "/r/n网页可见区域宽:"+ document.body.clientWidth;
s += "/r/n网页可见区域高:"+ document.body.clientHeight;
s += "/r/n网页可见区域宽:"+ document.body.offsetWidth +" (包括边线和滚动条的宽)";
s += "/r/n网页可见区域高:"+ document.body.offsetHeight +" (包括边线的宽)";
s += "/r/n网页正文全文宽:"+ document.body.scrollWidth;
s += "/r/n网页正文全文高:"+ document.body.scrollHeight;
s += "/r/n网页被卷去的高:"+ document.body.scrollTop;
s += "/r/n网页被卷去的左:"+ document.body.scrollLeft;
s += "/r/n网页正文部分上:"+ window.screenTop;
s += "/r/n网页正文部分左:"+ window.screenLeft;
s += "/r/n屏幕分辨率的高:"+ window.screen.height;
s += "/r/n屏幕分辨率的宽:"+ window.screen.width;
s += "/r/n屏幕可用工作区高度:"+ window.screen.availHeight;
s += "/r/n屏幕可用工作区宽度:"+ window.screen.availWidth;
s += "/r/n你的屏幕设置是 "+ window.screen.colorDepth +" 位彩色";
s += "/r/n你的屏幕设置 "+ window.screen.deviceXDPI +" 像素/英寸";
alert(s);
</SCRIPT>
<form id="form1" runat="server">
<div>
<table cellpadding="0" cellspacing="0" border="0" width="80%" style="font-size: 11px">
<tr>
<td align="center">
<asp:GridView ID="GridView1" runat="server" Width="100%" CellPadding="4" ForeColor="#333333"
AutoGenerateColumns="False" AllowPaging="True" PageSize="12" BorderColor="Silver"
BorderStyle="Solid" BorderWidth="1px" OnRowDataBound="GridView1_RowDataBound"
ShowFooter="True" EmptyDataText="没有数据记录!!" AllowSorting="True" OnSorting="GridView1_Sorting">
<Columns>
<asp:BoundField HeaderText="编号" DataField="id" Visible="False" />
<asp:TemplateField HeaderText="<input type='checkbox' id='chk' name='chk' onclick='checkJs(this.checked);' />全选" FooterText="全选">
<ItemTemplate>
<input type="checkbox" id="checkboxname" name="checkboxname" value='<%# DataBinder.Eval(Container.DataItem, "id")%>' onclick='SingleCheckJs();' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="单选" FooterText="单选">
<ItemTemplate>
<img src='Images/updown.gif' id='imgNavigator' name='imgNavigator'/>
<input type="radio" id="RadioName" name="RadioName" value='<%# Eval("id")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText= '出货数量<img src="Images/updown.gif" runat="server" id="imgNavigator" />' >
<ItemTemplate>
<%# (Container.DataItemIndex+1).ToString()%>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="姓名" FooterText="姓名" DataField="name" SortExpression="name" />
<asp:BoundField HeaderText="身份证号" FooterText="身份证号" DataField="card" SortExpression="card" />
<asp:BoundField HeaderText="价格" FooterText="价格" DataField="price" DataFormatString="{0:¥#,##0.00}"
HtmlEncode="False" SortExpression="price" />
<asp:BoundField HeaderText="数字" FooterText="数字" DataField="price" DataFormatString="{0:0.00}"
HtmlEncode="False" SortExpression="price" />
<asp:BoundField HeaderText="建立时间" FooterText="建立时间" DataField="createdate" DataFormatString="{0:yyyy年MM月dd日 hh时mm分ss秒}"
HtmlEncode="False" SortExpression="createdate" />
</Columns>
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<EditRowStyle BackColor="#999999" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<PagerSettings Visible="False" />
<FooterStyle Font-Bold="True" />
<HeaderStyle Font-Bold="False" Font-Italic="False" />
</asp:GridView>
</td>
</tr>
<tr>
<td align="center" style="height: 25px">
<asp:LinkButton ID="btnFirst" CommandArgument="first" OnClick="PagerButtonClick"
runat="server">首 页</asp:LinkButton>
<asp:LinkButton ID="btnPrev" CommandArgument="prev" OnClick="PagerButtonClick" Text="上一页" runat="server">上一页</asp:LinkButton>
<asp:LinkButton ID="btnNext" CommandArgument="next" OnClick="PagerButtonClick" Text="下一页" runat="server">下一页</asp:LinkButton>
<asp:LinkButton ID="btnLast" CommandArgument="last" OnClick="PagerButtonClick" Text="尾页" runat="server">尾 页</asp:LinkButton>
<asp:Label ID="LblCurrentIndex" runat="server"></asp:Label>
<asp:Label ID="LblPageCount" runat="server"></asp:Label>
<asp:Label ID="LblRecordCount" runat="server"></asp:Label></td>
</tr>
<tr>
<td>
<asp:Button ID="Button2" runat="server" Text="checkbox得到选择的行" OnClick="Button2_Click">
</asp:Button>
<asp:Button ID="Button1" runat="server" Text="radio得到选择的行" OnClick="Button1_Click"></asp:Button>
<asp:Button ID="Button3" runat="server" OnClick="Button3_Click" Text="btnPrint" Width="130px" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>