Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
30
Maintaining first visible column when UltraGrid is refreshed
posted

Hi,

I have a checkbox column on my grid. When user checks / unchecks the box an operation is performed which leads to data refresh on the grid. From the users perspective this also resets the active scroll region and the grid moves to show the first column instead of the column that was visible when the checkbox changed. I would like to maintain the active scroll region on checkbox change and the following code achieves this.

foreach(var visibleHeader in m_compositeControl.ActiveColScrollRegion.VisibleHeaders)
{
            if (m_compositeControl.ActiveRowScrollRegion.FirstRow.Cells[visibleHeader.Header.Column.Key].GetUIElement() == null)
            {
                    continue;
            }

            return m_compositeControl.ActiveRowScrollRegion.FirstRow.Cells[visibleHeader.Header.Column.Key];
}
 
This is a function in my framework that returns the first visible cell, which is used at the application layer to reset back to the first visible cell after refresh if required. Why am I using GetUIElement()? this is because the Visibleheaders[0] reffers to the column header that is prior to the visible column so on consecutive refresh the grid moves left one column and does not maintain it's position. To stop this from happening I looked for a way to see if the cells for the visible header where painted and saw that UIElement is null if they aren't. This worked but it does not seem right to use UIElement here. Is there a better or recommended way to achieve this?
Also, this code does not consider the fact that the VisibleHeader is a ColumnHeader i.e. I would like to avoid columns that are used on groupings etc. 
Thanks for your help.
Furqan Siddiqui
  • 469350
    Offline posted

    Hi, 

    The best thing to do here would be not to cause a data source reset. You will only lose your current positions if your data source sends a Reset notification of if you set the DataSource property to a new DataSource. So I'd recommend doing that if you possibly can - it's much easier and more efficient in the long run.

    If that's not possible, then the simplest thing to do would be to use: 

    this.ultraGrid1.ActiveColScrollRegion.VisibleHeaders[0].Header.Column

    I tried this out and it works correctly in my case, but I see that you mentioned it's not working for you because it's returning columns that are scrolled out of view. But I tried this out in a variety of different scenarios and I couldn't get this to happen. So I'm not sure why that's not working for you. 

    At first, I tried it in a simple grid with no groups. That worked fine.

    Then I added in some groups. In this case, the VisibleHeaders collection contains only group headers, no column headers. 

    Then I tried setting RowLayoutStyle to GroupLayout, and in this case, it once against seems to work correctly. So it might help if you could narrow down what RowLayoutStyle you are using so I know how you created your groups. 

    Anyway... your approach of using the UIElements is not necessarily a bad way to go. The only real down-side of this approach that I can see is that there's really no guarantee that the UIElement will return null when it's out of view. I mean... if it's doing that now and seems reliable, that's fine, but that's an undocumented behavior and in theory it could change in some future version of the controls. In my opinion, that would be very unlikely to change, but it's something to be aware of. 

    To answer your other question, you can determine whether the header is a column or group header simply by checking the Column and/or Group property. 

    visibleHeader.Header.Column will only return a column if the header is a column header. And visibleHeader.Header.Group will only return a group if it's a Group Header. 

    BTW... Another approach you could take is, instead of trying to store the column, you could just store the position of the horizontal scrollbar. After all... the first visible column doesn't necessarily have to be perfectly aligned to the left of the grid. It could be partially in view, in which case your code will not really restore the same position as before you reset the data. If your grid is still going to have the same columns after the reset and the columns/groups are all the same width as they were before, then the scroll position is probably a better way to go: 

    this.ultraGrid1.ActiveColScrollRegion.Position