0

我正在通过解析由 (.) 分隔的字符串来创建树

编辑:

public class TestElement{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Path { get; set; }
    public List<TestElement> Children { get; set; }
    public TestElement CurrentNode { get; set; }
    public TestElement Parent { get; set; }
}

在 TestElement 例如我有这个数据:

public List<TestElement> GetTreeNodes()
{
    var nodeElements = new List<TestElement>();
    AddNode(nodeElements, 1, "a.b.c.value");
    AddNode(nodeElements, 2, "a.c.f.g");

    return nodeElements;
}

解析:

private void AddNode(List<TestElement> nodes, int id, string path)
{
    AddNode(nodes, id, path.Split('.'));
}

在这里,我遍历解析的字符串并为它们分配唯一的 ID。我将 ID 分配给路径中的最后一个元素,以便我可以唯一标识每条路径。

private void AddNode(List<TestElement> nodes, int id, params string[] path)
{
    CurrentNode =null;

    foreach (var name in path)
    {
        var currentCollection = (CurrentNode != null ? CurrentNode.Children : nodes);
        var thisNode = currentCollection.FirstOrDefault(n => n.Name == name);
        if (thisNode == null)
        {
            thisNode = new TestElement { Name = name };
            currentCollection.Add(thisNode);
        }
        CurrentNode = thisNode;
    }
    if (CurrentNode != null)
        CurrentNode.Id = id;
}

我有一个包含以下数据的网格:

TestField.Add(new TestField(1, "ABCD",5, 4));
TestField.Add(new TestField(2, "EFGH", 9, 7));

在我的 ViewModel 中,这里是如何在网格和树节点 id 之间进行比较

public void SearchTree(int id, List<TestElement> nodes)
{
    foreach (var c in nodes)
    {
        if (c.id == id)
        {
            c.DisplayColor = Brushes.Violet; 
        }
        else
        {
            c.DisplayColor = Brushes.Black;
        }

        SearchTree(id, c.Children);
    }
}

我想要做的是在我的 WPF 应用程序中创建一个关系。当我单击 id=1 的 TestField 时,我想将它关联到我的树节点(TestElement),id 编号 =1 现在它只将它关联到最后一个元素。我怎样才能将它与整个路径相关联?这样我就可以用一些颜色突出显示它。

新编辑:

测试元素视图模型:

public TestElement Parent { get; set; }


public void HighlightNode(TestElementViewModel node)
{
    for (var n = node; n != null; n = n.Parent)
    {
        DisplayColor = Brushes.Violet;
    }
}

递归构建树:

public IEnumerable<TestElementViewModel> ToTreeViewModel(IEnumerable<TestElement>   treemodel)
{
    return treemodel.Select(item => new TestElementViewModel { Id = item.Id, Name = item.Name, Children = ToTreeViewModel(item.Children).ToList(), Parent=item.Parent });
}



public List<TestElementViewModel> GetRequestTreeNodesFromModel()
{
    return ToTreeViewModel(TreeModel.GetRequestTreeNodes()).ToList();
}

MainViewModel:这是我所有模型视图的容器......

public TestElementViewModel SearchTree(int id, List<TestElementViewModel> nodes)
{
    foreach (var c in nodes)
    {
        if (c.Id == id)
            return c;
        var n = SearchTree(id, c.Children);
        if (n != null)
            TestElementViewModelVModel.HighlightNode(n);
        return n;
    }
    return null;
}

private void HighlightNode(MessageElementViewModel node)
{
    for (var n = node; n != null; n = n.Parent)
    {
        n.DisplayColor = Brushes.Violet;
    }
}
4

1 回答 1

0

我可以想到两种方法来做到这一点:

1)不是每个节点只有一个 ID 属性,而是有一个 Ids 集合。由于为每个节点分配了额外的集合,因此在处理大量节点时,这可能会使用大量内存。

public class TestElement
{
    /*NOTE:*/ public HashSet<int> Ids { get { return _ids ?? (_ids = new HashSet<int>()); } }
    /*NOTE:*/ private HashSet<int> _ids;
    ...
}

private void AddNode(List<TestElement> nodes, int id, params string[] path)
{
    CurrentNode = null;

    foreach (var name in path)
    {
        var currentCollection = (CurrentNode != null ? CurrentNode.Children : nodes);
        var thisNode = currentCollection.FirstOrDefault(n => n.Name == name);
        if (thisNode == null)
        {
            thisNode = new TestElement { Name = name };
            currentCollection.Add(thisNode);
        }
        /*NOTE:*/ thisNode.Ids.Add(id);
        CurrentNode = thisNode;
    }
}

private void SearchTree(int id, List<TestElement> nodes)
{
    foreach (var c in nodes)
    {
        /*NOTE:*/ if (c.Ids.Contains(id))
        {
            c.DisplayColor = Brushes.Violet;
        }
        else
        {
            c.DisplayColor = Brushes.Black;
        }

        SearchTree(id, c.Children);
    }
}

2)每个节点只保留一个ID,并让每个节点都知道它的父节点。当您找到具有您要查找的 ID 的节点时,使用 Parent 属性向上遍历树以将属性分配给祖先节点。

public class TestElement
{
    /*NOTE:*/ public int ID { get; set; }
    /*NOTE:*/ public TestElement Parent { get; set; }
    ...
}

private void AddNode(List<TestElement> nodes, int id, params string[] path)
{
    CurrentNode = null;

    foreach (var name in path)
    {
        var currentCollection = (CurrentNode != null ? CurrentNode.Children : nodes);
        var thisNode = currentCollection.FirstOrDefault(n => n.Name == name);
        if (thisNode == null)
        {
            thisNode = new TestElement { Name = name, /*NOTE:*/ Parent = CurrentNode };
            currentCollection.Add(thisNode);
        }
        CurrentNode = thisNode;
    }
    if (CurrentNode != null)
        CurrentNode.Id = id;
}

private TestElement FindNode(int id, List<TestElement> nodes)
{
    foreach (var c in nodes)
    {
        if (c.ID == id)
            return c;
        var n = FindNode(id, c.Children);
        if (n != null)
            return n;
    }
    return null;
}

private void HighlightNode(TestElement node)
{
    for (var n = node; n != null; n = n.Parent)
        n.DisplayColor = Brushes.Violet;
}
于 2013-06-12T17:15:32.683 回答