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 をクリックすると、ID 番号 = 1 のツリー ノード (TestElement) に関連付けたいと思います。現在、最後の要素のみに関連付けられています。どうすればそれをパス全体に関連付けることができますか? 色でハイライトできるようにします。

新しい編集:

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: これはすべてのモデルビューのコンテナーです...

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

これを行うには、次の 2 つの方法が考えられます。

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) ノードごとに 1 つの 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 に答える