Can I control when DataGridView reads and writes from/to its DataSource?

旧街凉风 提交于 2019-12-12 18:06:41

问题


I'm binding to a List<MyCustomType> and when I put a breakpoint on property getters in MyCustomType, they are seemingly being called repeatedly. What causes the DataGridView to automatically re-read the data and can I control this?

Secondly, I note that when I make changes to the data in the grid, these are not immediately replicated to the DataSource. Putting breakpoints on property setters in MyCustomType, they only seem to be called when I click outside the grid control. How can I make sure changes made in the GUI are immediately applied to the data source?


回答1:


Re-reading from your properties is completely normal, it's because of rendering. When DataGridView renders cells, it reads from properties.

Supporting INotifyPropertyChanged:

If you want to changes on properties be visible to DataGridView, you should implement INotifyPropertyChanged to have two-way data-binding. This causes the changes in your objects immediately be visible in grid:

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class Category : INotifyPropertyChanged
{
    #region Properties
    private int _Id;
    public int Id
    {
        get
        {
            return _Id;
        }
        set
        {
            if (_Id == value)
                return;
            _Id = value;
            OnPropertyChanged();
        }
    }

    private string _Name;
    public string Name
    {
        get
        {
            return _Name;
        }
        set
        {
            if (_Name == value)
                return;
            _Name = value;
            OnPropertyChanged();
        }
    }
    #endregion

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var eventHandler = this.PropertyChanged;
        if (eventHandler != null)
            eventHandler(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}
  • If you are using .Net 4.5, remove [CallerMemberName] and when calling OnPropertyChanged simply pass propert name, for example OnPropertyChanged("Name")

Using BindingList:

To make changes to a list visible to the grid, for example when you add a new item to your list of data, use BindingList<T> instead of List<T>.

If you use List<T>, you should set the DataSource to null and again to your list to make changes visible to the grid.

BindingList<Category> source = new BindingList<Category>();

private void Form_Load(object sender, EventArgs e)
{
    //Load Data to BindingList
    new List<Category>()
    {
        new Category(){Id=1, Name= "Category 1"},
        new Category(){Id=2, Name= "Category 2"},
    }.ForEach(x=>list.Add(x));

    this.categoryDataGridView.DataSource = list;
}

private void toolStripButton1_Click(object sender, EventArgs e)
{
    //Add data to BindingList 
    //Data will be visible to grid immediately
    list.Add(new Category(){Id=3, Name= "Category 3"});
}
  • Also you can consider binding the BindingList<T> to a BindingSource and the the grid to BindingSource. It makes more sense when using designer.

Using CurrentCellDirtyStateChanged:

Changes on DataGridView will automatically apply on your models OnValidating but as you also mentioned, you can use the CurrentCellDirtyStateChanged event of the grid to commit changes to the data source.

private void categoryDataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (categoryDataGridView.IsCurrentCellDirty)
    {
        categoryDataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}
  • I personally don't recommend such trick for all columns, for example suppose you have a string property that validates for minimum string length of 5, now how can you enter 5 character to it, then you will receive 5 validation error messages until you enter 5 characters.

Choose what you need carefully.



来源:https://stackoverflow.com/questions/32913050/can-i-control-when-datagridview-reads-and-writes-from-to-its-datasource

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!