Click here to Skip to main content
15,886,873 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
Hi,

Currently i'm working on an application working with multiple threads to retrieve and parse data, but I'm running into a problem updating datagridview.

Simple application setup (i'm will use some logic class names to better visualize the structure)
  Object Garage
    Collection<car> Cars
    UserControl GarageView
      DataGridView CarTable
</car>


Now i have about 5 threads changing and adding Cars from the collection. In the DataGridView "CarTable" statusses are shown and updated. Currently this works by binding the collection "Cars" as Datasource to "CarTable"

public partial class GarageView : UserControl
{
    public GarageView(Garage garage)
    {
        InitializeComponent();
        this.CarTable.DataSource = garage.Cars;
    }
}


A car is extended from the INotifyPropertyChanged class so, it can be used as datasource:

public class Car: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}


This works, only half, only changes to rows are shown, new cars do not get added. I've found a workaround on the net, but it's ugly, and performs bad.

delegate void UpdateUIDelegate(Collection<car> Cars);
public void UpdateUI(Collection<car> Cars)
{
  if (this.InvokeRequired)
  {
     UpdateUIDelegate d = new UpdateUIDelegate(UpdateUI);
     this.Invoke(d, new object[] { Cars });
  } else {
     this.CarTable.DataSource = null;
     this.CarTable.DataSource = Cars;
     this.CarTable.Refresh();
     this.CarTable.Update();
  }
}
</car></car>


Currently there are about 200 records every ten seconds added/changed over a total of 800 rows.

I think I'm going in the proper direction, just can't complete the last bit :/

Any suggestions?

-- Daan
Posted

The Car class implements the INotifyPropertyChanged interface but the actual data source is the Cars object.

If I were you, I would create a custom Cars class (not just a collection) and implement INotifyPropertyChanged interface in the Cars class. And whenever a Car was added/changed/removed, I would call the NotifyPropertyChanged method. Even after doing that, you still have to bind a method in your UI code to the Cars.PropertyChanged event and update your GridView there.
 
Share this answer
 
To fully support data binding the collection should implement IBindingList (i.e. BindingList<T>) or INotifyCollectionChanged (e.g. ObservableCollection<T>). You can use a BindingSource but you still have to make sure that it is notified of changes if the underlying collection doesn't do that (and List<T> doesn't).

If this is just at startup a progress indicator and a one time hit of all 800 rows might be a better approach, trying to use a data grid which is constantly refreshing is a strange user experience, even if you get all the binding right so scroll position is preserved.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900