WPF中没有提供确保显示ListBox选中的Item这个功能,因此写了个函数来实现:
public void EnsureListBoxItemVisible(ListBox listbox, ListBoxItem selectedItem)
{
int itemIndex = listbox.SelectedIndex;
ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(listbox, 0), 0);
int verticalOffset = (int)scrollViewer.VerticalOffset;
if (itemIndex < verticalOffset)
{
verticalOffset = itemIndex;
}
else if (itemIndex > (int)(scrollViewer.ViewportHeight + verticalOffset - 1))
{
verticalOffset = itemIndex + 1 - (int)scrollViewer.ViewportHeight;
}
if (verticalOffset != scrollViewer.VerticalOffset)
scrollViewer.ScrollToVerticalOffset(verticalOffset);
}
private void TestListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(new Action(delegate
{
ListBoxItem selectedItem = e.OriginalSource as ListBoxItem;
ViewModel.EnsureListBoxItemVisible(TestListBox, selectedItem);
}), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
}
private void TestListBox_ItemSelected(object sender, RoutedEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(new Action(delegate
{
ListBoxItem selectedItem = e.OriginalSource as ListBoxItem;
ViewModel.EnsureListBoxItemVisible(TestListBox, selectedItem);
}), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
}
<ListBox x:Name="TestListBox" SelectionChanged="TestListBox_SelectionChanged">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="ListBoxItem.Selected" Handler="TestListBox_ItemSelected" HandledEventsToo="True"/>
</Style>
</ListBox.Resources>
</ListBox>