WPF TreeView - Как прокрутить так расширенное ответвление, видим

Когда я разворачиваю объекты в своем treeview так, чтобы прокрутка была необходима, полоса прокрутки появляется. Однако это не прокручивает вниз для недавно расширенного ответвления объектов - они обрезаются нижней частью управления. Таким образом, в то время как я продолжаю разворачивать объекты у основания дерева, я должен продолжать вручную прокручивать вниз для наблюдения новых детей. У кого-либо есть предложение для того, как заставляют его автоматически прокрутить для показа недавно расширенных объектов?

23
задан Jared 11 February 2010 в 00:16
поделиться

3 ответа

На TreeView обработайте событие TreeViewItem.Expanded (вы можете сделать это на уровне TreeView из-за пузырька событий). В обработчике Expanded вызовите BringIntoView для TreeViewItem, который вызвал событие.

Вам может потребоваться немного проб и ошибок, чтобы получить доступ к TreeViewItem в коде обработчика события. Я думаю (не проверял), что аргументом отправителя в обработчике события Expanded будет TreeView (поскольку именно к нему прикреплен обработчик события), а не TreeViewItem. А e.Source или e.OriginalSource может быть элементом в шаблоне данных TreeViewItem. Поэтому вам может понадобиться использовать VisualTreeHelper, чтобы пройтись по визуальному дереву и найти TreeViewItem. Но если вы используете отладчик для проверки отправителя и RoutedEventArgs, это должно быть тривиально.

(Если вы сможете заставить это работать и захотите объединить это, чтобы вам не пришлось прикреплять один и тот же обработчик событий к каждому TreeView, это должно быть легко инкапсулировать как присоединенное поведение, что позволит вам применять его декларативно, в том числе через стиль)

.
18
ответ дан 29 November 2019 в 01:27
поделиться

Благодаря ответу 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();
}
2
ответ дан 29 November 2019 в 01:27
поделиться

Использование свойства зависимости в триггере 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();
}
15
ответ дан 29 November 2019 в 01:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: