繁体   English   中英

更改复选框值后,DataGridView立即更新数据源

[英]DataGridView update datasource directly after changed Checkbox value

我有一个绑定到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的值, HasCustomValue另一个(只读)属性CurrentValue也会更改其值。 这是通过实现INotifyPropertyChanged事件来完成的(为简单起见,我在源代码示例中保留了该部分)

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

有没有一种方法可以在更改复选框值后直接强制网格更新数据源?

如果绑定控件属性,则可以将DataSourceUpdateMode设置为Windows.Forms.DataSourceUpdateMode.OnPropertyChanged但在DataGridView中找不到类似的内容

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

我只是这样做:

  • 重写DataGridViewCellMouseUp事件
  • 在这种情况下,调用DataGridViewEndEdit()方法。

我假设您使用的是bindingsource,然后在Check Box Click event / Edited上执行,

    BindingSource.EndEdit()

我做了这个技巧:

  • 将具有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:使其能够绑定到几乎任何东西的原因。

因此,您自然不希望知道当前项目的价值如何变化; 你只需要知道它已经被改变。

为此,您使用事件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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM