在 UWP 中添加新项目时临时暂停在 ItemsControl 上滚动

Temporarily pause scrolling on an ItemsControl as new items are added in UWP

我有一个 observablecollection 日志,它将新条目插入 Windows 通用应用程序的顶部。我通过将日志绑定到 itemscontrol 来让用户查看日志。如果日志中有大量传入更新,则可能难以使用,因为它会随着新项目的添加而不断滚动。我想添加一个暂停按钮来暂停滚动或更新。

我看到了 beginupdate 和 endupdate,但它们似乎只适用于 WPF 控件。我也在考虑在我的日志 class 中关闭引发 propertychanged 事件的内容,但我不确定如何在 itemscontrol 未暂停时无缝更新错过的所有内容?

我想出了一个解决方案...我将 itemscontrol 放入滚动查看器而不是 ItemContainerStyle 中的滚动查看器。

所以基本上我一直在跟踪滚动查看器的虚拟大小并跟踪日志收集。当暂停并且集合发生变化时,将 scrollviewer 的垂直偏移量移动它刚刚增长的量,同时禁用动画,因此移动不可见,因此它明显保持在同一个位置。

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        Log.Entries.CollectionChanged += Entries_CollectionChanged;
        this.LogItemsControl.ItemsSource = Log.Entries;
        lastExtentHeight = this.ScrollViewer.ExtentHeight;
    }

    private void Entries_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        lastExtentHeight = this.ScrollViewer.ExtentHeight;

        if (scrollingPaused)
        {
            double sizeGrown = ScrollViewer.ExtentHeight - pausedExtentHeight;

            pausedVerticalOffset += sizeGrown;
            pausedExtentHeight = ScrollViewer.ExtentHeight;

            this.ScrollViewer.ChangeView(0, pausedVerticalOffset, 1, true);
        }
    }

    private void PlayPauseAppBarButton_Click(object sender, RoutedEventArgs e)
    {
        if (scrollingPaused)
        {
            // UnPause
            scrollingPaused = false;
        }
        else
        {
            // Pause
            pausedVerticalOffset = this.ScrollViewer.VerticalOffset;
            pausedExtentHeight = lastExtentHeight;

            scrollingPaused = true;
        }
    }