3

まず、オールマイティなコードがあります。

List nodes = new List();
TreeNode Temp = new TreeNode();

TreeNodeCollection nodeList = treeViewTab4DirectoryTree.Nodes;

while (nodeList.Count != 0)
{
    Temp = nodeList[0];

    while (Temp.FirstNode != null)
    {
        Temp = Temp.FirstNode;
    }

    if (!nodes.Contains(Temp.FullPath))
    {
        nodes.Add(Temp.Text);
    }

    nodeList.Remove(Temp);
}

ここでの問題: ツリー内のすべてのノードからのテキストを含むリストを作成する目的で上記のコードを作成しました。それは完璧に機能します。私が抱えている問題は、変数からノードを削除すると、実際のリストからも削除されることです。問題は、実際のリストをいじらずにノードを操作できるように、ノードのリストのコピーを作成するにはどうすればよいかということです。参照するだけでなく、コピーを作成するにはどうすればよいですか? どんな助けでも大歓迎です!

4

2 に答える 2

3

「nodeList」は、そのコピーではなく、treeViewTab4DirectoryTree.Nodes への参照であるため、問題が発生します。

解決策は、.Copy()、.Clone()、.ToArray() メソッドを探す必要があるため、使用している TreeNodeCollection のタイプ (WinForms、ASP.net、その他の何か?) に完全に依存します。または、既存のコレクションへの参照ではなく、コレクションの内容のコピーを取得するのと同様です。

たとえば、asp.net を使用しているためSystem.Web.UI.WebControls.TreeNodeCollectionを使用している場合、次のような方法で .CopyTo メソッドを使用できます。

TreeNode[] x = null;
treeViewTab4DirectoryTree.Nodes.CopyTo(x, 0);
于 2010-02-24T13:50:47.330 に答える
2

スタックベースのアプローチを示すように更新されました:

List<String> result = new List<String>();
Stack<IEnumerator> nodeColls = new Stack<IEnumerator>();
IEnumerator nodes = treeViewTab4DirectoryTree.Nodes.GetEnumerator();

nodeColls.Push(null);

while (nodes != null)
{
    while (nodes.MoveNext())
    {
        result.add(nodes.Current.FullPath);
        if (nodes.Current.FirstNode != null)
        {
            nodeColls.Push(nodes);
            nodes = nodes.Current.Nodes.GetEnumerator();
        }
    }

    nodes = nodeColls.Pop();
}

以下のコードは、コメントで述べたようには機能しません。これは、ツリー全体を走査するのではなく、各最上位ブランチの最初のリーフ ノードのみを取得するためです。

私は実際には、元のコード (問題の) もそうしていると思っていました。なぜなら、Remove は、その下の最初のリーフ ノードを見つけた後、トップレベル ノードを実際に削除すると思ったからです。代わりに、最上位ノードのコレクションからリーフ ノードを削除しようとし、見つからない場合は無視します。

元の投稿、機能しないコード

まず、なぜリストからアイテムを削除する必要があるのですか?

List<string> nodes = new List<string>();

foreach (TreeNode tn in treeViewTab4DirectoryTree.Nodes)
{
    TreeNode temp = tn;

    while (Temp.FirstNode != null)
    {
        Temp = Temp.FirstNode;
    }

    if (!nodes.Contains(Temp.FullPath))
    {
        nodes.Add(Temp.Text);
    }
}

具体的な質問に答えるには、Nodes コレクションが IEnumerable を実装すると仮定して、次を使用します。

List<TreeNode> nodeList = new List<TreeNode>(treeViewTab4DirectoryTree.Nodes);

while ループに固執することにした場合は、変更することでインスタンスを保存できます。

TreeNode Temp = new TreeNode();

TreeNode Temp = null;

...少なくとも表示したコードの一部では、作成したオブジェクトを実際に使用することはありません。

于 2010-02-24T14:01:39.777 に答える