我可以控制的DataGridView读取和/它的数据源写? [英] Can I control when DataGridView reads and writes from/to its DataSource?

查看:146
本文介绍了我可以控制的DataGridView读取和/它的数据源写?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我绑定到名单,其中,MyCustomType> ,当我穿上属性获取一个断点 MyCustomType ,他们似乎正在重复调用。是什么原因导致了的DataGridView 自动重新读取数据,我可以控制吗?

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?

其次,我注意到,当我更改在网格中的数据,这些都不是立即复制到数据源。穿上属性setter断点 MyCustomType ,他们似乎只是被称为当我点击网格控制之外。我怎样才能使在GUI确信更改是立即应用到数据源?

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?

推荐答案

重新读取你的属性是完全正常的,这是因为渲染。当的DataGridView 渲染单元,其读取性能。

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

支持<一href="https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx"相对=nofollow> INotifyPropertyChanged的:

Supporting INotifyPropertyChanged:

如果您希望在性能的变化是可见的的DataGridView ,你应该实施<一个href="https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx"相对=nofollow> 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
}

  • 如果您使用的是.NET 4.5,删除 [CallerMemberName] 和打电话时 OnPropertyChanged 简单地传递PROPERT名,例如: OnPropertyChanged(名称)
    • If you are using .Net 4.5, remove [CallerMemberName] and when calling OnPropertyChanged simply pass propert name, for example OnPropertyChanged("Name")
    • 使用的BindingList

      Using BindingList:

      要更改可见的网格列表,例如,当你一个新的项目添加到您的数据列表,使用的 的BindingList&LT; T&GT; 代替名单,其中,T&GT;

      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>.

      如果您使用名单,其中,T&GT; ,你应该设置数据源为空,并再次到您的列表进行更改可见的网格

      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"});
      }
      

      • 你也可以考虑结合的BindingList&LT; T&GT; 到的BindingSource和网格的BindingSource 。它更有意义了使用设计器。
        • Also you can consider binding the BindingList<T> to a BindingSource and the the grid to BindingSource. It makes more sense when using designer.
        • 使用<一个href="https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged(v=vs.110).aspx"相对=nofollow> CurrentCellDirtyStateChanged :

          Using CurrentCellDirtyStateChanged:

          的DataGridView 将自动适用于你的模型OnValidating但你也提到,您可以使用<一个变化href="https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged(v=vs.110).aspx"相对=nofollow> 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);
              }
          }
          

          • 在我个人不推荐这种伎俩对所有列,例如,假设你有一个字符串属性,验证为5最小字符串长度,现在你怎么可以输入5个字符到它,那么你将获得5验证错误信息直到输入5个字符。
          • 选择你仔细需要的。

            这篇关于我可以控制的DataGridView读取和/它的数据源写?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆