【问题标题】:Flattening a hierarchy of observable collections into a single observable collection将可观察集合的层次结构展平为单个可观察集合
【发布时间】:2012-07-24 12:05:56
【问题描述】:

我有一个可观察集合的层次结构,有点像这样:

interface IItem
{
    ObservableCollection<IItem> Children { get; }
}

给定一个IItem(或ObservableCollection&lt;IItem&gt;),我想构造一个其他可观察的集合,它递归地包含所有子IItem 项目。然后,此集合将用作 WPF 列表视图的数据源(例如)。

修改这些项目中的任何一个以具有其他子项都应该更新生成的 observable 集合。请注意,没有循环引用。

我知道CompositeCollection Class,我相信这应该对我有帮助(我认为我需要的只是一个复合集合,它递归地包含Children 中每个孩子的复合集合),但我可以因为这个类没有能力将孩子“模板化”到所需的复合集合中。

【问题讨论】:

  • 一种方法是监听每个子 ObservableCollection 上的事件并更新“扁平化”列表。
  • @RQDQ 这将是我最初的方法,但是我意识到这很容易开始变得非常复杂,因为我需要确保我递归地附加到更改事件并从中分离因为孩子在 heirachy 中被添加和删除。看到CompositeCollection类,希望有更简单的方法。

标签: c# wpf observablecollection compositecollection


【解决方案1】:

您如何使用这个扁平化列表?你需要不时列举它吗? 考虑以下几点:

IEnumerable<Item> iterate(Item item)
{
     if (item == null)
          yield break;

     yield return item;

     foreach(Item i in item.Children)
     {
         foreach(Item ii in iterate(i){
            yield return ii;
         }
     }  
}

这实质上使层次结构变平并允许您遍历所有项目。由于它是懒惰的,它总是在旅途中进行评估。并且与对层次结构中单个项目所做的更改一致(只要您不同时枚举和更改)。

编辑:

flattend 集合根本不是一个集合,它是一个包含层次结构中所有项目的项目序列的表示。这意味着如果您从某个项目中添加(或删除)子项,您将在更改前后获得一致的结果。

考虑以下几点:

Item item = buildItemHierarchy();变平=迭代(项目); item.Children.RemoveAt(2); // 假设 2 存在

flat 现在“包含”原始树中的所有项目,不包括从根的第二个子节点发芽的分支(递归!)

【讨论】:

  • 它需要是可观察的,这样如果项目被添加到任何子集合中/从任何子集合中删除,扁平集合也会更新。
  • 它仍然无法观察到 - 如果修改了 heirachy,那么我将不会收到有关该更改的通知,并且我只会在下次枚举该集合时看到该更改。想象一下,该集合将用作 WPF 列表视图的数据源。
  • 我明白了。这就是为什么我问你如何使用扁平列表... :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
相关资源
最近更新 更多