New to Telerik UI for WPF? Download free 30-day trial

How to Keep the Selected Item in the Viewport when the Collection is Changed

Environment

Product RadGridView for WPF

Description

When an item is added or removed from the source collection of the RadGridView control, the scroll position is changed.

This article explains how to keep the selected item in the viewport when the collection is changed.

Solution

To keep the position of the selected item, you can handle the CollectionChanged event of its Items collection and offset the GridViewScrollViewer by the amount of items added/removed multiplied by the RowHeight.

Handle CollectionChanged event to keep item in viewport

gridView.Items.CollectionChanged += (s, a) => 
{ 
    var selectedItem = gridView.SelectedItem; 
    var selectedItemIndex = gridView.Items.IndexOf(selectedItem); 
 
    double offset = 0; 
 
    if (a.NewItems != null) 
    { 
        foreach (var item in a.NewItems) 
        { 
            if (gridView.Items.IndexOf(item) < selectedItemIndex) 
            { 
                offset += gridView.RowHeight; 
            } 
        } 
    } 
 
    if (a.OldItems != null) 
    { 
        foreach (var item in a.OldItems) 
        { 
            if (a.OldStartingIndex < selectedItemIndex) 
            { 
                offset -= gridView.RowHeight; 
            } 
        } 
    } 
 
    var scrollViewer = gridView.ChildrenOfType<GridViewScrollViewer>().FirstOrDefault(); 
    scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset); 
    scrollViewer.UpdateLayout(); // required so that the value of the VerticalOffset property is updated 
}; 
AddHandler gridView.Items.CollectionChanged, Sub(s, a) 
    Dim selectedItem = gridView.SelectedItem 
    Dim selectedItemIndex = gridView.Items.IndexOf(selectedItem) 
 
    Dim offset As Double = 0 
 
    If a.NewItems IsNot Nothing Then 
        For Each item In a.NewItems 
            If gridView.Items.IndexOf(item) < selectedItemIndex Then 
                offset += gridView.RowHeight 
            End If 
        Next item 
    End If 
 
    If a.OldItems IsNot Nothing Then 
        For Each item In a.OldItems 
            If a.OldStartingIndex < selectedItemIndex Then 
                offset -= gridView.RowHeight 
            End If 
        Next item 
    End If 
 
    Dim scrollViewer = gridView.ChildrenOfType(Of GridViewScrollViewer)().FirstOrDefault() 
    scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset) 
    scrollViewer.UpdateLayout() ' required so that the value of the VerticalOffset property is updated 
End Sub 

A working example of this approach can be found in our SDK Samples Browser. It is titled Preserve Selected Item Scroll Position.

See Also

In this article