在 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;
}
}
我有一个 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;
}
}