C# 如何访问树结构中的父对象

C# 如何访问树结构中的父对象,c#,data-structures,uwp,C#,Data Structures,Uwp,我使用的是MVVM,它工作得很好,除了一件事,访问父模型对象 目标是直接访问任何模型对象的父对象,但我找不到一种支持方法来做到这一点 例如: 祖父母 ---父母 ------孩子们 -----孙辈 我提到了一个孩子,但我必须检查孩子的一些属性,也许还有父母 目前,代码正在所有更高级别的对象中运行,直到父对象的子对象的孙子对象与我的孙子对象成功匹配,然后才可以检查属性。 但就智能代码和效率而言,这是一种令人厌恶的行为,不管它是如何完成的,我不想为了一场幸运的比赛而浏览我所有的数据。这是当前的iIm

我使用的是MVVM,它工作得很好,除了一件事,访问父模型对象

目标是直接访问任何模型对象的父对象,但我找不到一种支持方法来做到这一点

例如:

祖父母

---父母

------孩子们

-----孙辈

我提到了一个孩子,但我必须检查孩子的一些属性,也许还有父母

目前,代码正在所有更高级别的对象中运行,直到父对象的子对象的孙子对象与我的孙子对象成功匹配,然后才可以检查属性。 但就智能代码和效率而言,这是一种令人厌恶的行为,不管它是如何完成的,我不想为了一场幸运的比赛而浏览我所有的数据。这是当前的iImplementation,其他一些部分是使用LINQ完成的

    var someChild = calledChild;
    foreach (Grandparent gParent in mainViewModel.SelectedEnvironment.GrandParents)
    {
        foreach (Parent parent in gParent.Parents)
        {
            foreach (Child child in parent.Children)
            {
                if (child.A == calledChild.A)
                {
                     // Match
                     System.Diagnostics.Debug.WriteLine("CalledChilds grandparent is " + gParent.Name);
                }
            }
        }
    }
模型在类中设置,定义如下:

public class Parent : ObservableObject
{
    public const string NamePropertyName = "Name";
    private string _name;

    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            if (_name == value)
            {
                return;
            }
            _name = value;
            RaisePropertyChanged(NamePropertyName);
        }
    }

    public const string ChildrenPropertyName = "Children";
    private ObservableCollection<Child> _children;

    public ObservableCollection<Child> Children
    {
        get
        {
            return _children;
        }
        set
        {
            if (_children == value)
            {
                return;
            }
            _children = value;
            RaisePropertyChanged(ChildrenPropertyName);
        }
    }
}
公共类父对象:ObserveObject
{
public const string NamePropertyName=“Name”;
私有字符串\u名称;
公共字符串名
{
收到
{
返回_name;
}
设置
{
如果(_name==值)
{
回来
}
_名称=值;
RaisePropertyChanged(NamePropertyName);
}
}
public const string ChildrenPropertyName=“Children”;
私人可观察收集儿童;
公众观察收集儿童
{
收到
{
返回儿童;
}
设置
{
if(_children==值)
{
回来
}
_儿童=价值;
RaisePropertyChanged(ChildrenPropertyName);
}
}
}
模型保存在json文件中,并解析回模型的根对象类型以供使用

我不能仅仅将一个新的引用“Parent”添加到“Child”对象中,因为由于这个概念的限制,它最终会进入一个循环

如果能得到参考资料而不是整个模型分支的副本,那就太好了

是否有直接访问父对象的方法


谢谢大家!

最简单的方法是在子节点中存储对父节点的直接引用:

public class ParentNode
{
    private ObservableCollection<ChildNode> _children;
    public ParentNode()
    {
        _children = new ObservableCollection<ChildNode>();
        Children = new ReadOnlyObservableCollection<ChildNode>(_children);
    }
    public ReadOnlyObservableCollection<ChildNode> Children { get; }

    public void AddChild(ChildNode item)
    {
        if (item.Parent != null) throw new InvalidOperationException("Item is already added to another node");
        item.Parent = this;
        _children.Add(item);
    }
    public void RemoveChild(ChildNode item)
    {
        if (item.Parent != this) throw new InvalidOperationException("Item is not direct child of this node");
        item.Parent = null;
        _children.Remove(item);
    }
}

public class ChildNode
{
    public ParentNode Parent { get; internal set; }
}
公共类ParentNode
{
私人可观察收集儿童;
公共ParentNode()
{
_children=新的ObservableCollection();
Children=新的只读可观察集合(_Children);
}
public ReadOnlyObservableCollection子项{get;}
public void AddChild(ChildNode项)
{
如果(item.Parent!=null)抛出新的InvalidOperationException(“项已添加到另一个节点”);
item.Parent=此项;
_添加(项目);
}
public void RemoveChild(子节点项)
{
如果(item.Parent!=this)抛出新的InvalidOperationException(“item不是此节点的直接子节点”);
item.Parent=null;
_儿童。移除(项目);
}
}
公共类子节点
{
公共ParentNode父节点{get;internal set;}
}
只是要小心,因为这引入了循环引用-父引用子引用,反之亦然。这有点违反了DRY原则,因为树的形状定义了两次,很容易失去同步(例如,将
ChildNode.Parent
属性设置为实际父级以外的其他属性)


有很多方法可以解决这个问题,但我认为您可以从这个开始。

这不是真正的MVVM问题。这是使用hirachical结构时的一个普遍问题。您可以在每个子对象中添加对父对象的引用。如果这样做,则可以轻松地从父级访问属性。例如
GetParent().GetParent().property
当您必须从中的父级访问属性时,请提供一些示例代码,为您的问题提供更多详细信息欢迎!您的问题本质上是一组要求。有代码显示吗?