我有一个使用 VirtualizingStackPanel 的 Itemscontrol 来显示一个巨大的(并且不断增长的)项目列表:
<ItemsControl Grid.Row="1" Name="ConversationItemsControl" VirtualizingStackPanel.VirtualizationMode="Recycling">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:Message />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
虚拟化就像一个魅力,但我无法正确管理滚动条。如果我尝试以编程方式(例如加载时)滚动到底部,就像我在非虚拟化 StackPanels 中所做的那样:
var scrollViewer = VisualTreeHelper.GetChild(ConversationItemsControl, 0) as ScrollViewer;
scrollViewer.ChangeView(null, double.MaxValue, 1f, true);
scrollviewer 尝试滚动到底部,但并没有完全这样做 - 它总是在“真实”底部之前停止一点。这在某种程度上是有道理的,因为 VirtualizingStackPanels 使用滚动值来确定要渲染的项目,但这完全是我的磨难,最终用户无法接受。
如何滚动到“真实”底部?如果我想精确地向下滚动到某个项目的顶部位于视口的顶部(除非“真实”底部自然地太近),我该怎么办?