简体   繁体   English

将临时数据添加到列表并将其绑定到DataGridView Winform

[英]Adding Temporary Data to List and bind it to a DataGridView Winform

I want to put temporary datas into a generic list and bind it to the datagridview. 我想将临时数据放入通用列表并将其绑定到datagridview。
However, I can only put 1 row in the datagridview, I want to input multiple rows just like a database. 但是,我只能在datagridview中放置1行,我想像数据库一样输入多行。

Here's what I've tried, please tell me how to fix it. 这是我尝试过的方法,请告诉我如何解决。 thanks :)) 谢谢 :))

MyClass
{
   private List<object> _list = new List<object>();;

   public MyClass()
   {
   }

   protected void OnClickButton(object sender, args e)
   {
     _list.Add(new { Name = textBoxName.Text, Gender = genderComboBox.Text });
     dataGridView1.DataSource = _list;
   }
}

Thank you very much! 非常感谢你! I'm really STUCK-overflow with this problem. 我真的很困惑这个问题。

You could use BindingList<object> instead of List<object> , eg : 您可以使用BindingList<object>代替List<object> ,例如:

BindingList<object> bList = new BindingList<object>();

public MyClass()
{
}

private void button1_Click(object sender, EventArgs e)
{
    bList.Add(new { Name = "Foo", Gender = "Bar" });
    dataGridView1.DataSource = bList;
}

The problem with your code is that you're adding an element to _list and then you pass the list as datasource of the grid. 代码的问题是,您要向_list添加元素,然后将列表作为网格的数据源传递。 The first time everything works fine. 第一次,一切正常。 The next times it doesn't work because DataGridView.DataSource property internally performs a check that verify if the passed object is equal (or better reference-equal) to the current, and in case it does nothing. 下次它不起作用,因为DataGridView.DataSource属性在内部执行检查,以验证所传递的对象是否等于当前对象(或更佳的引用等于),并且在不执行任何操作的情况下。

BindingList<T> works, because it exposes events (used internally by the grid) reporting when the list is modified, so basically you could also avoid to pass it to the DataSource every time except the first one. BindingList<T>之所以起作用,是因为它在修改列表时公开了事件(由网格内部使用)报告,因此,基本上,您也可以避免每次都将其传递给DataSource第一个除外)。


As a side note, I suggest you to use a specific class (as shown in @Alex answer ) instead of put an anonymous-class in a list of object . 作为附带说明,我建议您使用特定的类(如@Alex answer所示),而不是将匿名类放入object列表中。

For example using a custom class like Person , you can pass an empty BindingList<Person> to grid.DataSource then add other Person objects without any problems. 例如,使用类似Person的自定义类,可以将一个空的BindingList<Person>传递给grid.DataSource然后添加其他Person对象而不会出现任何问题。

Instead, you can't pass an empty BindingList<object> to grid.DataSource because it results in a no-columns grid and so after you cannot add any elements having public properties (because the public properties are turned into columns). 相反,您不能将空的BindingList<object>传递给grid.DataSource因为它会导致形成无列的网格,因此在添加任何具有公共属性的元素之后(因为公共属性会变成列)。 Thus, you need to pass a BindingList<object> with at least one object defined, such that the grid can understand what the columns will be and create them. 因此,您需要传递一个至少定义了一个对象的BindingList<object> ,以便网格可以了解列的内容并创建它们。

It seems that DataGridView always needs to be reset if you use a it your way. 如果您以自己的方式使用DataGridView,似乎总是需要将其重置。

public class Person
{
    public String Name { get; set; }
    public String Gender { get; set; }
}

// Your control
private List<Person> _persons = new List<Person>();

// Click Event
dataGridView1.DataSource = null;
_persons.Add(new Person() { Name = "Test", Gender = "Male" });
dataGridView1.DataSource = _persons;

This refreshes the datagridview with the current data in your List 这将使用列表中的当前数据刷新datagridview

Using a BindingList<T> seems to be the appropriate way though. 但是,使用BindingList<T>似乎是适当的方法。 (Thanks to @digEmAll ) (感谢@digEmAll)

private BindingList<Person> _persons = new BindingList<Person>();

// Load Event
dataGridView1.DataSource = _persons;

private void button1_Click(object sender, EventArgs e)
{
    _persons.Add(new Person() { Name = "Test", Gender = "Male" });
}

使用ObservableCollection<T>而不是列表

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

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