使用VirtualizingStackPanel的ItemsControl中的精确滚动条控件 [英] Accurate scrollbar control in an ItemsControl with a VirtualizingStackPanel
问题描述
我有一个ItemsControl,该控件使用VirtualizingStackPanel来显示庞大(并且正在增长)的项目列表:
I have an Itemscontrol using a VirtualizingStackPanel to display a huge (and growing) list of items:
<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中所做的那样:
The virtualization is working like a charm, but i cannot get the management of the scrollbar right. If I try to programmatically (e.g. on load) scroll to the bottom like i do in non-virtualized StackPanels:
var scrollViewer = VisualTreeHelper.GetChild(ConversationItemsControl, 0) as ScrollViewer;
scrollViewer.ChangeView(null, double.MaxValue, 1f, true);
scrollviewer尝试滚动到底部,但没有完全这样做-它总是在真实"底部之前停下来一点.这在某种意义上是有道理的,因为VirtualizingStackPanels使用滚动值来确定要渲染的项目,但是这完全使我费力,最终用户无法接受.
the scrollviewer tries to scroll to the bottom, but does not do so completely - it always stops a bit before the "real" bottom. This makes sense in a way since VirtualizingStackPanels are using the scroll value to determine which items to render, but it is totally grinding my gears and unacceptable for end users.
如何滚动到真实"底部?如果我想精确地向下滚动 到一定程度,以至于某个项目的顶部位于视口的顶部(除非真实"底部自然太近了),我该怎么办?
How can I scroll to the "real" bottom? What do I have to do if i want to scroll exactly so far down that the top of a certain item is at the top of the viewport (unless the "real" bottom is too close, naturally)?
推荐答案
这是因为内置的ItemsControl类不支持虚拟化.您可以尝试使用默认情况下使用UI虚拟化的ListBox.
This is because the built-in ItemsControl class doesn't support virtualization. You can try a ListBox instead, which uses UI virtualization by default.
如果您不希望选择行为,只需设置:
If you don't want to have selection behaviour, just set:
<ListBox x:Name="lbCustom">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
然后类似:
lbCustom.ScrollIntoView(lbCustom.Items[lbCustom.Items.Count - 1]
这篇关于使用VirtualizingStackPanel的ItemsControl中的精确滚动条控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!