DataGridView обновляет источник данных непосредственно после изменения значения флажка - PullRequest
4 голосов
/ 03 января 2011

У меня есть System.Windows.Forms DataGridView, который связан с List<MyObject>.
. Класс MyObject содержит логическое свойство, которое связано с DataGridViewCheckboxCell в DataGridView.

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.

Есть ли способ принудительно вызватьсетка для обновления источника данных непосредственно после изменения значения флажка?

Если я связываю свойство элемента управления, у меня есть возможность установить DataSourceUpdateMode на Windows.Forms.DataSourceUpdateMode.OnPropertyChanged, но я не нашел ничего подобного в DataGridView

Ответы [ 5 ]

2 голосов
/ 07 сентября 2012

У меня была похожая проблема.И я не использовал BindingSource, просто BindingList.После большого количества разочарований и экспериментов (и после различных решений, которые не вполне работали),

я просто сделал это:

  • переопределил событие DataGridView * CellMouseUp
  • в этом случае вызовите метод DataGridView EndEdit().
2 голосов
/ 03 января 2011

Я предполагаю, что вы используете bindingsource, затем на флажке Нажмите событие / Отредактировано,

    BindingSource.EndEdit()
1 голос
/ 22 октября 2015

Я могу представить, что вы не хотите, чтобы ваш bindingSource знал, с чем он связан. В конце концов, это не то, почему вы создали bindingSource: чтобы позволить ему быть связанным практически с чем угодно.

Естественно, вы не хотите знать, как изменяется значение вашего текущего предмета; вы только хотите знать , что он был изменен.

Для этого вы используете событие 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();
    }
}

Это приведет к событию BindingSource.CurrentItemChanged

1 голос
/ 04 января 2014

Использовать обработчик для 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
}
1 голос
/ 10 октября 2013

Я сделал этот трюк:

  • Установите для столбца с свойством 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;
        }
    
...