本文介绍了DataGridView的非阻塞更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解如何使用委托来更新主控制线程上的控件,就像一个魅力一样。我的问题是如果我在一个绑定的 DataGridView 中添加一个大的 DataSet (说2000项)网格填充5-8秒,在5-8秒内,整个GUI被锁定。如何更新 DataGridView ,使其不会锁定用户界面?



要清楚,问题不在于我对数据库进行缓慢的查询,而是阻止用户界面,所以我已经拥有了 DataSet对象[] 并添加对象数组到 BindingList< object> 其中 DataGrid 被绑定到:

  BindingList< object> dataProvider = new BindingList< object>(); 
DataGridView gridView = new DataGridView();
gridView.DataSource = dataProvider;

// ...东西发生...

object [] source = dataSet; // of 2000 items
foreach(object item in source){// this foreach blocks
dataProvider.Add(item);
}

我尝试过各种各样的东西(我知道不行, d)创建一个委托,它执行 dataProvider.Add(),但这并不重要,因为它仍然必须发生在控制线程上。



一些好的建议围绕着建立 BindingList ,然后设置 gridView.DataSource 。虽然这有效(它立即更新网格),但我看到添加更多数据的唯一方法是创建另一个新的 BindingList ,执行 gridView。 DataSource.copyTo()(以获取现有数据)并添加新数据,然后将 gridView.DataSource 设置为新的 BindingList 。这对我来说不起作用,因为我的列表中的对象不是静态的,它们都是异步地将数据上传到服务器,并将它们复制到新的 BindingList 会导致问题

解决方案

您正在添加记录,而GridView链接到DataSource。这意味着它会每次更新布局。



您如何首先填写DataSource,然后只设置DataSource属性?

  gridView.DataSource = null; 
...东西发生...

object [] source = dataSet; // of 2000 items
foreach(object item in source){// this foreach blocks
dataProvider.Add(item);
}

gridView.DataSource = dataProvider;

foreach循环可以转到另一个线程,但我不认为你会需要。 p>

I understand how to use delegates to update controls on the main control thread, works like a charm. My problem here is if I'm adding a large DataSet (say 2000 items) to a bound DataGridView, it takes 5-8 seconds for the grid to populate and during that 5-8 seconds the whole GUI is locked. How can I update the DataGridView such that it doesn't lock the user interface?

To be clear, the problem isn't that I'm doing a slow query to a database and the UI is blocking on that, I already have the DataSet object[] and adding the array of objects to a BindingList<object> which the DataGrid is bound to so:

BindingList<object> dataProvider = new BindingList<object>();
DataGridView gridView = new DataGridView();
gridView.DataSource = dataProvider;

// ...stuff happens...

object[] source = dataSet; //of 2000 items
foreach (object item in source) {  //this foreach blocks
    dataProvider.Add(item);
}

I tried various things (that I knew wouldn't work but figured I'd see) like creating a delegate that did the dataProvider.Add(), but that didn't matter since it still had to happen on the control thread.

A couple good suggestions revolved around building the BindingList first and then setting the gridView.DataSource. While this works (it updates the grid instantly), the only way I see to add more data is to create another new BindingList, do a gridView.DataSource.copyTo() (to get the existing data) and add the new data on top of that, then set the gridView.DataSource to the new BindingList. This won't work for me since the objects in my list are not static, they are each uploading data to a server asynchronously, and copying them to a new BindingList would cause problems.

解决方案

You are adding records while the GridView is linked to the DataSource. This means it will update the layout each time.

How about you first fill your DataSource and only then set the DataSource property?

gridView.DataSource = null;
...stuff happens...

object[] source = dataSet; //of 2000 items
foreach (object item in source) {  //this foreach blocks
    dataProvider.Add(item);
}

gridView.DataSource = dataProvider;

The foreach loop could go to another thread but I don't think you will need that.

这篇关于DataGridView的非阻塞更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 10:11