当 DataGridView 可编辑时,DataGridView / 数据集的线程安全更新
我有一个 WinForms 应用程序,其中包含数据集 ds 和 DataGridView dgv。 dgv 与 ds 绑定。
ds 通过 Task() 进行更新,Task() 使用 TableAdapter.Fill() 方法定期查询数据库。我在这里遇到两个问题。
更新 ds 时,除非调整窗口大小或某些其他事件导致表单重绘,否则 dgv 不会刷新。
更新当用户开始编辑 dgv 中的单元格时,ds 会更新并由于多个线程访问同一 GUI 控件而导致 UI 崩溃。我尝试使用标志 EditModeOn,该标志由 DataGridView dgv 中的某些事件设置,尽管这无助于防止线程错误。
拥有可由用户编辑并通过更改绑定数据集(在另一个线程中更新)进行更新的 DataGridView 的最佳方法是什么?
I have a WinForms application that contains a Dataset ds and a DataGridView dgv. dgv is bound to ds.
ds is updated via a Task() that periodically queries a database using the TableAdapter.Fill() method. There are two issues that I am experiencing here.
When ds is updated, dgv is not refreshed unless a the window is resized or some other event causes a redraw of the form.
When a user begins to edit a cell in dgv, ds is updated and causes a UI crash due to multiple threads accessing the same GUI control. I have attempted using a flag, EditModeOn, which is set by certain events from DataGridView dgv, though this has not helped in preventing the thread errors.
What is the best way to have a DataGridView that can be edited by a user and is updated via changes to the bound dataset (which is updated in another thread)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于第 2 点,您可以使用 Control 类中的函数
Invoke
。该函数将执行UI线程中的函数。http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
例如。 :
For your point #2, you can use the function
Invoke
from the Control class. This function will execute the function in the UI Thread.http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
Ex. :
对于第 1 点,您可以通过调用 Form.Invalidate() 来非常简单地解决此问题。这将导致您的窗体重新绘制自身;这有点脏,但应该可以解决问题。
关于第 2 点,如果您有一个任务正在从另一个线程更新控件的内容,那么您应该总是得到异常,因为从除该线程之外的任何线程访问控件都是非法的。 UI 线程(创建 UI 的线程)。所以我不太清楚你是如何做到这一点的。
但是,我要做的是使用线程检索结果,然后将这些结果存储在成员变量(字段)中。然后定期检查该字段以查看数据是否需要刷新,以及是否从该字段中获取数据并将其放入网格中,然后将该字段清空。您可以使用
System.Windows.Forms.Timer
类来实现此定期检查。在更新例程中,您可以检查标记以查看网格是否正在编辑,并忽略更新,直到稍后。
On point #1, you can fix this pretty simply by calling
Form.Invalidate()
. This will cause your form to repaint itself; that's a bit dirty but it should do the trick.On point #2, if you have a Task that is updating the contents of the control from another thread, then you should always get an exception since it is illegal to access a control from any thread other than the UI thread (the thread he UI is created on). So I'm not quite clear how you're doing this.
But, what I would do is use the thread to retrieve the results and then store those results in a member variable (field). Then periodically check that field to see if the data needs to be refreshed, and if take the data from the field and put it into your grid, and then null out the field. You can use the
Tick
event of aSystem.Windows.Forms.Timer
class to implement this periodic check.In your update routine, you can check your flag to see if the grid is being edited, and ignore the updates until later.