[C#]多线程Datagridview控件绑定到集合 [英] [C#] Multithreaded Datagridview control binding to collection

查看:366
本文介绍了[C#]多线程Datagridview控件绑定到集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



目前,我正在使用具有多个线程的应用程序来检索和解析数据,但是在更新datagridview时遇到了问题.

简单的应用程序设置(我将使用一些逻辑类名称来更好地可视化结构)

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>



现在我有大约5个线程在集合中更改和添加Cars.在DataGridView中,将显示和更新"CarTable"状态.当前,这是通过将集合"Cars"作为数据源绑定到"CarTable"来实现的.



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;
    }
}



汽车是从INotifyPropertyChanged类扩展的,因此可以用作数据源:



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>



目前,每十秒钟大约有200条记录被添加/更改,总共有800行.

我想我朝着正确的方向前进,只是无法完成最后一点:/

有什么建议吗?

-Daan



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

推荐答案

Car类实现INotifyPropertyChanged接口,但实际的数据源是Cars对象.

如果您是我,我将创建一个自定义的Cars类(不仅仅是一个集合),并在Cars类中实现INotifyPropertyChanged接口.每当添加/更改/删除汽车时,我都会调用NotifyPropertyChanged方法.即使这样做,您仍然必须将UI代码中的方法绑定到Cars.PropertyChanged事件并在那里更新GridView.
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.


要完全支持数据绑定,集合应实现IBindingList(即BindingList< T>或INotifyCollectionChanged(例如ObservableCollection< T>).您可以使用BindingSource,但是如果基础集合不这样做(而List< T>不这样做),您仍然必须确保将更改通知给它.

如果这只是在启动时使用进度指示器,并且一次击中所有800行可能是更好的方法,即使使用了正确的绑定,尝试使用不断刷新的数据网格也是一种奇怪的用户体验.位置被保留.
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.


这篇关于[C#]多线程Datagridview控件绑定到集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆