C# DataGridView在更改复选框值后直接更新数据源
我有一个System.Windows.Forms DataGridView,它绑定到一个C# DataGridView在更改复选框值后直接更新数据源,c#,.net,winforms,datagridview,datagridviewcheckboxcell,C#,.net,Winforms,Datagridview,Datagridviewcheckboxcell,我有一个System.Windows.Forms DataGridView,它绑定到一个列表 类MyObject包含绑定到DataGridView中DataGridViewCheckboxCell的布尔属性 public class MyObject { public decimal DefaultValue {get; set; } public bool HasCustomValue {get;set; } public decimal CustomValue {ge
列表
类MyObject包含绑定到DataGridView中DataGridViewCheckboxCell的布尔属性
public class MyObject
{
public decimal DefaultValue {get; set; }
public bool HasCustomValue {get;set; }
public decimal CustomValue {get;set; }
public decimal CurrentValue
{
get
{
return HasCustomValue
? CustomValue
: DefaultValue;
}
}
如果我更改HasCustomValue
的值,另一个(只读)属性CurrentValue
也会更改它的值。
这是通过实现INotifyPropertyChanged事件来实现的(为了简单起见,我在源代码示例中保留了该部分)
如果我从DataGridView外部更改了HasCustomValue
,绑定到CurrentValue
的列将立即更新。
但是,如果用户启用/禁用复选框,HasCustomValue
不会在基础数据源中更改,除非用户通过单击鼠标或按TAB键离开该列
有没有办法在更改复选框值后直接强制网格更新数据源
如果绑定控件属性,我可以将DataSourceUpdateMode
设置为Windows.Forms.DataSourceUpdateMode.OnPropertyChanged
,但我在DataGridView中没有找到类似的内容我假设您使用的是bindingsource,然后在复选框中单击事件/编辑执行以下操作
BindingSource.EndEdit()
我也有类似的问题。我使用的不是BindingSource
,而是bindingslist
。在经历了大量的挫折和试验后(以及遵循不同的解决方案,但效果并不理想)
我只是这样做:
- 覆盖
DataGridView
的CellMouseUp
事件
- 在这种情况下,调用
DataGridView
的EndEdit()
方法
我做了这个把戏:
- 将列的with CheckBox ReadOnly属性设置为true
- 然后在CellContentClick中,以编程方式将该值更改为相反的值
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int chkBoxColIdx = 0; //Index of the column with checkbox.
if (e.ColumnIndex == chkBoxColIdx)
{
dataGridView1.Rows[e.RowIndex].Cells[chkBoxColIdx].Value = !(bool)dataGridView1.Rows[e.RowIndex].Cells[chkBoxColIdx].Value;
}
使用datagridview的处理程序。CurrentCellDirtyStateChanged
private void datagridview_CurrentCellDirtyStateChanged(Object sender, EventArgs e)
{
//_checkboxColumnIndex - index of your checkboxcolumn
DataGridView dgv = (DataGridView)sender;
if (_checkboxColumnIndex == dgv.CurrentCell.ColumnIndex &&
dgv.Columns[_checkboxColumnIndex].GetType() == typeof(DataGridViewCheckBoxColumn) &&
dgv.IsCurrentCellDirty == true)
{
//Remember that here dgv.CurrentCell.Value is previous/old value yet
YourObject.HasCustomValue = !(bool)dgv.CurrentCell.Value
}
dgv.CommitEdit(DataGridViewDataErrorContexts.Commit) //this will fire .CellEndEdit event
}
我可以想象,您不想让bindingSource知道它绑定到什么。毕竟,这不是创建bindingSource的原因:能够让它绑定到几乎任何东西
因此,您自然不想知道当前项目的值是如何更改的;您只想知道它已被更改
为此,请使用event BindingSource.CurrentItemChanged:无论使用何种方法更改数据,都会收到通知
绑定到BindingSource的视图必须告诉BindingSource更改值已完成;编辑属性已结束
在您的例子中,视图是DataGridView。DataGridView告诉BindingSource当前单元格已使用DataGridView.EndEdit()完成更改
通常,在键入单元格时,当单元格失去焦点或按esc键时,编辑将结束。这使您有机会更正键入错误或取消编辑,以防不需要更改
但是,对于DataGridViewCheckBoxCell,大多数人希望在单击DataGridViewCheckBoxCell后立即完成编辑
因此,您需要处理事件DataGridView.CurrentCellDirtyStateChanged
// Whenever a DataGridViewCheckBoxCell becomes dirty editing is finished:
private void OnCurrentCellDirtyChanged(object sender, EventArgs e)
{
if (this.dataGridView1.CurrentCell is DataGridViewCheckBoxCell;
{
this.dataGridView1.EndEdit();
}
}
这将导致事件绑定源。CurrentItemChanged能否显示DataGridView标记?它是WinForms,因此我没有标记代码;)我真的想不出C#中有任何元素既没有代码也没有标记。它可能是一个可视化设计器,但仍然有代码。你确定没有标记代码吗?反正我不会命名设计器代码标记代码,我没有设置任何特殊属性,只是在DataGridView中添加了一个复选框列和一些文本框列。我想我会按照alliswell的建议处理Click事件。虽然EventArgs
对象没有e.ColumnIndex
,但这对我来说是可行的。您可以使用dgv.CurrentCell.ColumnIndex
而不是e.ColumnIndex
。将column属性设置为只读对我也有效,代码放入OnClick事件中。在DataGridView上使用InvalidateCell方法,然后设置单元格值,