Is this a bug?
Calling System.Windows.Forms.Form.ShowDialog() fires all way up through UltraGrid.OnPaint() then UltraGrid.EnsureTempActiveRowAssigned() which sets an active row in my grid (which happens to be somewhere in the middle, not even the first row).
I've caught the BeforeRowActivate event to see what's going on.
See the below call stack, thanks.
...WorkersGrid_BeforeRowActivate(object sender, Infragistics.Win.UltraWinGrid.RowEventArgs e) Line 498 C# Infragistics2.Win.UltraWinGrid.v10.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.OnBeforeRowActivate(Infragistics.Win.UltraWinGrid.RowEventArgs e) + 0x98 bytes Infragistics2.Win.UltraWinGrid.v10.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.FireEvent(Infragistics.Win.UltraWinGrid.GridEventIds id, System.EventArgs e) + 0xcbf bytes Infragistics2.Win.UltraWinGrid.v10.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.OnActiveRowChange(Infragistics.Win.UltraWinGrid.UltraGridRow newActiveRow, bool scrollIntoView) + 0x16c bytes Infragistics2.Win.UltraWinGrid.v10.3.dll!Infragistics.Win.UltraWinGrid.UltraGridBase.SetActiveRow(Infragistics.Win.UltraWinGrid.UltraGridRow row, bool scrollIntoView) + 0x329 bytes Infragistics2.Win.UltraWinGrid.v10.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.EnsureTempActiveRowAssigned() + 0x261 bytes Infragistics2.Win.UltraWinGrid.v10.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.OnPaint(System.Windows.Forms.PaintEventArgs pe) + 0x89 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.PaintWithErrorHandling(System.Windows.Forms.PaintEventArgs e, short layer) + 0x9f bytes System.Windows.Forms.dll!System.Windows.Forms.Control.WmPaint(ref System.Windows.Forms.Message m) + 0x757 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x449 bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x16c bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x11d bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x16c bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x11d bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x16c bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x11d bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x15e bytes [Native to Managed Transition] [Managed to Native Transition] System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) + 0x640 bytes System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) + 0x593 bytes System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x81 bytes System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x765 bytes
Having looked at the code for the UltraGrid and UltraGridBase classes, I saw the following in UltraGridBase:
internal Infragistics.Win.UltraWinGrid.UltraGridRow TempActiveRow { get { return this.tempActiveRow; } set { // SSP 11/17/04 UWG2234 // Changed the behavior so that when a column is sorted we maintain the scroll position // instead of keeping the first row the first row. Added SetTempActiveRow method and // moved the code from here into that method. We are passing in true for the // scrollIntoView parameter in order to maintain the previous behavior which was to // scroll the row into view. // this.SetTempActiveRow( value, true ); } }
I then checked the sort on the first column in my grid, and after a couple of tests, found this to be the reason why. The grid gets loaded up with rows, the sort if then performed on the first column (which happens to be name in this case), the first row in the grid now ends up in the middle of the grid which is still the active row.
So in short, it's due to the column sort and the above change.
If someone could verify my findings, then anyone else who comes across this problem won't have to do the digging that I had to.
Could someone sort the formatting on my previous post? It seems to have gone off screen.
Thanks.
I imagine this change relates to a user clicking a column header to sort ultra rows in the grid?
I would expect the default behaviour to activate/select the first row in the grid by default when loading the grid datasource for the first time, having applied a column sort in code. My column sort gets applied in InitializeLayout after the grid has it's datasource set.
Yep, as I suspected, that's the grid synchronizing the active row with the current Position of the BindingManager. It does this asynchronously for performance reasons.
Setting SyncWithCurrencyManager to false should prevent this from happening. And you can always set the ActiveRow after a delay by using a BeginInvoke.
I've run in to this problem again. Yes we are still on 8.3 and we will be upgrading soon, so this perhaps isn't of much relivance, but here is an example call stack showing the path it's taking, having simply called MessageBox.Show("some string"). This is firing a grid row activate:
MyGrid.MyGrid_AfterRowActivate(Object sender, System.EventArgs e) Line 2186 + 0x35 bytes Basic Infragistics2.Win.UltraWinGrid.v8.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.OnAfterRowActivate() + 0x56 bytes Infragistics2.Win.UltraWinGrid.v8.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.FireEvent(Infragistics.Win.UltraWinGrid.GridEventIds id, System.EventArgs e) + 0x187 bytes Infragistics2.Win.UltraWinGrid.v8.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.OnActiveRowChange(Infragistics.Win.UltraWinGrid.UltraGridRow newActiveRow, bool scrollIntoView) + 0x435 bytes Infragistics2.Win.UltraWinGrid.v8.3.dll!Infragistics.Win.UltraWinGrid.UltraGridBase.SetActiveRow(Infragistics.Win.UltraWinGrid.UltraGridRow row, bool scrollIntoView) + 0x1c0 bytes Infragistics2.Win.UltraWinGrid.v8.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.EnsureTempActiveRowAssigned() + 0x100 bytes Infragistics2.Win.UltraWinGrid.v8.3.dll!Infragistics.Win.UltraWinGrid.UltraGrid.OnPaint(System.Windows.Forms.PaintEventArgs pe) + 0x49 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.PaintWithErrorHandling(System.Windows.Forms.PaintEventArgs e, short layer, bool disposeEventArgs) + 0x9a bytes System.Windows.Forms.dll!System.Windows.Forms.Control.WmPaint(ref System.Windows.Forms.Message m) + 0x1d4 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x33e bytes System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x10 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x5a bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x130 bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x5 bytes Infragistics2.Win.v8.3.dll!Infragistics.Win.EditorWithMask.AccessibleTextManager.AccessibleTextSubclasser.WndProc(ref System.Windows.Forms.Message msg) + 0x48 bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x5a bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x130 bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x5 bytes Infragistics2.Win.v8.3.dll!Infragistics.Win.FormattedLinkLabel.FormattedLinkEditor.AccessibleTextManager.AccessibleTextSubclasser.WndProc(ref System.Windows.Forms.Message msg) + 0x41 bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x5a bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x130 bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x5 bytes Infragistics2.Win.v8.3.dll!Infragistics.Win.FormattedLinkLabel.IMENativeWindowManager.IMENativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x18 bytes System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes [Native to Managed Transition] [Managed to Native Transition] System.Windows.Forms.dll!System.Windows.Forms.MessageBox.ShowCore(System.Windows.Forms.IWin32Window owner, string text, string caption, System.Windows.Forms.MessageBoxButtons buttons, System.Windows.Forms.MessageBoxIcon icon, System.Windows.Forms.MessageBoxDefaultButton defaultButton, System.Windows.Forms.MessageBoxOptions options, bool showHelp) + 0x220 bytes > System.Windows.Forms.dll!System.Windows.Forms.MessageBox.Show(string text) + 0x26 bytes
Hi,
The grid does not automatically activate any row. But it does try to keep the ActiveRow in synch with the CurrencyManager/BindingManager.
So what is probably happened here is that you are setting the DataSource on your grid and the grid creates it's rows and activate the same row that is active in the CurrencyManager. This is typically the first row.
Then your grid is getting sorted - probably because you are sorting it in code or loading a layout into the grid which you previously saved. The grid then gets sorted and the active row is now in the middle somewhere.
If you don't want the grid to synchronize the ActiveRow, you could set grid.SyncWithCurrencyManager to false.
Or, you could just find out where your code is setting up the sorting and then activate the first row in the grid immediately after that.