[C#]多线程Datagridview控件绑定到集合 [英] [C#] Multithreaded Datagridview control binding to collection
问题描述
目前,我正在使用具有多个线程的应用程序来检索和解析数据,但是在更新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.
TheCar
class implements theINotifyPropertyChanged
interface but the actual data source is theCars
object.
If I were you, I would create a custom Cars class (not just a collection) and implementINotifyPropertyChanged
interface in the Cars class. And whenever a Car was added/changed/removed, I would call theNotifyPropertyChanged
method. Even after doing that, you still have to bind a method in your UI code to theCars.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屋!