C# 对象层次结构中的层次结构更改通知

C# 对象层次结构中的层次结构更改通知,c#,.net,wpf,graphics,drawingvisual,C#,.net,Wpf,Graphics,Drawingvisual,我在C库中有三种对象的递归层次结构。让我们称之为盒子、螺母和螺栓。盒子可以包含其他盒子,或螺母和螺栓。螺母和螺栓显然不能包含任何东西 让我们假设每个盒子都有可以观察到的盒子、螺母和螺栓的集合。每个螺母和螺栓执行INotifyProperty更改 是否有公认的最佳实践,用于将可观察集合的更改通知或任何螺母或螺栓上的属性更改传播到包含最顶端框引用的对象?或者你会推荐什么特别的设计模式 编辑:为了给这个问题提供一些背景知识,我负责这个项目。您可以在左侧看到实时显示结构的构件。 现在,信不信由你,目前这

我在C库中有三种对象的递归层次结构。让我们称之为盒子、螺母和螺栓。盒子可以包含其他盒子,或螺母和螺栓。螺母和螺栓显然不能包含任何东西

让我们假设每个盒子都有可以观察到的盒子、螺母和螺栓的集合。每个螺母和螺栓执行INotifyProperty更改

是否有公认的最佳实践,用于将可观察集合的更改通知或任何螺母或螺栓上的属性更改传播到包含最顶端框引用的对象?或者你会推荐什么特别的设计模式

编辑:为了给这个问题提供一些背景知识,我负责这个项目。您可以在左侧看到实时显示结构的构件。 现在,信不信由你,目前这一切都是通过数据绑定实现的。LHS上显示的每个分子都是ItemsControl。是的,我正在使用WPF和MVVM!事实证明,这会带来太多的管理费用,并且缺乏长期解决方案的灵活性。所以我又回到了直接生成绘图视觉效果。这种方法允许更精细的控制。
我最初的例子中的盒子、螺母和螺栓是分子、原子和键。如果添加、删除或更改了其中任何一项,则显示器必须了解该项信息,以便进行更新。因为我已经实现了数据绑定的接口和对象,所以我想利用我已有的代码。

为什么不在更改通知中调用父级呢。类似于以下伪代码:

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);
    }
}

为什么不在变更通知中给家长打电话呢。类似于以下伪代码:

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,则可以为注册到添加的螺母的NotifyPropertyChanged事件的螺栓创建AddNut-nut方法和另一个方法

这样,当子对象的属性发生更改时,您将在框中知道并采取措施。

如果封装了螺母和螺栓的ObservableCollection,并且只公开ReadOnlyObservableCollection,则可以为注册到添加的螺母的NotifyPropertyChanged事件的螺栓创建一个AddNut-nut方法和另一个螺栓方法


这样,当子对象的属性发生更改时,您将在框中知道并采取措施。

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

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...
  }
}
编辑:

关于weakreference…我们的图可以拥有的一个功能是引用其他图中的节点。我们有一个节点解析器服务,它将获取其他节点。这些向外看的引用由标识值、GUID或长引用和关联的弱引用表示。通过这种方式,我们可以根据需要加载指定的节点,但不会将其保留超过需要的时间。解析程序维护以这种方式解析的节点的LRU缓存

如果此类已解析的引用需要解析其自己的父级,则存在类似的机制以允许从属节点解析其父级。即使节点收集的子节点也可能通过解析器服务延迟加载,尽管有注释通知我们的框架何时延迟加载和何时不延迟加载

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


在一些分析场景中,我们将有成千上万的节点进出。我可以想象化学建模中的类似动态。

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

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...
  }
}
编辑:

关于weakreference…我们的图可以拥有的一个功能是引用其他图中的节点。我们有一个节点解析器服务,它将获取其他节点。这些向外看的引用由标识值、GUID或长引用和关联的弱引用表示。通过这种方式,我们可以根据需要加载指定的节点,但不会将其保留超过需要的时间。解析程序维护以这种方式解析的节点的LRU缓存

如果这样一个已解析的引用需要解析它自己的父引用,可以使用类似的机制 存在以允许从属节点解析其父节点。即使节点收集的子节点也可能通过解析器服务延迟加载,尽管有注释通知我们的框架何时延迟加载和何时不延迟加载

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



在一些分析场景中,我们将有成千上万的节点进出。我可以想象化学建模中的类似动力学。

为什么会有这个问题?实际问题是什么?如果您绑定到Nut,则不需要将更改一直冒泡到Box或observeCollection。您不需要仅仅为了更新绑定到Nut的UI元素而重新加载和绘制所有框。您是否直接修改UI而不是使用数据绑定?或者您是在对Nut使用单向绑定?@dymanoid InotifyProperty更改和ObservableCollection主要用于WFP、XAML和UWP。Winforms依赖于事件,而ASP.NET不关心服务器端事件。即使问题不是关于XAML相关技术之一,但实际的问题是什么?问题是什么?如何找到父母?INotifyPropertyChanged是完美的选择,家长可以使用它。但ObservableCollection不会监视其子对象。这是您的角色,或者如果您正在谈论wpf,那么绑定将起到什么作用。根据任务,你可以考虑另一种设计,当每个孩子都得到它的父母的参考,并且能够在改变时调用父母的方法。实际的问题是,我展示了包含原子、键和其他分子的分子图。我尝试了数据绑定,并让它在生产中运行了一段时间。管理费用和缺乏灵活性意味着我不得不回到绘图板,直接在画布上绘制相应的形状。所以我已经在每个对象上更改了InotifyProperty。我想通知top levelm对象对数据模型的所有更改,这样我就可以相应地更新,让每个容器的内容也成为它所包含的内容的工厂……然后让包含的内容对它们的容器有弱引用。然后,任何叶节点或分支节点都有一个闪电般快速向上传播的通信通道…具有空安全调用:parent?.something发生在原始节点上;为什么要问这个问题?实际问题是什么?如果您绑定到Nut,则不需要将更改一直冒泡到Box或observeCollection。您不需要仅仅为了更新绑定到Nut的UI元素而重新加载和绘制所有框。您是否直接修改UI而不是使用数据绑定?或者您是在对Nut使用单向绑定?@dymanoid InotifyProperty更改和ObservableCollection主要用于WFP、XAML和UWP。Winforms依赖于事件,而ASP.NET不关心服务器端事件。即使问题不是关于XAML相关技术之一,但实际的问题是什么?问题是什么?如何找到父母?INotifyPropertyChanged是完美的选择,家长可以使用它。但ObservableCollection不会监视其子对象。这是您的角色,或者如果您正在谈论wpf,那么绑定将起到什么作用。根据任务,你可以考虑另一种设计,当每个孩子都得到它的父母的参考,并且能够在改变时调用父母的方法。实际的问题是,我展示了包含原子、键和其他分子的分子图。我尝试了数据绑定,并让它在生产中运行了一段时间。管理费用和缺乏灵活性意味着我不得不回到绘图板,直接在画布上绘制相应的形状。所以我已经在每个对象上更改了InotifyProperty。我想通知top levelm对象对数据模型的所有更改,这样我就可以相应地更新,让每个容器的内容也成为它所包含的内容的工厂……然后让包含的内容对它们的容器有弱引用。然后,任何叶节点或分支节点都有一个闪电般快速向上传播的通信通道…具有空安全调用:parent?.something发生在原始节点上;ReadOnlyObservableCollection是我的新产品,谢谢。我会进一步调查。ReadOnlyObservableCollection是我的新产品,谢谢。我会进一步调查的。很多人都提到了弱引用。与强引用相比,使用这些引用有哪些优点?弱引用在A引用B和B引用C和C引用A的情况下非常有用。这可能会阻塞垃圾收集器。如果从下到下有强引用,但从上到下有弱引用,则不必做任何奇怪的事情来促进垃圾收集。当你从树上分离一个节点分支时,它会被干净地收集起来。尽管如此,如果整个树超出范围,我相信GC仍然可以解析所有这些引用并收集所有内容。这可能是一个错误
在其他决定性的地面军事系统中,比如在斯威夫特,有更大的交易…所以这可能是杀伤力过大。仍然值得调查。原则上,这些不是大对象树。但它们可能会很混乱。感谢您的有用评论。仔细想想,我可以看到某些场景,其中我们需要引用其他图中的节点。所以weakreference更为适用。相当多的人提到了弱引用。与强引用相比,使用这些引用有哪些优点?弱引用在A引用B和B引用C和C引用A的情况下非常有用。这可能会阻塞垃圾收集器。如果从下到下有强引用,但从上到下有弱引用,则不必做任何奇怪的事情来促进垃圾收集。当你从树上分离一个节点分支时,它会被干净地收集起来。尽管如此,如果整个树超出范围,我相信GC仍然可以解析所有这些引用并收集所有内容。这可能是一个更大的交易,在其他确定性地面军事系统,如在斯威夫特…所以它可能是在这里杀伤力过大。仍然值得调查。原则上,这些不是大对象树。但它们可能会很混乱。感谢您的有用评论。仔细想想,我可以看到某些场景,其中我们需要引用其他图中的节点。因此,weakreference更加适用。