5

我有一个绑定到List<MyObject>.
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 事件来完成的(为了简单起见,我将那部分留在源示例中)

如果我HasCustomValue从 DataGridView 外部更改,绑定到的列CurrentValue会立即更新。但是,如果用户启用/禁用该复选框,HasCustomValue则在基础数据源中不会更改,除非他通过单击鼠标或按 TAB 键离开该列。

有没有办法在更改复选框值后强制网格直接更新数据源?

如果我绑定一个控件属性,我可以将其设置为DataSourceUpdateModeWindows.Forms.DataSourceUpdateMode.OnPropertyChanged但我在 DataGridView 中没有找到类似的东西

4

5 回答 5

2

我有一个类似的问题。而且我没有使用 a BindingSource,只是 a BindingList。经过大量的挫折和实验(并遵循不太奏效的不同解决方案),

我只是这样做了:

  • 覆盖DataGridView'CellMouseUp事件
  • 在这种情况下,调用DataGridView'sEndEdit()方法。
于 2012-09-07T16:19:18.837 回答
2

我假设您正在使用 bindingsource,然后在 Check Box Click 事件/编辑上执行 ,

    BindingSource.EndEdit()
于 2011-01-03T18:24:06.667 回答
2

我做了这个把戏:

  • 将具有 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;
        }
    
于 2013-10-10T15:04:07.253 回答
1

使用处理程序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
}
于 2014-01-04T06:57:12.333 回答
1

我可以想象你不希望你的 bindingSource 知道它的绑定。毕竟,这不是您创建 bindingSource 的原因吗:能够让它绑定到几乎任何东西。

所以很自然,你不想知道你当前物品的价值是如何变化的;你只想知道已经被改变了。

为此,您使用事件 BindingSource.CurrentItemChanged:无论使用什么方法更改数据,您都会收到通知。

绑定到 BindingSource 的视图必须告诉 BindingSource 更改值已完成;编辑属性已结束。

在您的情况下,视图是 DataGridView。DataGridView 使用 DataGridView.EndEdit() 告诉 BindingSource 当前单元格已完成更改。

通常,当您键入单元格时,当单元格失去焦点或按下 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();
    }
}

这将导致事件 BindingSource.CurrentItemChanged

于 2015-10-22T12:07:48.950 回答