简体   繁体   中英

Exception when Asynchoon loading of datagridview bindinglist

When I try to load a datagridview asyncroon I recieve an InvalidOperationException with the message: "Operation is not valid due to the current state of the object." This happens when I add an item to the BindingList and invocation is requierd. Without threading no exception is thrown. Any help is much appreciated.

These are the methods I use to add items to the DataGridview:

public static class ExtensionMethods
{
    public static void LoadAsync<T>(this DataGridView gv, IEnumerable<T> enumerable)
    {
        gv.DataSource = new BindingList<T>();
        new Thread(() => gv.LoadItems(enumerable)) { IsBackground = true, Name = "AsyncLoad" }.Start();
    }

    private static void LoadItems<T>(this DataGridView gv, IEnumerable<T> enumerable)
    {
        foreach (T item in enumerable)          
            gv.AddItemToDataSourche(item);          
    }

    private static void AddItemToDataSourche<T>(this DataGridView gv, T item)
    {
        if (gv.InvokeRequired)
            gv.Invoke(new Action(() => gv.AddItemToDataSourche(item)));
        else
            ((BindingList<T>)gv.DataSource).Add(item); //This is where it goes wrong.
    }
}

This is how I instantiate the DataGridView:

public partial class Form1 : Form
{
    private DataGridView _gv = new DataGridView();
    private readonly IEnumerable<Person> _persons = new List<Person>
        {
            new Person {ID = 1, FirstName = "Test 1", LastName = "Someone"},
            new Person {ID = 2, FirstName = "Test 2", LastName = "Someone"},
            new Person {ID = 3, FirstName = "Test 3", LastName = "Someone"}
        };

    public Form1()
    {
        InitializeComponent();
        Controls.Add(_gv);
        _gv.LoadAsync(_persons);            
    }
}

public class Person
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

I don't think the DataGridView control is in a ready state yet for that operation, so it won't work in the constructor, and the Load method seems too early, too, so try the OnShown override method instead:

protected override void OnShown(EventArgs e) {
  base.OnShown(e);
  _gv.LoadAsync(_persons);
}

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