C# 在 DataGridView 中触发复选框值更改事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/932040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Triggering a checkbox value changed event in DataGridView
提问by mustafabar
I have a grid view that has a check box column, and I want to trigger a drawing event as soon as the value of the cell is toggled. I tried the ValueChaged and the CellEndEdit and BeginEdit, and chose the selection mode as CellSelect. As for the the first 2 events, the event was triggered upon the finishing of the edit mode, like moving out of the current cell, or going back and forth. It's just a weird behavior.
我有一个带有复选框列的网格视图,我想在单元格的值被切换后立即触发绘图事件。我尝试了 ValueChaged 和 CellEndEdit 和 BeginEdit,并选择了 CellSelect 作为选择模式。对于前2个事件,该事件是在编辑模式完成时触发的,例如移出当前单元格,或来回移动。这只是一种奇怪的行为。
Is there anything that triggers the event on the grid view as soon as the cell value is changed?
一旦单元格值发生变化,是否有任何东西会触发网格视图上的事件?
采纳答案by user120381
A colleague of mine recommends trapping the CurrentCellDirtyStateChanged event. See http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx.
我的一位同事建议捕获 CurrentCellDirtyStateChanged 事件。请参阅http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx。
回答by BFree
Try hooking into the CellContentClick event. The DataGridViewCellEventArgs will have a ColumnIndex and a RowIndex so you can know if a ChecboxCell was in fact clicked. The good thing about this event is that it will only fire if the actual checkbox itself was clicked. If you click on the white area of the cell around the checkbox, it won't fire. This way, you're pretty much guaranteed that the checkbox value was changed when this event fires. You can then call Invalidate() to trigger your drawing event, as well as a call to EndEdit() to trigger the end of the row's editing if you need that.
尝试挂接到 CellContentClick 事件。DataGridViewCellEventArgs 将有一个 ColumnIndex 和一个 RowIndex,因此您可以知道是否真的单击了 CheckboxCell。这个事件的好处是它只有在实际的复选框被点击时才会触发。如果您单击复选框周围单元格的白色区域,它将不会触发。这样,您几乎可以保证在此事件触发时复选框值已更改。然后,您可以调用 Invalidate() 来触发绘图事件,如果需要,还可以调用 EndEdit() 来触发行编辑的结束。
回答by mustafabar
I finally implemented it this way
我终于以这种方式实现了
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();
}
回答by James
I had the same issue, but came up with a different solution:
我有同样的问题,但想出了不同的解决方案:
If you make the column or the whole grid "Read Only" so that when the user clicks the checkbox it doesn't change value.
如果您将列或整个网格设为“只读”,则当用户单击复选框时,它不会更改值。
Fortunately, the DataGridView.CellClick
event is still fired.
In my case I do the following in the cellClick
event:
幸运的是,DataGridView.CellClick
事件仍然被触发。就我而言,我在cellClick
事件中执行以下操作:
if (jM_jobTasksDataGridView.Columns[e.ColumnIndex].CellType.Name == "DataGridViewCheckBoxCell")
But you could check the column name if you have more than one checkbox column.
但是,如果您有多个复选框列,则可以检查列名。
I then do all the modification / saving of the dataset myself.
然后我自己完成数据集的所有修改/保存。
回答by Leandro
cellEndEditTimer.Start();
cellEndEditTimer.Start();
this line makes the datagridview update the list of checked boxes
此行使 datagridview 更新复选框列表
Thank you.
谢谢你。
回答by Christo
I use the CellContentClick event, which makes sure the user clicked the checkbox. It DOES fire multiple times even if the user stays in the same cell. The one issue is that the Value does not get updated, and always returns "false" for unchecked. The trick is to use the .EditedFormattedValue property of the cell instead of the Value property. The EditedFormattedValue will track with the check mark and is what one wishes the Value had in it when the CellContentClick is fired.
我使用 CellContentClick 事件,它确保用户单击复选框。即使用户停留在同一个单元格中,它也会多次触发。一个问题是 Value 不会更新,并且总是返回“false”以表示未选中。诀窍是使用单元格的 .EditedFormattedValue 属性而不是 Value 属性。EditedFormattedValue 将使用复选标记进行跟踪,并且当 CellContentClick 被触发时,它是人们希望其中包含的值。
No need for a timer, no need for any fancy stuff, just use CellContentClick event and inspect the EditedFormattedValue to tell what state the checkbox is going into / just went into. If EditedFormattedValue = true, the checkbox is getting checked.
不需要计时器,不需要任何花哨的东西,只需使用 CellContentClick 事件并检查 EditedFormattedValue 来判断复选框正在进入/刚刚进入的状态。如果 EditedFormattedValue = true,则复选框被选中。
回答by Stuart
Another way is to handle the CellContentClick event (which doesn't give you the current value in the cell's Value property), call grid.CommitEdit(DataGridViewDataErrorContexts.Commit) to update the value which in turn will fire CellValueChanged where you can then get the actual (i.e. correct) DataGridViewCheckBoxColumn value.
另一种方法是处理 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
}
Target .NET framework: 2.0
目标 .NET 框架:2.0
回答by Mike Pollitt
I found a combination of the first two answers gave me what I needed. I used the CurrentCellDirtyStateChanged event and inspected the EditedFormattedValue.
我发现前两个答案的组合给了我我需要的东西。我使用了 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;
}
}
}
回答by Jegan
Use this code, when you want to use the checkedChanged
event in DataGrid View:
当您想checkedChanged
在 DataGrid 视图中使用该事件时,请使用以下代码:
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());
}
}
}
Here, grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox
in Grid (Second column).
在这里,grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox
在网格(第二列)中。
So, when we want to fire checkchanged event for each click, first do the CellContentClick it will get fire when user clicked the Text box, then it will move the current cell to next column, so the CellEndEdit column will get fire, it will check the whether the checkbox is checked and add the "gBillNumber" in list box (in function calcBill).
因此,当我们想为每次点击触发 checkchanged 事件时,首先执行 CellContentClick 当用户单击文本框时它会触发,然后它将当前单元格移动到下一列,因此 CellEndEdit 列会触发,它会检查是否选中复选框并在列表框中添加“gBillNumber”(在函数 calcBill 中)。
回答by user593029
Small update.... Make sure you use EditedFormattedValue
instead of value
as I tried value
but it never give right status that is checked/unchecked most of the site still use value
but as used in latest c# 2010 expressbelow is one way to access..
小更新.... 确保您使用EditedFormattedValue
而不是value
像我尝试的那样,value
但它永远不会给出正确的状态,即已选中/未选中的大多数站点仍在使用,value
但在下面的最新c# 2010 express中使用的是一种访问方式..
grdJobDetails.Rows[e.RowIndex].Cells[0].EditedFormattedValue
Also _CellValueChanged
event suggested or used by few must be usable for some cases but if you are looking for every check/uncheck of cell make sure you use _CellContentClick
else per my notice I see not every time _CellValueChanged
is fired.. that is if the same checkbox is clicked over & over again it does not fire _CellValueChanged
but if you click alternately for example you have two chekbox & click one after other _CellValueChanged
event will be fired but usually if looking for event to fire everytime the any cell is check/uncheck _CellValueChanged
is not fired.
此外_CellValueChanged
,少数人建议或使用的事件必须在某些情况下可用,但如果您正在查找单元格的每次选中/取消选中,请确保_CellContentClick
根据我的通知使用else 我看到不是每次都_CellValueChanged
被触发..也就是说,如果单击相同的复选框一遍又一遍,它不会触发,_CellValueChanged
但如果您交替单击,例如,您有两个 chekbox 并单击一个,然后其他_CellValueChanged
事件将被触发,但通常如果每次选中/取消选中任何单元格时都查找要触发的事件,_CellValueChanged
则不会触发。