You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MVVM模式下将WPF TreeView的IsExpanded绑定到命令实现节点折叠

WPF MVVM模式下TreeView批量折叠节点实现方案

核心思路

遵循MVVM原则,把TreeViewItem的IsExpanded属性绑定到节点数据模型的对应属性,通过ViewModel中的命令触发批量修改所有节点的该属性,实现全折叠效果。

具体步骤

1. 改造节点数据模型

给你的节点ViewModel(比如命名为TreeNodeViewModel)添加IsExpanded属性,实现INotifyPropertyChanged接口来通知UI更新:

public class TreeNodeViewModel : INotifyPropertyChanged
{
    private bool _isExpanded = true; // 默认展开,对应原Style的初始值
    public bool IsExpanded
    {
        get => _isExpanded;
        set
        {
            if (_isExpanded != value)
            {
                _isExpanded = value;
                OnPropertyChanged();
                // 可选:递归折叠所有子节点
                if (!value && Children != null)
                {
                    foreach (var child in Children)
                    {
                        child.IsExpanded = false;
                    }
                }
            }
        }
    }

    // 节点的子集合和其他属性
    public ObservableCollection<TreeNodeViewModel> Children { get; set; } = new();
    public string DisplayName { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 修改TreeViewItem样式

把原来静态设置的IsExpanded改成双向绑定到节点模型的IsExpanded属性:

<Style x:Key="TreeViewItemStyle2" TargetType="{x:Type TreeViewItem}">
    <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
    <!-- 保留你原来的其他样式设置 -->
</Style>

3. 在主ViewModel中添加折叠命令

实现一个RelayCommand来遍历所有节点,递归设置IsExpanded为false:

public class MainViewModel : INotifyPropertyChanged
{
    public ObservableCollection<TreeNodeViewModel> Nodes { get; set; }
    public ICommand CollapseAllCommand { get; }

    public MainViewModel()
    {
        Nodes = LoadYourNodesData(); // 替换成你的节点初始化逻辑
        CollapseAllCommand = new RelayCommand(CollapseAllNodes);
    }

    private void CollapseAllNodes()
    {
        foreach (var node in Nodes)
        {
            CollapseNodeRecursively(node);
        }
    }

    private void CollapseNodeRecursively(TreeNodeViewModel node)
    {
        node.IsExpanded = false;
        if (node.Children != null)
        {
            foreach (var child in node.Children)
            {
                CollapseNodeRecursively(child);
            }
        }
    }

    // 实现INotifyPropertyChanged接口的代码...
}

4. 绑定按钮命令

在XAML里添加按钮并绑定到ViewModel的命令:

<Button Content="折叠所有节点" Command="{Binding CollapseAllCommand}"/>

补充提示

  • 如果只需要折叠顶层节点,去掉递归逻辑即可;如果要全层级折叠,保留递归。
  • 确保你的RelayCommand已经正确实现(标准的ICommand实现类,处理Execute和CanExecute逻辑)。

内容的提问来源于stack exchange,提问作者Igor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:55:16