【问题标题】:Binding List<T> to DataGridView in WinForm在 WinForm 中将 List<T> 绑定到 DataGridView
【发布时间】:2013-05-17 17:57:01
【问题描述】:

我有课

class Person{
      public string Name {get; set;}
      public string Surname {get; set;}
}

还有一个List&lt;Person&gt;,我在其中添加了一些项目。该列表绑定到我的DataGridView

List<Person> persons = new List<Person>();
persons.Add(new Person(){Name="Joe", Surname="Black"});
persons.Add(new Person(){Name="Misha", Surname="Kozlov"});
myGrid.DataSource = persons;

没有问题。 myGrid 显示两行,但是当我将新项目添加到我的 persons 列表时,myGrid 不会显示新的更新列表。它只显示了我之前添加的两行。

那么问题出在哪里?

每次重新绑定都很好。但是,当我将DataTable 绑定到网格时,每次我对DataTable 进行一些更改时,都不需要重新绑定myGrid

如何在不重新绑定的情况下解决?

【问题讨论】:

  • {get; 的访问者必须添加 set;} 才能显示 datagridview。

标签: c# list datagridview binding grid


【解决方案1】:

这不完全是我遇到的问题,但如果有人希望将任何类型的 BindingList 转换为相同类型的 List,那么它就是这样做的:

var list = bindingList.ToDynamicList();

此外,如果您将动态类型的 BindingLists 分配给 DataGridView.DataSource,请确保首先将其声明为 IBindingList,以便上述工作。

【讨论】:

    【解决方案2】:

    列表没有实现IBindingList,所以网格不知道你的新项目。

    改为将您的 DataGridView 绑定到 BindingList&lt;T&gt;

    var list = new BindingList<Person>(persons);
    myGrid.DataSource = list;
    

    但我什至会更进一步,将您的网格绑定到 BindingSource

    var list = new List<Person>()
    {
        new Person { Name = "Joe", },
        new Person { Name = "Misha", },
    };
    var bindingList = new BindingList<Person>(list);
    var source = new BindingSource(bindingList, null);
    grid.DataSource = source;
    

    【讨论】:

    • 它说你也可以使用IList和其他接口:msdn.microsoft.com/en-us/library/…
    • @Pacane:当然可以,但是 DataGridView 需要知道您的数据源是否有任何更改。 One 方法是使用 BindingList,如果底层列表发生变化,它将引发一个事件。另一种方法是使用 BindingSource 并在每次添加/删除 Row 时调用 ResetBinding() ,但这就是更多工作。如果您想通知 Grid 属性更改,最简单的方法是实现 INotifyPropertyChanged
    • 你为什么使用 BindingList 和 BindingSource 因为我们可以直接将列表绑定到 datagridview 数据源属性。讨论这里使用的 BindingList 和 BindingSource 的重要性。谢谢
    • @Mou 如果需要,您可以将 DataGrid 绑定到 List&lt;T&gt;。但是,如果您以编程方式将项目添加到列表中,DataGridView 将不会知道它,因为您的列表没有实现IBindingList。关于 BindingSource:我经常使用 winform,除了 BindingSource - FULLSTOP 之外,我不绑定任何其他东西。添加更多细节对于评论来说太过分了,但是BindingSource 可以提供这么多没有任何缺点的东西。我会说Anyone who does not use a BindingSource for binding has not fully understood windows forms databindings
    • @CraigBrett 将BindingSource 视为数据源和 GUI 之间的桥梁。它解决了许多与数据绑定相关的问题。你想重新加载你的数据吗?只需将bindingSource.DataSource 设置为您的新集合,而不是重新绑定每个控件。您的 DataSource 可以为空吗?设置bindingSource.DataSource = typeof(YourClass) 您想要一个可编辑的网格,但您的数据源没有无参数构造函数?只需实现bindingSource.AddingNew 事件并自己创建对象。我在使用 BindingSource 时从未遇到过缺点,但有很多好处。
    【解决方案3】:

    是的,可以通过实现 INotifyPropertyChanged 接口来避免重新绑定。

    这里有非常简单的例子,

    http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

    【讨论】:

    • 这还不够,如果您实现INotifyPropertyChanged,DataGridView 将显示后台发生的所有属性更改,但它不会知道您是否从源中添加/删除行。为此,有一个IBindingList 接口,并且为了您的方便,一个实现BindingList&lt;T&gt; 已经实现了它,但不支持排序/过滤。
    • 是的,我同意你的看法。所以我认为 ObservableCollection 可以用于此。你怎么看?
    【解决方案4】:

    persons添加新项目后添加:

    myGrid.DataSource = null;
    myGrid.DataSource = persons;
    

    【讨论】:

    • datagrid下看不到dataSource属性,能告诉我怎么用吗?
    • 此建议可能会导致问题。例如,您会发现单击网格中的项目可能会得到 IndexOutOfRangeException,因为此时数据源为空。最初绑定到 BindingList 并在您的对象上实现 INotifyPropertyChanged 会更明智,因为其他答案表明
    • 如果您立即将其分配给下一行的persons,那么将其分配给null有什么意义?
    【解决方案5】:

    每次向 List 添加新元素时,都需要重新绑定 Grid。 比如:

    List<Person> persons = new List<Person>();
    persons.Add(new Person() { Name = "Joe", Surname = "Black" });
    persons.Add(new Person() { Name = "Misha", Surname = "Kozlov" });
    dataGridView1.DataSource = persons;
    
    // added a new item
    persons.Add(new Person() { Name = "John", Surname = "Doe" });
    // bind to the updated source
    dataGridView1.DataSource = persons;
    

    【讨论】:

    • datagrid下看不到dataSource属性,能告诉我怎么用吗?
    猜你喜欢
    • 2016-11-04
    • 2010-09-12
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多