WPF中没有提供确保显示TreeView选中的Item的功能,因此写个函数实现:
public void EnsureTreeViewItemVisible(TreeView treeview, TreeViewItem selectedItem)
{
Point itemPosition = selectedItem.TranslatePoint(new Point(0, 0), treeview);
ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(treeview, 0), 0);
int childenCount = VisualTreeHelper.GetChildrenCount(selectedItem);
double selectdItemWidth = treeview.ActualWidth;
double selecedItemHeight = 16;
if (childenCount > 0)
{
FrameworkElement itemGrid = (FrameworkElement)VisualTreeHelper.GetChild(selectedItem, 0);
FrameworkElement itemExpander = (FrameworkElement)VisualTreeHelper.GetChild(itemGrid, 0);
FrameworkElement itemBorder = (FrameworkElement)VisualTreeHelper.GetChild(itemGrid, 1);
selectdItemWidth = itemExpander.ActualWidth + itemBorder.ActualWidth;
selecedItemHeight = itemBorder.ActualHeight > itemExpander.ActualHeight ? itemBorder.ActualHeight : itemExpander.ActualHeight;
}
else
{
Trace.WriteLine("Can't get the item children!");
}
double horizontalOffset = scrollViewer.HorizontalOffset;
if (itemPosition.X < 0)
{
horizontalOffset += itemPosition.X;
}
else if ((itemPosition.X + selectdItemWidth) > scrollViewer.ViewportWidth)
{
if (selectdItemWidth > treeview.ActualWidth)
{
horizontalOffset -= itemPosition.X;
}
else
{
horizontalOffset += (itemPosition.X + selectdItemWidth - scrollViewer.ViewportWidth);
}
}
if (horizontalOffset != scrollViewer.HorizontalOffset)
scrollViewer.ScrollToHorizontalOffset(horizontalOffset);
double verticalOffset = scrollViewer.VerticalOffset;
if (itemPosition.Y < 0)
{
verticalOffset += itemPosition.Y;
}
else if ((itemPosition.Y + selecedItemHeight) > scrollViewer.ViewportHeight)
{
verticalOffset += (itemPosition.Y + selecedItemHeight - scrollViewer.ViewportHeight);
}
if (verticalOffset != scrollViewer.VerticalOffset)
scrollViewer.ScrollToVerticalOffset(verticalOffset);
}
private void TestTreeView_ItemSelected(object sender, RoutedEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(new Action(delegate
{
TreeViewItem selectedItem = e.OriginalSource as TreeViewItem;
ViewModel.EnsureTreeViewItemVisible(VisualElementTree, selectedItem);
}), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
}
<TreeView x:Name="TestTreeView" TreeViewItem.Selected="TestTreeView_ItemSelected">
</TreeView>