使用虚拟化数据网格保持滚动位置

时间:2018-05-31 11:18:16

标签: c# wpf

我有点问题。我有一个datagrid,显示了很多行。因此,为了提高性能,我决定虚拟化我的数据网格。 直到这个,没问题。现在,我想在刷新后保持滚动位置。

尽管进行了一些研究,但我找不到解决方案。 这是我的代码,但是,它不起作用:

 <DataGrid x:Name="Test" AutoGenerateColumns="False" ItemsSource="{Binding ItemCollection}" SelectionMode="Single"  IsReadOnly="True"
                         CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False"
                         SelectedItem="{Binding SelectedItem, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                         VirtualizingPanel.IsVirtualizingWhenGrouping="True" VirtualizingPanel.IsContainerVirtualizable="True"
                         VirtualizingPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" Grid.Row="1"
                         ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled">

在我的ViewModel中,我像这样刷新我的数据网格:

public ICollectionView ItemCollection
{
    get
    {
        return _itemCollection;
    }
    set
    {
        _itemCollection= value;
        OnPropertyChanged(() => ItemCollection);
    }
} 

这是我的函数,它补充了datagrid集合:

var orderCollection = Items.OrderByDescending(item => item.BeginDate);

var itemCollection = CollectionViewSource.GetDefaultView(orderCollection);
itemCollection.GroupDescriptions.Clear();

using (itemCollection.DeferRefresh())
{
    itemCollection.GroupDescriptions.Add(new PropertyGroupDescription("ShortStartDate"));
    itemCollection.Filter = ApplyFilter;
}

ItemCollection = itemCollection;

而这,我的代码背后。在调用上述方法之前调用GetScrollPosition。而SetScrollPosition就在之后调用。

private void GetScrollPosition()
{
    if (DayBooks != null)
    {
        var scrollViewer = GetScrollViewer(DayBooks);
        if (scrollViewer != null)
            _currentScrollPosition = scrollViewer.VerticalOffset;
    }
}

public void SetScrollPosition()
{
    if (Test != null)
    {
        var scrollViewer = GetScrollViewer(Test);
        if (scrollViewer != null)
        {
            if (_currentScrollPosition != 0)
            {
                scrollViewer.InvalidateScrollInfo();
                scrollViewer.ScrollToVerticalOffset(_currentScrollPosition);
            }
        }
    }
}

private ScrollViewer GetScrollViewer(UIElement element)
{
    if (element == null) return null;

    ScrollViewer retour = null;
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element) && retour == null; i++)
    {
        if (VisualTreeHelper.GetChild(element, i) is ScrollViewer)
        {
            retour = (ScrollViewer)(VisualTreeHelper.GetChild(element, i));
        }
        else
        {
            retour = GetScrollViewer(VisualTreeHelper.GetChild(element, i) as UIElement);
        }
    }
    return retour;
}

所以,当我的数据网格更新时,我试图设置我的滚动位置(_currentScrollPosition),但是该位置保持为0并且我失去了我的位置。

是否可以解决我的问题并保持虚拟化过程?

1 个答案:

答案 0 :(得分:0)

您的问题通常会通过滚动到视图行为来解决,该行为会对选定项目而不是某个scoll位置做出反应: ScrollIntoView for WPF DataGrid (MVVM)

您是否考虑过使用此类行为来实现您正在寻找的行为?