更改了Checkbox值后,DataGridView直接更新数据源

时间:2011-01-03 15:49:53

标签: c# .net winforms datagridview datagridviewcheckboxcell

我有一个绑定到List<MyObject>的System.Windows.Forms DataGridView。
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键离开列。

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

如果我绑定一个Control属性,我可以将DataSourceUpdateMode设置为Windows.Forms.DataSourceUpdateMode.OnPropertyChanged,但我在DataGridView中找不到类似的东西

5 个答案:

答案 0 :(得分:2)

我假设您正在使用bindingsource然后在Check Box Click事件/ Edited do the,

    BindingSource.EndEdit()

答案 1 :(得分:2)

我有类似的问题。我没有使用BindingSource,只使用BindingList。经过许多挫折和实验(并遵循不同的解决方案),

我只是这样做了:

  • 覆盖DataGridView的{​​{1}}事件
  • 在活动中,请调用CellMouseUp的{​​{1}}方法。

答案 2 :(得分:1)

我做了这个伎俩:

  • 使用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;
        }
    

答案 3 :(得分: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
}

答案 4 :(得分: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