我一直在研究如何让VirtualizingStackPanel的ItemsControl滚动到某个项目,但一直找到的答案是“使用ListBox”。我不想用ListBox,所以我找到了一种方法。首先,您需要为ItemsControl设置一个控件模板,其中包含一个ScrollViewer(如果您正在使用ItemsControl,则可能已经拥有)。我的基本模板类似于以下内容(包含在ItemsControl的便捷样式中)
<Style x:Key="TheItemsControlStyle" TargetType="">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="">
<Border BorderThickness="" Padding="" BorderBrush="" Background="" SnapsToDevicePixels="True">
<ScrollViewer Padding="" Focusable="False" HorizontalScrollBarVisibility="Auto">
<ItemsPresenter SnapsToDevicePixels="" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
所以,我基本上有一个带有滚动视图的边框,它将包含我的内容。
我的ItemsControl定义为:
<ItemsControl x:Name="myItemsControl" [..snip..] Style="{DynamicResource TheItemsControlStyle}" ScrollViewer.CanContentScroll="True" VirtualizingStackPanel.IsVirtualizing="True">
现在来到有趣的部分。我已经创建了一个扩展方法,可以将其附加到任何 ItemsControl 上,以便滚动到给定的项:
public static void VirtualizedScrollIntoView(this ItemsControl control, object item) {
try {
ScrollViewer sv = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild((DependencyObject)control, 0), 0) as ScrollViewer;
int index = control.Items.IndexOf(item);
if(index != -1) {
sv.ScrollToVerticalOffset(index);
}
} catch(Exception ex) {
Debug.WriteLine("What the..." + ex.Message);
}
}
有了扩展方法后,您可以像使用ListBox的伴生方法一样使用它:
myItemsControl.VirtualizedScrollIntoView(someItemInTheList)
非常好用!
请注意,您还可以调用sv.ScrollToEnd()和其他常见的滚动方法来浏览您的项目。