简体   繁体   中英

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.
However, I can only put 1 row in the datagridview, I want to input multiple rows just like a database.

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

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.


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 .

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.

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

It seems that DataGridView always needs to be reset if you use a it your way.

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

Using a BindingList<T> seems to be the appropriate way though. (Thanks to @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>而不是列表

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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