WPF:将网格所选元素与唯一的treenode关联 [英] WPF: Associating Grid selected element with unique treenode

查看:68
本文介绍了WPF:将网格所选元素与唯一的treenode关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a tree by parsing a string separated by (.)

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中,例如,我有以下数据:

In TestElement For example I have this data:

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,以便可以唯一地标识每个路径.

Here I am looping thru the parsed strings and assign them the unique Id. I am assigning ID to the last element in the path so that I can uniquely identify each path.

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

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

I have a grid with the following data:

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

在我的ViewModel中,这是如何在网格和treenode ID之间进行比较

In my ViewModel here is how am doing the comparison between the grid and treenode 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时,我想将其与ID号= 1的树节点(TestElement)关联. 现在,它仅将其与最后一个元素相关联.如何将其关联到整个路径?这样我就可以用一些颜色突出显示它

What I want to do is create a relationship in my WPF application. When I click the TestField with id=1 I want to associate it to my tree node(TestElement) with id number =1 Right now it is associating it to the last element only. How can I associate it to the whole path? so that I can Highlight it with some color.

新修改:

TestElementViewModel:

TestElementViewModel:

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:这是我所有模型视图的容器...

MainViewModel: This is a container of all my modelviews...

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

推荐答案

我可以想到两种方法:

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

1) Instead of having just an ID property for each node, have a Ids collection. This may use a substantial amount of memory when dealing with large numbers of nodes due to the extra collection being allocated for each node.

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属性在树上移动以将这些属性分配给祖先节点.

2) Keep only a single ID per node and let each node be aware of its parent. When you find the node that has the ID you're looking for, use the Parent property to walk up the tree to assign the properties to ancestor nodes.

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

这篇关于WPF:将网格所选元素与唯一的treenode关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆