Hi,
I encountered a bug that in the event of AfterColPosChanged, the VisiblePosition returned from e.ColumnHeaders(0).VisiblePosition is wrong.
Example:
In the grid i have column1, column2 and column3 (Left to Right).
I removed Column2.
Drag Column1 into Column3 position.
Now in the AfterColPosChanged event, e.ColumnHeaders(0).VisiblePosition is 2, which is WRONG. It should be 1, because there is only 2 visible columns (zero based index)
Please help.
I'm not sure exactly what you mean by "I removed Column2." Is this an unbound column that you removed? Or did you mean that you are hiding the column?
I hidden column does not change it's VisiblePosition, so the numbers you are getting here are correct. The column is not visible when Hidden, but it maintains the same VisiblePosition. It has to do this, because otherwise when you hide a column and then show it again, it would not come back to the same position.
Hi Mike,
"Removed" means hide it (uncheck the box in columnchooser). So how can i work around this to get the correct visibleposition? Basically the column2 that is hidden now, column 1 and column 3 is visible on the grid. When I drag the column 1 to column 3 position, how can I tell what the new visible position is for the column1 on the grid ? I need to know the actual position that is shown on the grid, not including the hidden columns.
The VisiblePositions values you are getting here are correct. VisiblePosition is actually very flexible. You could, if you wanted to, set VisiblePosition to completely disparate values like 10, 20, 30, etc.
I'm not sure what you need the VisiblePosiiton values for, so it's hard to answer your question. But if you need to know what columns are actually visible an in what order, then I recommend that you use the grid.ActiveColScrollRegion.VisibleHeaders collection.
What I was trying to do is I have to keep an index list of all visible columns in current order shown on the grid and write it to a database. The order has to be sequentially from 0 to N. I cannot use the visiblePosition because that's including the hidden column. the ActiveColScrollRegion contains only VisibleHeaders but not sorted and the value from VisiblePosition also a skipping index.
Is there an easy way to do this? In short, from my example earlier. Now the grid became Column3, Column1 (left to right). I need to find out Column3 (index 0), column1 (index 1). Column2 is hidden, I don't need that for now. If later I decided to bring column2 become visible again ===> COLUMN3, COLUMN2,COLUMN1 (index 0, 1, 2 respectively). The visiblePosition might probably messed up for now. I hope this will make more sense to you.
caspers said:What I was trying to do is I have to keep an index list of all visible columns in current order shown on the grid and write it to a database. The order has to be sequentially from 0 to N. I cannot use the visiblePosition because that's including the hidden column.
I don't see the problem.
If you want to save the column order, then why does it matter if you save the hidden columns VisiblePosition? I would think that you would want to do this. Otherwise, when you load the application and the user shows one of the columns that was hidden when they saved it, it will show up in the wrong place. So it makes sense to save the VisiblePosition of all of the columns.
Even if that's not what you want, why is it a problem to save the VisiblePositions of the columns with gaps?
caspers said:the ActiveColScrollRegion contains only VisibleHeaders but not sorted
I don't know what you mean by this. The VisibleHeaders collection is in the order of he visible columns.So you could simply walk over the collection and use the index as the position.
By the way... are you aware of the Save and Load methods on the grid.DisplayLayout? This will save the column order along with column size, sorting, filtering, etc. It saves and loads everything the user can change in the grid. So you don't have to write this code yourself.
Refresh works for me but not invalidate. I think that should do the trick, let me sort around things in my program and see if I can make it work. Thanks for your help.
It looks like this is just a timing issue. The VisibleHeaders has not been updated when AfterColPosChanged fires. If you put a button on the form and call RefreshGrid in your sample and then move the column and then click the button, the VisibleHeaders is correct.
So I think the problem here is that the VisibleHeaders collection is updated asynchronously - probably the next time the grid paints.So the solution is simple - you need to force the grid to paint before you check the VisibleHeaders.You can do this by adding a call to Grid.Refresh before you access the VisibleHeaders collection. I tried this out and it works fine. In fact, it works for me when I call grid.Invalidate, so that's probably the better option.
Private Sub RefreshGrid() C1.Text = "" C2.Text = "" C3.Text = "" ' Invalidate the grid so that the VisibleHeaders are up-to-date. UltraGrid1.Invalidate() For i As Integer = 0 To UltraGrid1.ActiveColScrollRegion.VisibleHeaders.Count - 1 Select Case i Case 0 C1.Text = UltraGrid1.ActiveColScrollRegion.VisibleHeaders(i).Header.VisiblePosition.ToString Case 1 C2.Text = UltraGrid1.ActiveColScrollRegion.VisibleHeaders(i).Header.VisiblePosition.ToString Case 2 C3.Text = UltraGrid1.ActiveColScrollRegion.VisibleHeaders(i).Header.VisiblePosition.ToString End Select Next End Sub
Attached sample project. Try drag and drop Column1 to Column3 position. Looping thru collection of ActiveColScrollRegion.VisibleHeaders will give you VisiblePosition 2-0-1 instead of 0-1-2 with the actual column item being swapped around in the collection.
I guess the grid column still stay at the same place as in the collection item, only the VisiblePosition has changed. So, how can I can sort them out easily without having me copy over them to an array and sort it myself. Thanks
I will try to compose a sample project in a bit.
I must keep the visibleposition in sequence without gap because i have to maintain the columns list (top to bottom = left to right on the grid) in few other listview controls (similar to fieldchooser). User has the ability to make changes on the listview with drag and drop function to reorder/add/delete columns without accessing the grid. Changes make on the listview and grid will reflect each other. If grid sequence has gap, i can't reorder the listview correctly without the exact position shown on the listview (top to bottom = left to right on the grid). I considered to delete all the items on the listview and reconstruct them based on the fresh list of grid columns, but that I required the collection of grid columns to be in order ===> sample project
caspers said:I cannot save the invisible columns. Reason: I have to toss them away and not save into database so that later time when user load the grid and the columns that were invisible should not be exists at all.
Okay... but why does it matter that there are gaps in the VisiblePosition values? As I mentioned before, the VisiblePositons do not have to be in sequence.
You could save this:
Column A = 0
Column B = 10
Column C = 15
And restore the same values and it will work fine. The only tricky part of this is that you must set the VisiblePositions in order from lowest to highest - but you would have to do that regardless of whether the numbers are consecutive or not.
caspers said:VisiblePosition NOT in order meaning when I walked thru the collection, it shows VisiblePosition as (2, 0, 1) from item 1 to item N (left to right columns on the grid). Which is not what I want, I need it to be 0, 1, 2.... etc. Also, again the visiblePosition still included the hiddencolumns but if the collection items are in order, i can easily fix it myself, problem is it's not in order.
I've never seen this happen - unless maybe you are using RowLayouts - in which case, the VisiblePosition property is not used.
If you can duplicate this in a small sample project and post it here, I'd love to take a look at it.