我有一个带有复选框列的网格视图,我希望在切换单元格的值后立即触发绘图事件。我尝试了ValueChaged和CellEndEdit以及BeginEdit,并选择了选择模式作为CellSelect。至于前2个事件,事件是在编辑模式结束时触发的,例如移出当前单元格或来回移动。这只是一种奇怪的行为。
一旦单元格值发生变化,是否有任何东西在网格视图上触发事件?
最诚挚的问候,
答案 0 :(得分:33)
我使用CellContentClick事件,确保用户单击该复选框。即使用户停留在同一个小区,它也会多次触发。一个问题是Value没有得到更新,并且总是返回“false”表示未选中。诀窍是使用单元格的.EditedFormattedValue属性而不是Value属性。 EditedFormattedValue将使用复选标记进行跟踪,并且是当CellContentClick被触发时,Value希望其拥有的内容。
不需要计时器,不需要任何花哨的东西,只需使用CellContentClick事件并检查EditedFormattedValue以告知复选框进入/刚刚进入的状态。如果EditedFormattedValue = true,则会检查复选框。
答案 1 :(得分:23)
我的一位同事建议捕获CurrentCellDirtyStateChanged事件。见http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx。
答案 2 :(得分:20)
另一种方法是处理CellContentClick事件(它不会在单元格的Value属性中提供当前值),调用grid.CommitEdit(DataGridViewDataErrorContexts.Commit)来更新值,这反过来会触发CellValueChanged,你可以在哪里然后获取实际(即正确的)DataGridViewCheckBoxColumn值。
private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// do something with grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value
}
目标.NET框架:2.0
答案 3 :(得分:4)
尝试连接到CellContentClick事件。 DataGridViewCellEventArgs将具有ColumnIndex和RowIndex,因此您可以知道是否实际上点击了ChecboxCell。这个事件的好处是它只会在点击实际的复选框本身时触发。如果单击复选框周围单元格的白色区域,则不会触发。这样,您可以确保在此事件触发时更改了复选框值。然后,您可以调用Invalidate()来触发绘图事件,并调用EndEdit()以在需要时触发行的编辑结束。
答案 4 :(得分:4)
我终于以这种方式实现了
private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
{
if (dataGridView1[e.ColumnIndex, e.RowIndex].GetContentBounds(e.RowIndex).Contains(e.Location))
{
cellEndEditTimer.Start();
}
}
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{ /*place your code here*/}
private void cellEndEditTimer_Tick(object sender, EventArgs e)
{
dataGridView1.EndEdit();
cellEndEditTimer.Stop();
}
答案 5 :(得分:4)
我遇到了同样的问题,但想出了一个不同的解决方案:
如果您将列或整个网格设置为“只读”,那么当用户单击该复选框时,它不会更改值。
幸运的是,DataGridView.CellClick
事件仍然被触发。
在我的情况下,我在cellClick
事件中执行以下操作:
if (jM_jobTasksDataGridView.Columns[e.ColumnIndex].CellType.Name == "DataGridViewCheckBoxCell")
但如果您有多个复选框列,则可以检查列名称。
然后我自己完成了对数据集的所有修改/保存。
答案 6 :(得分:4)
小更新....确保您在尝试EditedFormattedValue
时使用value
代替value
,但它永远不会提供已选中/取消选中的正确状态,大部分网站仍在使用value
但正如下面最新的 c#2010 express 所使用的一种访问方式..
grdJobDetails.Rows[e.RowIndex].Cells[0].EditedFormattedValue
在某些情况下,少数建议或使用的_CellValueChanged
事件也必须可用,但如果您正在寻找每个检查/取消选中的单元格,请确保在我的通知中使用_CellContentClick
其他我看不到每个时间_CellValueChanged
被解雇..即如果点击相同的复选框&再次它不会触发_CellValueChanged
,但如果你交替点击,例如你有两个chekbox&在其他_CellValueChanged
事件被触发后点击一个,但通常如果在每次检查/取消选中任何单元格时都要查找事件,则不会触发_CellValueChanged
。
答案 7 :(得分:1)
“EditingControlShowing”事件不会在复选框值更改时触发。因为复选框单元格的显示样式不会改变。
我使用的解决方法如下。 (我使用过CellContentClick事件)
private void gGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (string.Compare(gGridView1.CurrentCell.OwningColumn.Name, "CheckBoxColumn") == 0)
{
bool checkBoxStatus = Convert.ToBoolean(gGridView1.CurrentCell.EditedFormattedValue);
//checkBoxStatus gives you whether checkbox cell value of selected row for the
//"CheckBoxColumn" column value is checked or not.
if(checkBoxStatus)
{
//write your code
}
else
{
//write your code
}
}
}
以上对我有用。如果需要更多帮助,请告诉我。
答案 8 :(得分:1)
我找到了一个简单的解决方案。
单击单元格后,只需更改单元格焦点。
private void DGV_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == "Here checkbox column id or name") {
DGV.Item(e.ColumnIndex, e.RowIndex + 1).Selected = true;
//Here your code
}
}
不要忘记检查(ckeckbox + 1)索引的列是否存在。
答案 9 :(得分:1)
CellClick
和CellMouseClick
答案中的每一个都是错误的,因为您可以使用键盘更改单元格的值,并且不会触发事件。此外,CurrentCellDirtyStateChanged
仅触发一次,这意味着如果您多次选中/取消选中同一个框,则只会获得一个事件。结合上面的一些答案给出了以下简单的解决方案:
private void dgvList_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvList.CurrentCell is DataGridViewCheckBoxCell)
dgvList.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void dgvList_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// Now this will fire immediately when a check box cell is changed,
// regardless of whether the user uses the mouse, keyboard, or touchscreen.
//
// Value property is up to date, you DO NOT need EditedFormattedValue here.
}
答案 10 :(得分:0)
<强> cellEndEditTimer.Start(); 强>
此行使datagridview更新复选框列表
谢谢。
答案 11 :(得分:0)
我发现前两个答案的组合给了我所需要的东西。我使用了CurrentCellDirtyStateChanged事件并检查了EditedFormattedValue。
private void dgv_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
DataGridView dgv = (DataGridView)sender;
DataGridViewCell cell = dgv.CurrentCell;
if (cell.RowIndex >= 0 && cell.ColumnIndex == 3) // My checkbox column
{
// If checkbox checked, copy value from col 1 to col 2
if (dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue != null && dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue.Equals(true))
{
dgv.Rows[cell.RowIndex].Cells[1].Value = dgv.Rows[cell.RowIndex].Cells[2].Value;
}
}
}
答案 12 :(得分:0)
如果要在DataGrid视图中使用checkedChanged
事件:
private void grdBill_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
grdBill.CurrentCell = grdBill.Rows[grdBill.CurrentRow.Index].Cells["gBillNumber"];
}
private void grdBill_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
calcBill();
}
private void calcBill()
{
listBox1.Items.Clear();
for (int i = 0; i < grdBill.Rows.Count - 1; i++)
{
if (Convert.ToBoolean(grdBill.Rows[i].Cells["gCheck"].Value) == true)
{
listBox1.Items.Add(grdBill.Rows[i].Cells["gBillNumber"].Value.ToString());
}
}
}
此处,网格中的grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox
(第二列)。
因此,当我们想要为每次点击触发checkchanged事件时,首先执行CellContentClick,当用户单击文本框时它会触发,然后它会将当前单元格移动到下一列,因此CellEndEdit列将会触发,它将检查复选框是否已选中,并在列表框中添加“gBillNumber”(在函数calcBill中)。
答案 13 :(得分:0)
使用未绑定的控件(即我以编程方式管理内容),没有EndEdit()它只调用一次CurrentCellDirtyStateChanged然后再调用一次;但是我发现在EndEdit()中,CurrentCellDirtyStateChanged被调用了两次(第二次可能是由EndEdit()引起的,但我没有检查过),所以我做了以下操作,这对我来说效果最好:
bool myGridView_DoCheck = false;
private void myGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (!myGridView_DoCheck)
{
myGridView_DoCheck = true;
myGridView.EndEdit();
// do something here
}
else
myGridView_DoCheck = false;
}
答案 14 :(得分:0)
使用 .EditedFormattedValue 属性可以解决问题
要在每次单击单元格中的复选框切换值时得到通知,您可以使用 CellContentClick 事件并访问单元格的初始值 .EditedFormattedValue 。
当事件触发时, .EditedFormattedValue 尚未以可视方式应用于复选框,并且尚未提交给.Value属性。
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var checkbox = dataGridView1.CurrentCell as DataGridViewCheckBoxCell;
bool isChecked = (bool)checkbox.EditedFormattedValue;
}
该事件在每次点击时触发,并且 .EditedFormattedValue 切换