WPF TreeView - 如何滚动如此扩展的分支是可见的

Jar*_*red 23 wpf treeview scroll

当我在树视图中展开项目以便滚动时,会出现滚动条.但是,它不会向下滚动新扩展的项目分支 - 它们会被控件的底部裁剪掉.因此,当我继续在树的底部扩展项目时,我必须手动向下滚动以查看新的子项.有人建议如何让它自动滚动显示新扩展的项目?

ito*_*son 18

在TreeView上,处理TreeViewItem.Expanded事件(由于事件冒泡,您可以在TreeView级别执行此操作).在Expanded处理程序中,在引发事件的TreeViewItem上调用BringIntoView.

您可能需要一些试验和错误来获取事件处理程序代码中的TreeViewItem.我认为(尚未检查)您的Expanded事件处理程序的sender参数将是TreeView(因为那是附加事件处理程序的地方)而不是TreeViewItem.e.Source或e.OriginalSource可能是TreeViewItem数据模板中的一个元素.因此,您可能需要使用VisualTreeHelper来查看可视树以查找TreeViewItem.但是如果你使用调试器检查发送者和RoutedEventArgs,这应该是微不足道的.

(如果你能够使它工作并想要捆绑它,这样你就不必将相同的事件处理程序附加到每个TreeView,应该很容易将它封装为附加行为,这将允许你应用它以声明的方式,包括通过风格.)


小智 17

您可以使用TreeViewItem样式中的简单EventSetter在选择项目时调用事件处理程序.然后为该项目调用BringIntoView.

<TreeView >
 <TreeView.ItemContainerStyle>
   <Style TargetType="{x:Type TreeViewItem}">
     <EventSetter Event="Selected" Handler="TreeViewSelectedItemChanged" />
   </Style>
 </TreeView.ItemContainerStyle>

</TreeView>

private void TreeViewSelectedItemChanged(object sender, RoutedEventArgs e)
{
    TreeViewItem item = sender as TreeViewItem;
    if (item != null)
    {
        item.BringIntoView();
        e.Handled = true;  
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 15

在IsSelected触发器上使用依赖项属性:

<Style TargetType="{x:Type TreeViewItem}">
 <Style.Triggers>
  <Trigger Property="IsSelected" Value="True">
    <Setter Property="commands:TreeViewItemBehavior.BringIntoViewWhenSelected" Value="True" />
  </Trigger>
</Style.Triggers>
Run Code Online (Sandbox Code Playgroud)

这是依赖属性的代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 至少应该引用原始来源:[WPF中的附加行为简介](https://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF) (3认同)
  • 当您在树上启用虚拟化时,这不起作用。(仅当您滚动到该项目时,IsSelected才会触发) (2认同)