3
votes

I have a C# WinForms app that contains a BindingList which is populated with widget objects like this:

BindingList<Widget> widgetsList = new BindingList<Widget>();

A widget has three properties (one int, one string and one bool) and implements INotifyPropertyChanged. The widgets get added to the BindingList like this:

for (int i = 0; i < 100000; i++) // takes < 1/10 of a second to execute
{
   widgetsList.Add(new Widget(intValue, stringValue, boolValue));
}

And finally, I set the BindingList as the data source for a DataGridView (actually three DataGridView controls):

dataGridView1.DataSource = widgetsList;

This code is working well. However, if my user makes changes in the DataGridView and then wants to discard those changes and re-load the original data, I'm having issues. Right now I have a button to do this and the code in the button's Click event handler looks like this:

dataGridView1.Rows.Clear() // very fast

widgetsList.Clear() // also very fast

    for (int i = 0; i < 100000; i++) // takes 18.6 seconds to execute
    {
       widgetsList.Add(new Widget(intValue, stringValue, boolValue));
    }

As you can see, this loop executes substantially slower (18.6s vs < .1s) than the same loop above. It does appear to work but I'm trying to figure where the bottleneck is and how to remove it. Am I missing something?

1
Instead of simply clearing the widgetsList, what if you actually create a new instance? I've seen other objects that retain internal buffers even after clear, perhaps this would clear it. Another thought is to remove the datasource on your grids, or at least pause binding. It could be attempting to render after each add, where the first loop wouldn't since it occurs before being set as data source. - Matt Klinker
You're right! It was the binding. I had to add a binding source in between the BindingList and the DataGridView in order to get it working but that allowed me to suspend the binding while I was re-loading the original data and it solved my problem. If you'd like to post this as an answer, I'd be happy to accept it. Thank you! - bmt22033

1 Answers

4
votes

Posting answer from comment above: You need to add a BindingSource between the grid and the binding list. This will allow you to suspendbinding while reloading the source list and allow the grid to hold off rendering until the datasource is fully updated.