对象层次结构中的层次更改通知
Hierarchical change notifications in an object hierarchy
我在 C# 库中有三种对象的递归层次结构。我们称它们为 Boxes、Nuts 和 Bolts。 Boxes 可以包含其他 Boxes,或 Nuts 和 Bolts . 螺母和螺栓显然不能包含任何东西。
假设每个 Box 都有 ObservableCollections of Box, Nut ,以及 螺栓。每个 Nut 和 Bolt 实现 INotifyPropertyChanged.
是否有公认的最佳实践来传播对可观察集合的更改通知,或者 属性 对任何 Nut 或 Bolt[= 的更改49=] 到一个对象,该对象持有对最顶层 Box 的引用?或者您会推荐任何特定的设计模式?
编辑:为了给这个问题一些背景,我领导 Chemistry for Word project. You can see the component that display structures in real time on the left.
现在,不管你信不信,这目前通过数据绑定绘制 一切。 LHS 上显示的每个分子都是一个 ItemsControl。 (是的,我 是 将 WPF 与 MVVM 结合使用!)事实证明,对于长期解决方案而言,这会产生过多的开销并且缺乏灵活性。所以我又回到直接生成 DrawingVisuals。这种方法允许更精细的控制。
Boxes、Nuts 和 Bolts 在我原来的例子中是 Molecules、原子和键。如果添加、删除或更改了其中任何一个,则显示器必须知道它才能更新。因为我已经实现了数据绑定的接口和对象,所以我想利用我已有的代码。
你为什么不在更改通知中调用父级。类似于以下伪代码:
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);
}
}
如果您封装了 ObservableCollection
的具体细节并且只制作了 ReadOnlyObservableCollection
public,您可以制作一个 Add(Nut nut)
方法(另一个用于螺栓)注册到添加的 Nut 的 NotifyPropertyChanged
事件。
这样,当 child 的 属性 发生变化时,您会在 Box
中知道并采取行动。
我有一个类似的模型,可以快速访问有向无环图中的上游 Node
实例。 Node
对其直接父级有弱引用。 Node
有一个 属性 来获取 Root...试图 return 其父级的 Root。如果没有父节点,则该节点是根节点。根性完全基于遏制。请注意,父节点不是集合...因为有时子节点甚至不在集合中。或多或少像...
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...
}
}
编辑:
关于 WeakReferences...我们的图表可以拥有的一件事是对其他图表中节点的引用。我们有一个节点解析器服务,可以获取其他节点。这些外观引用由标识值(GUID
或 Long
)和关联的弱引用表示。这样,我们可以根据需要加载指定的节点,但不会超过必要的时间。解析器维护以这种方式解析的节点的 LRU 缓存。
如果这样一个已解析的引用需要解析它自己的父节点,则存在一个类似的机制来允许从属节点解析它的父节点。甚至一个节点收集的子节点也可以通过解析器服务进行延迟加载(尽管有注释会告知我们的框架何时延迟加载以及何时不延迟加载)。
因此,弱引用有助于所有这些偶然解决的场景。呃...更准确地说,它们帮助我们在这种情况下不会搞砸垃圾收集。
在某些分析场景中,我们将有数十万个节点进出。我可以想象化学建模中的类似动态。
我在 C# 库中有三种对象的递归层次结构。我们称它们为 Boxes、Nuts 和 Bolts。 Boxes 可以包含其他 Boxes,或 Nuts 和 Bolts . 螺母和螺栓显然不能包含任何东西。
假设每个 Box 都有 ObservableCollections of Box, Nut ,以及 螺栓。每个 Nut 和 Bolt 实现 INotifyPropertyChanged.
是否有公认的最佳实践来传播对可观察集合的更改通知,或者 属性 对任何 Nut 或 Bolt[= 的更改49=] 到一个对象,该对象持有对最顶层 Box 的引用?或者您会推荐任何特定的设计模式?
编辑:为了给这个问题一些背景,我领导 Chemistry for Word project. You can see the component that display structures in real time on the left.
你为什么不在更改通知中调用父级。类似于以下伪代码:
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);
}
}
如果您封装了 ObservableCollection
的具体细节并且只制作了 ReadOnlyObservableCollection
public,您可以制作一个 Add(Nut nut)
方法(另一个用于螺栓)注册到添加的 Nut 的 NotifyPropertyChanged
事件。
这样,当 child 的 属性 发生变化时,您会在 Box
中知道并采取行动。
我有一个类似的模型,可以快速访问有向无环图中的上游 Node
实例。 Node
对其直接父级有弱引用。 Node
有一个 属性 来获取 Root...试图 return 其父级的 Root。如果没有父节点,则该节点是根节点。根性完全基于遏制。请注意,父节点不是集合...因为有时子节点甚至不在集合中。或多或少像...
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...
}
}
编辑:
关于 WeakReferences...我们的图表可以拥有的一件事是对其他图表中节点的引用。我们有一个节点解析器服务,可以获取其他节点。这些外观引用由标识值(GUID
或 Long
)和关联的弱引用表示。这样,我们可以根据需要加载指定的节点,但不会超过必要的时间。解析器维护以这种方式解析的节点的 LRU 缓存。
如果这样一个已解析的引用需要解析它自己的父节点,则存在一个类似的机制来允许从属节点解析它的父节点。甚至一个节点收集的子节点也可以通过解析器服务进行延迟加载(尽管有注释会告知我们的框架何时延迟加载以及何时不延迟加载)。
因此,弱引用有助于所有这些偶然解决的场景。呃...更准确地说,它们帮助我们在这种情况下不会搞砸垃圾收集。
在某些分析场景中,我们将有数十万个节点进出。我可以想象化学建模中的类似动态。