1

我在 C# 库中有三种对象的递归层次结构。我们称它们为BoxesNuts and BoltsBoxes可以包含其他BoxesNuts and BoltsNuts and Bolts显然不能包含任何东西。

假设每个Box都有BoxNutBoltObservableCollections。每个Nut and Bolt实现INotifyPropertyChanged

是否有公认的最佳实践将可观察集合的更改通知或任何NutBolt上的属性更改传播到包含对最顶层Box的引用的对象?或者您会推荐任何特定的设计模式?

编辑:为了给这个问题提供一些背景信息,我领导了Chemistry for Word项目。您可以在左侧看到实时显示结构的组件。Chem4Word 导航器 现在,不管你信不信,这目前通过数据绑定来绘制所有内容。LHS 上显示的每个分子都是一个 ItemsControl。(是的,我正在将 WPF 与 MVVM 一起使用!)事实证明,这对于长期解决方案来说开销太大且缺乏灵活性。所以我又回到了直接生成DrawingVisuals。这种方法允许更精细的控制。我最初的例子中的盒子螺母螺栓是分子原子债券。如果添加、删除或更改其中任何一个,则显示器必须知道它,以便它可以更新。因为我已经实现了数据绑定的接口和对象,所以我想利用我已经拥有的代码。

4

3 回答 3

2

我有一个类似的模型,可以快速访问有Node向无环图中的上游实例。ANode对其直接父级的引用很弱。Node有一个属性来获取根...试图返回其父级的根。如果没有父节点,则该节点是根节点。根性完全基于遏制。请注意,父节点不是集合......因为有时子节点甚至不在集合中。或多或少像...

public abstract class Node
{
  WeakReference<Node> parent;

  public Node Root
  {
    get { return Parent?.Root ?? this; }
  }

  public Node Parent
  {
    get
    {
      if ( parent != null )
      {
        if ( parent.TryGetTarget( out Node parentNode ) )
        {
          return parentNode;
        }
      }
      return this;
    }
    internal set { /*...*/ } //--> if you're brave...
  }
}

编辑

关于弱引用......我们的图表可以拥有的东西之一是对其他图表中的节点的引用。我们有一个节点解析器服务,它将获取那些其他节点。这些外向引用由标识值(aGUID或 a Long)和关联的弱引用表示。这样,我们可以根据需要加载指定的节点,但不会将其保留超过必要的时间。解析器维护以这种方式解析的节点的 LRU 缓存。

如果这样的已解析引用需要解析其自己的父节点,则存在类似的机制以允许依赖节点解析其父节点。甚至一个节点收集的子节点也可能通过解析器服务延迟加载(尽管有一些注释会通知我们的框架何时延迟加载,何时不延迟加载)。

因此,弱引用有助于所有这些偶然解决的场景。呃……更准确地说,它们帮助我们在这种情况下不会搞砸垃圾收集。

在某些分析场景中,我们将有数十万个节点进出。我可以想象化学建模中的类似动态。

于 2019-01-11T16:17:15.223 回答
1

您为什么不在更改通知中致电父母。类似于以下伪代码:

Bolt()
{
    NotifyPropertyChanged(property)
    {
         PropertyChanged(this, property);
    }

    ChildNutPropertyChanged(Nut child, property)
    {
         PropertyChanged(this, child + property);
    }
}


Nut(Bolt parentBolt)
{ 
    parent = parentBolt;

    NotifyPropertyChanged(property)
    {
         PropertyChanged(this, property);
         parent.NotifyPropertyChanged(this, property);
    }
}
于 2019-01-10T15:07:41.777 回答
1

如果你封装你ObservableCollection的 Nuts 和 Bolts 并且只ReadOnlyObservableCollection公开,你可以创建一个注册到添加的 Nut事件的Add(Nut nut)方法(以及另一个用于 bolts 的方法) 。NotifyPropertyChanged

这样,您将知道Box孩子的属性何时发生变化并采取行动。

于 2019-01-10T15:12:29.117 回答