We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

BeginUpdate()/EndUpdate() problem

Me again, sorry :) I call BeginUpdate() prior to performing a lengthy operation on my GridControl. During GridControl processing I display a Status Form that contains a progress bar (not running a special thread though). Within my loop I call Increment() on the Status Form's progress bar and right after that I call up Application.DoEvents() to have the Windows messages being dispatched to controls. However, the call to Application.DoEvents() never returns. I assume that the Framework locks up in the Grid's OnPaint() implementation as it reads somewhere within OnPaint() if(updating) throw new InvalidProgramException("Grid is in updating mode"); I don't think this makes too much sense as the OnPaint() method could easily return; out of the method. I guess this is where my lock up comes from. If not there must be something hidden down the GridControl implementation as my same code works when I BeginUpdate() on, e.g. a ListView, and don't touch BeginUpdate() of the GridControl. Regards Kai Iske DWS Investments

2 Replies

AD Administrator Syncfusion Team November 27, 2002 03:02 PM UTC

Kai, I don't think the problem has anything to do with that exception. Instead, what I think is happening is that when you call DoEvents with some grid's WM_PAINT messages pending, the DoEvents comes across a WM_PAINT for the grid. So, it tells the grid to process the WM_PAINT, but the grid just ignores the WM_PAINT because of the BeginUpdate call. So, DoEvents again tells the grid to handle the SAME ignored WM_PAINT, and an endless loop is born. I discussed this problem with Stefan, and he will look into it when he has time. But during the BeginUpdate/EndUpdate, the idea was to let these WM_PAINT messages remain in the message queue so they would eventually be handled when EndUpdate was done. Of course, this will not work if from a DoEvents handler. But changing it, may impact other things. I think there is a straight-forward workaround. The idea is to note when you are in a DoEvents loop, and if so, then don't ignore the grid's WM_PAINT. To do this, add a public static member to some class that you can use to mark when you are in a DoEvents loop.
public static bool InDoEvents = false;
private void button1_Click(object sender, System.EventArgs e)
{
	this.gridControl1.BeginUpdate();

	this.gridControl1.Refresh();

	Console.WriteLine("before Application.DoEvents");
	Form1.InDoEvents = true;
	Application.DoEvents();
	Form1.InDoEvents = false;
	Console.WriteLine("after Application.DoEvents");

	this.gridControl1.EndUpdate();
}
Then override the grid's WndProc and process the WM_PAINT if you are in the DoEvents loop.
public class MyGridControl : GridControl
{
	public const int WM_PAINT = 15;
	protected override void WndProc(ref System.Windows.Forms.Message msg)
	{
		if(Form1.InDoEvents && msg.Msg == WM_PAINT)
			DefWndProc(ref msg);
		else
			base.WndProc(ref msg);
	}
}
One other comment is that if you want to have a progress bar on a different thread, then there is such a bar in the Shared library. If you look at the GridPopulationSample that ships with the grid, it uses it to put up a prgress bar if something is taking a long time (lik eusing the Indexer method to populate a 1000x1000 grid).


KI Kai Iske November 28, 2002 03:08 AM UTC

Hi Clay, of course you're right. After some more investigation I came to the conclusion that Windows Messages simply won't be consumed by the Grid when in Updating mode. I have overridden WndProc: ... if(m.Msg == WM_PAINT && base.Updating == true) { DefWndProc(ref m) } ... Works fine, thanks for the hint. Anyway, wouldn't be better to have the grid simple dequeue messages and not act on them and instead in EndUpdate(), when the updating counter drops to zero call up an Invalidate() on the Grid? Well, just my 2 cents Kai

Loader.
Up arrow icon