Когда я разворачиваю объекты в своем treeview так, чтобы прокрутка была необходима, полоса прокрутки появляется. Однако это не прокручивает вниз для недавно расширенного ответвления объектов - они обрезаются нижней частью управления. Таким образом, в то время как я продолжаю разворачивать объекты у основания дерева, я должен продолжать вручную прокручивать вниз для наблюдения новых детей. У кого-либо есть предложение для того, как заставляют его автоматически прокрутить для показа недавно расширенных объектов?
На TreeView обработайте событие TreeViewItem.Expanded (вы можете сделать это на уровне TreeView из-за пузырька событий). В обработчике Expanded вызовите BringIntoView для TreeViewItem, который вызвал событие.
Вам может потребоваться немного проб и ошибок, чтобы получить доступ к TreeViewItem в коде обработчика события. Я думаю (не проверял), что аргументом отправителя в обработчике события Expanded будет TreeView (поскольку именно к нему прикреплен обработчик события), а не TreeViewItem. А e.Source или e.OriginalSource может быть элементом в шаблоне данных TreeViewItem. Поэтому вам может понадобиться использовать VisualTreeHelper, чтобы пройтись по визуальному дереву и найти TreeViewItem. Но если вы используете отладчик для проверки отправителя и RoutedEventArgs, это должно быть тривиально.
(Если вы сможете заставить это работать и захотите объединить это, чтобы вам не пришлось прикреплять один и тот же обработчик событий к каждому TreeView, это должно быть легко инкапсулировать как присоединенное поведение, что позволит вам применять его декларативно, в том числе через стиль)
.Благодаря ответу itowlson, вот расширенный код обработчика событий, который работает для обоих моих деревьев
private static void Tree_Expanded(object sender, RoutedEventArgs e)
{
// ignore checking, assume original source is treeviewitem
var treeViewItem = (TreeViewItem)e.OriginalSource;
var count = VisualTreeHelper.GetChildrenCount(treeViewItem);
for (int i = count - 1; i >= 0; --i)
{
var childItem = VisualTreeHelper.GetChild(treeViewItem, i);
((FrameworkElement)childItem).BringIntoView();
}
// do NOT call BringIntoView on the actual treeviewitem - this negates everything
//treeViewItem.BringIntoView();
}
Использование свойства зависимости в триггере IsSelected:
<Style TargetType="{x:Type TreeViewItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="commands:TreeViewItemBehavior.BringIntoViewWhenSelected" Value="True" />
</Trigger>
</Style.Triggers>
Вот код для свойства зависимости:
public static bool GetBringIntoViewWhenSelected(TreeViewItem treeViewItem)
{
return (bool)treeViewItem.GetValue(BringIntoViewWhenSelectedProperty);
}
public static void SetBringIntoViewWhenSelected(TreeViewItem treeViewItem, bool value)
{
treeViewItem.SetValue(BringIntoViewWhenSelectedProperty, value);
}
public static readonly DependencyProperty BringIntoViewWhenSelectedProperty =
DependencyProperty.RegisterAttached("BringIntoViewWhenSelected", typeof(bool),
typeof(TreeViewItemBehavior), new UIPropertyMetadata(false, OnBringIntoViewWhenSelectedChanged));
static void OnBringIntoViewWhenSelectedChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
TreeViewItem item = depObj as TreeViewItem;
if (item == null)
return;
if (e.NewValue is bool == false)
return;
if ((bool)e.NewValue)
item.BringIntoView();
}