DataGridView的bug?!
昨天在查一个DataGridView当前焦点CheckBox不勾选问题,发现在修改DataGridView数据源的值很容易忽略的问题,或者叫DataGridView的bug
绑定数据
假定我们绑一个DataTable
/// <summary> /// 当前数据。Form私有成员 /// </summary> DataTable curTable; /// <summary> /// 启动 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void TabForm_Load(object sender, EventArgs e) { curTable = buildDataTable(); this.dataGridViewY1.AutoGenerateColumns = false; this.dataGridViewY1.DataSource = this.curTable.DefaultView; } /// <summary> /// 生成数据源 /// </summary> /// <returns></returns> private DataTable buildDataTable() { DataTable table = new DataTable(); table.Columns.Add("Id", typeof(int)); table.Columns.Add("IsSelected", typeof(bool)); table.Columns.Add("Title", typeof(string)); for (int i = 0; i < 5; i++) { DataRow row = table.NewRow(); row["Id"] = i; row["IsSelected"] = true; row["Title"] = "标题 " + i; table.Rows.Add(row); } return table; }
好,我设置DataGrid的第一列为DataGridViewCheckBoxColumn,其DataPropertyName="IsSelected"。现在我们决定双击头时对这一行全选、全否
bool isSelected = false; private void dataGridViewY1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { isSelected = !isSelected; dataGridViewY1.BeginEdit(true); for (int j = 0; j < dataGridViewY1.Rows.Count; j++) { dataGridViewY1.Rows[j].Cells[0].Value = isSelected; } dataGridViewY1.EndEdit(); }
发现Bug
好了,运行双击感觉没什么问题。但请注意,以下步骤你将发现问题:
1.先全选中
2.点击一行的CheckBox,让其不勾选,再点击一次让其勾选
3.点击行头,程序应尝试设置全否。但你会发现刚才点击那行还处于勾选状态。
解决方法
全选/全否很容易,直接修改数据源就行
private void setAllSeleted(bool isTrue) { foreach (DataRow row in this.curTable.Rows) row["IsSelected"] = isTrue; }
但有时难受需要对当前界面定位的行来进行设置
for (int j = 0; j < dataGridViewY1.Rows.Count; j++) { DataRowView row = this.dataGridViewY1.Rows[j].DataBoundItem as DataRowView; if (row == null) continue; row.BeginEdit();//必须先开始 row["IsSelected"] = isTrue; row.EndEdit(); }
好了,两种方式,按需选择。