Threadsafe Updating of DataGridView / Dataset When DataGridView is Editable
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 no开发者_如何学运维t 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)?
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. :
// Invoke an anonymous method on the thread of the form.
this.Invoke((MethodInvoker) delegate
{
//Call your function to update your datagridview with the dataset in parameters
...
});
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 a System.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.
精彩评论