I have a grid where I have a number of databound columns and then I add a single column which is not databound. I move that column to position 0:
grid.DisplayLayout.Bands[0].Columns["MyColumn"].Header.VisiblePosition = 0;
This works great.
I save the layout XML and in subsequent runs, I reload the layout. As the user can re-order columns, my intent is for whatever the last column layout was to be used.
The grid is bound to a BindingSource with a DataSource set to an array of objects which implement an interface.
In future executions, things go roughly as follows:- I bind the grid to the BindingSource.- I set the DataSource of the BindingSource to an empty array of the interface (_bindingSource.DataSource = new IMyInterface[0];)- I load the layout from the XML file.
At this point, the Header.VisiblePosition for my column is properly set to 0.
- The user performs an action that loads data.- The BindingSource.DataSource is set to the data which is an array of the objects implementing IMyInterface.
Immediately prior to setting the BindingSource.DataSource, the VisiblePosition. After that line executes, my column order gets changed and my unbound column is now the last column.
I have 3 other grids that operate under the same algorithm roughly and the other 3 operate properly. I can't figure out what I'm doing differently here.
I thought I could subscribe to AfterColPosChanged to see what's triggering the change, but it doesn't seem to ever get called except when e.PosChanged = PosChanged.Sized. Why is that?Is there some way to know what's triggering the change in VisiblePosition?
Hi,
I'm afraid you lost me.
pdavis68 said:Immediately prior to setting the BindingSource.DataSource, the VisiblePosition.
There seem to be some words missing from this sentence. :)
Sorry, prior to setting the BindingSource.DataSource, the VisiblePosition of the Header is 0. Immediately after I set the BindingSource.DataSource, the VisiblePosition is 15 (which makes it the last column).When you run the app the first time, everything works just fine. I can bind new data over and over and my columns stay put. It's not until I re-run the app and the layout is loaded from XML that it doesn't work. I doubt the loading of the layout is to blame. I imagine I'm doing something in my code that's causing it to reset the columns, but I simply can't figure out what it is and was hoping there was some event that would let me know when the header is getting moved so I can see what's triggering it. I mean, binding the data is the root of it. But that's causing something to happen that's then resetting my column order.
The grid will lose it's layout any time you set the DataSource or DataMember property of the grid or if the data source sends a Reset notification to the grid. Setting the DataSource on the BindingSource probably causes the BindingSource to send a Reset notification and the grid throws away the current layout in favor of the new layout for the new data source.
The best thing to do would be to avoid causing a Reset. But if you cannot do that, then another option would be to save the DisplayLayout before you set the DataSource, then Load it back in again afterward.
Mike,
Thanks for the info.
Can you elaborate on the reset mechanism? What is the specific event (and on which object, the CurrencyManager?) that the grid throws out the layout?
As I said, I have 3 other grids that don't have this problem and I suspect using the BindingSource is what's keeping that from happening. So I want to try to figure out what's making this particular grid different and see if I can fix it to be consistent with the other 3 rather than to take a different path with this grid.
I had actually considered temporarily saving the layout before binding and reloading after binding. While it's doable, it's a bit problematic because of our architecture and environment. But I can swing it if I need to.
I'd like to see if I can figure out what's causing the reset event, however and see if I can prevent that from happening.
Thanks
Put a breakpoint in the InitializeLayout event of the grid and look at the call stack. That might give you a good idea of the exact sequence of events. I say "might", because the grid might be handling this asynchronously, in which case the call stack will start with the OnPaint and that won't help.
Basically, I was referring to the ListChanged notification. The grid hooks this notification on the IBindingList interface of the data source.