【问题标题】:Multi-layer "Expand All" for expanders?扩展器的多层“全部扩展”?
【发布时间】:2026-02-18 14:50:01
【问题描述】:

我正在编写一个 MVVM 配置界面,并且我正在尝试实现适用于所有视图的展开/折叠所有功能。

顶层 ViewModel 是其他 ViewModel 的同质集合,它绑定到视图中的 ItemsControl。这些子 ViewModel 中的每一个都有许多依赖的 ViewModel,每个 ViewModel 都绑定到 View 中的一个 ContentControl。从视觉上看,这采用一组扩展器(例如,其中 3 个)的形式,每个扩展器内部都隐藏着 4-6 个扩展器。

我尝试过自上而下的搜索方法。由于*扩展器已折叠,因此它们的子扩展器甚至在它们第一次显示之前都不存在(Caliburn.Micro 在第一次被要求时为它们做查看位置),并且“全部展开” action 只扩展了第一层。

逻辑树也没有任何帮助。* ItemsControl 的 Items 属性实际上包含我的 ViewModel 类型的对象,因此我无法在其中查找扩展器。

我曾考虑在 ViewModel 级别进行管理,但是向所有 VM 添加一个 IsExpanded 属性并使用一些全局管理器进行设置似乎很麻烦。虚拟机没有其他理由知道扩展了哪些扩展器。

处理此问题的最佳方法是什么?是否有一些我可以提取的附加属性绑定技巧?

【问题讨论】:

  • 抱歉,但我不确定我是否得到了您想要实现的目标,您想对每个 VM 的 IsExpanded 属性做什么?在 XAML 中绑定或以某种方式处理?
  • 不,这都是视觉层面的;我正在尝试设置所有 Expander 控件的 IsExpanded 属性。

标签: wpf mvvm expander


【解决方案1】:

您的 ViewModel 应该有一个可以扩展自身并在其子级中调用相同函数的函数。

public abstact class BaseItem
{
   public List<BaseItem> Children;

   public virtual void SetSelfAndChildrenExpandedState(bool inState)
   {
      // Expand Self
      IsExpanded = inState;
      // Expand Children
      foreach (BaseItem i in Children)
      {
          i.SetSelfAndChildrenExpandedState(inState);
      }
   }

   public bool IsExpanded { get; set; }
}

现在您只需连接您的“全部展开”操作,即可使用适当的参数调用 SetSelfAndChildrenExpandedState()。

这可能对你有用...考虑一下。

【讨论】:

  • 我试图避免这成为一个视图模型问题,但这种方法效果很好。实际上,我最终继承自 ReactiveObject 并使用了 allPublicProperties 助手。谢谢!