如何在代码后面展开WPF树视图的所有节点?

Pad*_*oti 13 c# wpf treeview expand

我可能会遇到星期一的愚蠢,但是在我将它们添加到后面的代码中后,我找不到扩展所有树视图节点的好方法(比如treeView.ExpandAll()).

有什么快速帮助?

OrP*_*Paz 29

在xaml中,您可以按如下方式执行此操作:

 <TreeView.ItemContainerStyle>
            <Style TargetType="TreeViewItem">
                <Setter Property="TreeViewItem.IsExpanded" Value="True"/>
            </Style>
 </TreeView.ItemContainerStyle>
Run Code Online (Sandbox Code Playgroud)


bri*_*ler 5

在尝试了完全展开和折叠树视图的所有各种方法之后,目前最快的方法如下。这种方法似乎适用于非常大的树。

确保你的树是虚拟化的,如果它没有被虚拟化,那么一旦树达到任何大小,无论你做什么,它都会变得非常缓慢。

VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
Run Code Online (Sandbox Code Playgroud)

假设您有一个支持树的视图模型,该视图模型上对应于一个属性的每个节点都HierarchicalDataTemplate需要一个IsExpanded属性(它不需要实现属性更改)。假设这些视图模型实现了这样的接口:

interface IExpandableItem : IEnumerable
{
    bool IsExpanded { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

TreeViewItem风格需要如下的绑定设置IsExpanded属性视图模型视图:

<Style
    TargetType="{x:Type TreeViewItem}">
    <Setter
        Property="IsExpanded"
        Value="{Binding
            IsExpanded,
            Mode=TwoWay}" />
</Style>
Run Code Online (Sandbox Code Playgroud)

我们将使用这个属性来设置扩展状态,而且,因为树是虚拟化的,这个属性对于在个体TreeViewItems 被回收时保持正确的视图状态是必要的。如果没有这个绑定节点,当用户浏览树时,它们会消失在视野之外。

在大树上获得可接受的速度的唯一方法是在视图层后面的代码中工作。计划基本如下:

  1. 获取当前绑定到TreeView.ItemsSource.
  2. 清除那个绑定。
  3. 等待绑定真正清除。
  4. 在(现在未绑定)视图模型中设置扩展状态。
  5. 重新绑定TreeView.ItemsSource使用绑定,我们在第1步缓存。

因为我们启用了虚拟化TreeView.ItemsSource,所以即使使用大型视图模型,执行绑定也非常快。同样,当 unbound 更新节点的扩展状态应该非常快。这导致了令人惊讶的快速更新。

这是一些代码:

void SetExpandedStateInView(bool isExpanded)
{
    var model = this.DataContext as TreeViewModel;
    if (model == null)
    {
        // View model is not bound so do nothing.
        return;
    }

    // Grab hold of the current ItemsSource binding.
    var bindingExpression = this.TreeView.GetBindingExpression(
        ItemsControl.ItemsSourceProperty);
    if (bindingExpression == null)
    {
        return;
    }

    // Clear that binding.
    var itemsSourceBinding = bindingExpression.ParentBinding;
    BindingOperations.ClearBinding(
    this.TreeView, ItemsControl.ItemsSourceProperty);

    // Wait for the binding to clear and then set the expanded state of the view model.
    this.Dispatcher.BeginInvoke(
        DispatcherPriority.DataBind, 
        new Action(() => SetExpandedStateInModel(model.Items, isExpanded)));

    // Now rebind the ItemsSource.
    this.Dispatcher.BeginInvoke(
        DispatcherPriority.DataBind,
        new Action(
            () => this.TreeView.SetBinding(
                ItemsControl.ItemsSourceProperty, itemsSourceBinding)));
}

void SetExpandedStateInModel(IEnumerable modelItems, bool isExpanded)
{
    if (modelItems == null)
    {
        return;
    }

    foreach (var modelItem in modelItems)
    {
        var expandable = modelItem as IExpandableItem;
        if (expandable == null)
        {
            continue;
        }

        expandable.IsExpanded = isExpanded;
        SetExpandedStateInModel(expandable, isExpanded);
    }
}
Run Code Online (Sandbox Code Playgroud)