Hello,
I've spoken with Infragistics Support about this issue (support request CAS-08857-GUP6P0 if Infragistics engineers (for instance Mike :) ) would like to take a look at it). Unfortunately, the answer was pretty much depressing. Our current implementation looks like this:
We have a form with a grid on it. There is a System.Data.DataSet bound to the grid. To be more specific, let’s assume that the user enters some article ids (one in each row). After the user is done with ids, he presses a button which starts some long running calculation (computation of optimal prices). Currently we do the following:
1. We call BeginUpdate() and SuspendRowSynchronization() on the grid. 2. We start the thread which changes the dataset 3. At the very end this method (which changes the dataset) calls UpdateGrid()
4. private void UpdateGrid()
{
if(InvokeRequired)
Invoke(new MethodInvoker(UpdateGrid));
}
else
ultraGrid1.ResumeRowSynchronization();
ultraGrid1.EndUpdate();
So, we do everything in our power to prevent access to UI controls (grid) from a non UI thread.
According to Infragistics Support the described implementation still doesn’t guarantee that the grid won’t “try to query the datasource for changes. If a property is set on the grid, or an action is taken, such as moving the mouse, then the grid will try to talk to its data source to retrieve the values and this is where the problems occur”.
So, my question is whether there is some solution for this more than usual problem (without unbinding the grid completely from the datasource like grid.DataSource=null). Would setting AllowUpdate=false help? Would grid.Enabled = false help?
I’m more than aware that I need to “synchronize worker threads with the UI”. My task is to keep the UltraGridRows and Layout (therefore I don’t want to unbind the DataGrid from the DataSet) AND perform some long running operation which changes the dataset on a separate thread. I would very appreciate an algorithm in pseudo code.
When dataset is in update, can you send the grid to back, showing busy indicator in front? You can bring grid back to front after update is done
We currently do
UltraGrid.SuspendRowSynchronization();
UltraGrid.DisplayLayout.Override.AllowUpdate = DefaultableBoolean.False;
view.Enabled = false;
AND (drums!) hide the grid replacing it with a screenshot. This works pretty stable, no issues in last 1,5 years, but of course behaves awfully when the user resizes the form (fortunatelly, very rarely in our application). At least the user can use other functionality
Control control = view.UltraGrid; // Hack: Replace grid by screenshot and make grid invisible to prevent drawing events. Bitmap bitmap = new Bitmap(control.Width, control.Height); control.DrawToBitmap(bitmap, Rectangle.FromLTRB(0, 0, bitmap.Width, bitmap.Height)); view.DisabledGridPictureBox.Image = bitmap; view.DisabledGridPictureBox.Dock = DockStyle.Fill; view.DisabledGridPictureBox.SizeMode = PictureBoxSizeMode.Normal; view.UltraGrid.Visible = false; view.DisabledGridPictureBox.BringToFront();
Did anyone find any solution to this problem, I am using version 10 of infragistics libraries.
thanks
Thank you, Mike, for detailed explanation. I will think about possible alternatives.
Even if the grid had a property as you suggest, and even it was completely thread-safe, the DotNet BindingManager/CurrencyManager is not. So it would continue to update it's own state and could easily get out of snych.