UltraGrid shows big red "X" on subsequent attempts to re-bind flat data programmatically. This is using Infragistics2.Win.UltraWinGrid.v7.3. Sometimes it occurs after the second button click. Sometimes it takes maybe 10 clicks. The faster you click, the fewer clicks it takes. I created a simple app and reproduced the problem there. I've researched this a lot (it seems I'm not the only one who has seen the "big red cross") but have run out of ideas. It could be something simple. The exceptions below appear randomly apparently. I've tried setting the UltraGrid.DataSource to null before rebinding, DataTable.Clear(), Reset(), and resetting the width / height of the Ultragrid several places at runtime. I've tried enabling all exceptions and debugging it as well. The errors appear there as well, but only at the Application.Run line in Program.cs. Any ideas?
The code that rebinds the data (it calls the controller to get the XML data):
private void ReBindData() { DataTable dt = new DataTable("SomeDataTable"); XmlNodeList xmlnodes = controller.getNodes(); dt.Columns.Add("Col1"); IEnumerator enumerator = xmlnodes.GetEnumerator(); while (enumerator.MoveNext()) { XmlNode node = (XmlNode)enumerator.Current; DataRow dr; dr = dt.NewRow(); dr[0] = node.FirstChild.Value; dt.Rows.Add(dr); } ultraGrid1.DataSource = dt; ultraGrid1.DataBind(); }
Exceptions:
System.NullReferenceException: Object reference not set to an instance of an object. at Infragistics.Win.UIElement.DrawChildElements(UIElementDrawParams& drawParams) at Infragistics.Win.UIElement.DrawElement(UIElementDrawParams& defaultDrawParams) at Infragistics.Win.UIElement.DrawChildElements(UIElementDrawParams& drawParams) at Infragistics.Win.UIElement.DrawElement(UIElementDrawParams& defaultDrawParams) at Infragistics.Win.UIElement.DrawChildElements(UIElementDrawParams& drawParams) at Infragistics.Win.UIElement.DrawElement(UIElementDrawParams& defaultDrawParams) at Infragistics.Win.UIElement.DrawHelper(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean clipText, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics) at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Size elementSize, Boolean preventAlphaBlendGraphics) at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode) at Infragistics.Win.UltraWinGrid.UltraGridUIElement.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode) at Infragistics.Win.UltraControlBase.OnPaint(PaintEventArgs pe) at Infragistics.Win.UltraWinGrid.UltraGrid.OnPaint(PaintEventArgs pe) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.Parameter name: index at System.Collections.ArrayList.get_Item(Int32 index) at Infragistics.Shared.DisposableObjectCollectionBase.GetItem(Int32 index) at Infragistics.Win.UltraWinGrid.VisibleRowsCollection.get_Item(Int32 index) at Infragistics.Win.UltraWinGrid.RowColRegionIntersectionUIElement.PositionChildElements() at Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UltraWinGrid.RowColRegionIntersectionUIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UltraWinGrid.DataAreaUIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UltraWinGrid.UltraGridUIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UIElement.DrawHelper(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean clipText, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics) at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Size elementSize, Boolean preventAlphaBlendGraphics) at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode) at Infragistics.Win.UltraWinGrid.UltraGridUIElement.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode) at Infragistics.Win.UltraControlBase.OnPaint(PaintEventArgs pe) at Infragistics.Win.UltraWinGrid.UltraGrid.OnPaint(PaintEventArgs pe) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
This has all the ingredients of an illegal cross-thread operation. UltraGrid is not thread-safe (in fact almost all Windows Forms controls are not), so if your ReBindData method is being executed on a different thread, this is the sort of thing you can expect, since you aren't supposed to set the DataSource on a different thread.
The control's BeginInvoke method (inhreited from the System.Windows.Forms.Control class) provides a way to call a synchronous method asynchronously. This is commonly used to marshall method calls across thread boundaries.
I've run into a similar problem and was hoping to get some more information on this reply.
I'm building a "configurable grid" where the DataSource changes at runtime when the user chooses to load a different grid configuration.
Similar to the example that started this thread, the user would do so by clicking a button in a dialog. So here's my question:
If the action of changing the DataSource is triggered by an action on the UI thread (like user clicking a button), it seems like the code that changes the DataSource would already be on the UI thread without needing to use BeginInvoke. Is that a true statement?
If so, I'm experiencing a problem where a red X is appearing when the changing of the DataSource is definitely taking place on the UI thread, because its done in an event handler for a click event. The stack I've seen is different, as it originates from the painting of the column filters.
Any advice?
tshawver said:If the action of changing the DataSource is triggered by an action on the UI thread (like user clicking a button), it seems like the code that changes the DataSource would already be on the UI thread without needing to use BeginInvoke. Is that a true statement?
Yes, typically a button click (even on another dialog) is on the same UIThread with the grid. Unless, of course, the dialog was launched by a different thread.
The data source you are assigning to the grid could still come from another thread, or it could be accessed or modified by some other thread, and any of these would cause a problem.
But if you are certain that there are no other threads being spawned by your application and you are still getting a Red X in the grid, then there could be a bug there. Are you able to duplicate this problem reliably? If so, and you can send us a small sample project demonstrating the issue, we will be happy to take a look.
Was there any progress on this issue? I'm experiencing the same thing...I do utilize a background worker to initialize my form however the initialization of the grid is actually not done within a background worker (although other grids are being init'd in them). In any case, I'm certain the UI thread is the only one setting the data source on this grid, so was wondering what you have found here.
Using 8.2 version of Infragistics controls.
If I remember correctly, in my case it turned out that I had some cross thread problems. I went through all my code and made sure every modification to the UltraDataSource was definitely taking place on the UI thread. Once I fixed those, the problem was fixed. I'm using version 9.1 of the controls.
Not sure exactly what you mean when you say you're using a background worker to initialize your form...but you definitely want to make sure that you only create/modify that form and UltraGrid control on the UI thread or you could run into red X issues.
You know what? It was a cross-thread in my case as well. I thought I removed all the datasource modification code from the worker thread, but I found a case where it was buried.
Now, I do the work in my background thread to prep the new datatable, but then use BeginInvoke((MethodINvoker) {}); to set the datasource after the work is done.