GridView 不会向下滚动到虚拟化项目

GridView doesn't scroll down to virtualized items

在我的应用程序中,当我返回图书馆时,我需要select 新创建的文档(注释)。 selected 库项目后,必须将库滚动到 selected 项目。

我的库的 OnLoaded 方法:

private async void OnLoaded(object sender, RoutedEventArgs e)
{
   await this.ViewModel.InitializeAsync();

   // CollectionViewSource of my GridView being filled
   ViewModel.CollectionChanging = true;
   GroupInfoCVS.Source = ViewModel.GroupsCollection;
   ViewModel.CollectionChanging = false;

   // Loading Last selected item - THIS CHANGES SELECTION
   ViewModel.LoadLastSelection();
}

在我调用 LoadLastSelection 方法后,selection 更改成功(我已经测试过)。这是之后调用的方法(在我们的 GridView 的扩展控件中):

private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    this.SelectedItemsCount = this.SelectedItems.Count;

    var newlySelectedItems = e.AddedItems;
    if (newlySelectedItems.Any())
    {
        var item = newlySelectedItems.Last();
        ScrollTo(item);
    }
}

private void ScrollTo(object item)
{
    UpdateLayout();
    var itemUI = (FrameworkElement)this.ContainerFromItem(item);

    if (itemUI != null)
    {
        _scrollViewer.UpdateLayout();
        _scrollViewer.ChangeView(null, itemUI.ActualOffset.Y - itemUI.ActualHeight, null, false);
    }
}

这在大多数情况下也 有效。当 itemUI 不为 null 时,该方法成功滚动到所需的项目。当项目开始溢出屏幕尺寸时,问题就开始了。当项目从屏幕上完全隐藏时,它们就被虚拟化了。这意味着 ContainerFromItem returns 为 null,因此我无法获取偏移属性。请记住,这实际上发生在 之前 库的 OnLoaded 方法完成。

请帮我一些替代方法来获取此类属性或其他滚动方法,这将帮助我成功滚动。

我读了很多书并尝试使用 Dispatcher.RunAsync 和 ScrollIntoView 方法,但我无法产生任何滚动行为。如果你指出我如何成功使用它们,那也是一个很好的帮助。

这是我读过(并尝试过)的内容:

ItemContainerGenerator.ContainerFromItem() returns null?

Is there a "All Children loaded" event in WPF

Let ListView scroll to selected item

提前致谢!

重要提示:如果您不想阅读官方答案中的所有对话,请在此处阅读简短的解决方案:

TemplatedControl 的样式已将 ScrollViewer 的名称从“ScrollViewer”更改为“LibraryScrollViewer”,这导致 ScrollIntoView 方法无用。

对于GridView,实现您需求的最佳方法是调用GridView.ScrollIntoView

但是你好像也做过类似的尝试,并没有成功,那么以下几点可能对你有帮助:

1.不要使用 GridView 作为 ScrollViewer.

的子元素

在你的代码中,我看到你正在调用ScrollViewer.ChangeView的方法来调整视图滚动,所以推测你可能会将GridView放在ScrollViewer中, 不推荐。

因为GridView里面有个ScrollViewer,它的ScrollIntoView方法是改变内部ScrollViewer的滚动区域。当外面有ScrollViewer时,GridView里面的ScrollViewer会失去滚动能力,从而使ScrollIntoView方法失效。

2。实现数据class.

Equals方法

如果你的数据class不是简单类型(比如StringInt32等),那么实现数据的Equals方法class 将帮助 GridView 找到相应的项目。

谢谢。