【问题标题】:GridView doesn't scroll down to virtualized itemsGridView 不会向下滚动到虚拟化项目
【发布时间】:2020-09-17 03:45:40
【问题描述】:

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

我的库的 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 方法后,选择成功更改(我已经测试过)。这是之后调用的方法(在我们的 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 返回 null,所以我不能获取偏移属性。请记住,这实际上发生在 库的 OnLoaded 方法完成之前。

请帮助我获得这些属性或其他滚动方法的替代方法,这将帮助我成功滚动。

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

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

ItemContainerGenerator.ContainerFromItem() returns null?

How to Know When a FrameworkElement Has Been Totally Rendered?

Is there a "All Children loaded" event in WPF

Let ListView scroll to selected item

提前致谢!

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

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

【问题讨论】:

    标签: c# xaml gridview uwp uwp-xaml


    【解决方案1】:

    对于GridView,满足您需求的最佳方式是致电GridView.ScrollIntoView

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

    1.不要将GridView 用作ScrollViewer 的子元素。

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

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

    2。实现数据类的Equals方法。

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

    谢谢。

    【讨论】:

    • 亲爱的理查德,谢谢。 _scrollViewer 是我们的 GridView 扩展 (NotesGridView) 模板中的 ScrollViewer。所以实际上,ScrollViewer 是 GridView 的一部分,而不是相反。到目前为止,我在进行平等检查时没有问题。我的主要问题是 ScrollIntoView 似乎根本不起作用。
    • 你好,作为对比,你可以用一个普通的GridView来显示数据,然后调用ScrollIntoView看是否生效(我尝试创建一个可以滚动到的简单demo最后一项通常)。如果普通的GridView有效,能否分享一下你创建的自定义GridView控件,问题可能出在这个。
    • 亲爱的理查德,您说得对,我们都没有预料到。我们确实有一个带有自定义模板的模板化控件。主要问题是 ScrollViewer - 它的标准名称是“ScrollViewer”,但在我们的模板中它被重命名为“LibraryScrollViewer”。这导致 ScrollIntoView 方法不起作用。请在您的答案中添加一行,让人们知道阅读下面的 cmets,我会将其标记为已回答。否则我必须自己写答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 2018-03-21
    • 2017-08-12
    相关资源
    最近更新 更多