C#ツリーノードを再帰的に巡回して格納

4456 ワード

前にTreeViewコントロール生成ツリーを紹介しましたが、TreeViewコントロールはC#開発で広く使われています.ここでは私が実際に使った方法をまとめてみます.
1.TreeViewノードをクリックし、そのノードのすべてのサブノードをストレージに移動します.
たとえば、親ノードの下にあるすべてのサブノードを知りたいです.
まず、ノードを格納するListを定義します.
List<string> m_SubNode = new List<string>();
ノードを再帰的に巡回し、サブノードを格納する
private void RecursionSaveNode(TreeNode tn)
{        
     foreach (TreeNode tnSub in tn.Nodes)
     {
           m_SubNode.Add(tnSub.Text); // Text, tnSub.ToString(), , "TreeNode: ", TreeNode: 
           RecursionSaveNode(tnSub);  
     }
}
実際の呼び出し中
m_SubNode.Clear();
m_SubNode.Add(treeView.SelectedNode.Text); // , , 。
RecursionSaveNode(treeView.SelectedNode);
2.
指定したノードを格納します.TreeViewにチェックボックスが付いている場合は、TreeViewノードがチェックされているかどうかを確認します.
親ノードがチェックされている場合、すべての子ノードがチェックされます.親ノードがチェックされていない場合、すべての子ノードがチェックされていません.子ノードのチェックは親ノードに影響しませんが、すべての子ノードがチェックされていない場合、親ノードはチェックされません.子ノードがチェックされている場合、親ノードもチェックされます.
(1)親ノードと子ノードの論理判断
サブノードの状態を設定します.サブノードの状態を設定するのは簡単で、サブノードの状態を親ノードと同じにすればいいだけで、すべてのサブノードを再帰的に巡回して設定すればいい.
 private void setchild(TreeNode node)
 {
        foreach (TreeNode child in node.Nodes)
        {
                child.Checked = node.Checked; // 
                setchild(child);
        }         
 }
親ノードのステータスの設定
親ノードの状態を設定するのは少し面倒ですが、まず親ノードが存在するかどうかを判断する必要があります.存在しない場合は戻ります.存在する場合は判断し、親ノードのすべての子ノードがチェックを解除すると、親ノードはチェックを解除し、子ノードがチェックされている場合は親ノードはチェックを解除します.
private void setparent(TreeNode node)
{
            if (node.Parent != null)
            {
                if (node.Checked)
                {
                    node.Parent.Checked = node.Checked;
                    return;
                }
                else
                {   // 
                    // , 
                    foreach (TreeNode brother in node.Parent.Nodes) // 
                    {
                        if (brother.Checked == false)
                            continue;
                        else
                            return;
                    }
                    node.Parent.Checked = false;
                }
            }
}

実際の呼び出し、実際の呼び出しの過程で親子ノードの判断はtreeView_に書かれています.AfterCheckイベントでは、TreeViewのロード中にツリーノードがチェックされている場合、TreeViewの初期化時にこのイベントがトリガーされます.ここでは、ウィンドウのロードをブロックするときにこのイベントをトリガーする必要があります.
private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
{
            if (e.Action!=TreeViewAction.Unknown) // TreeView , TreeView 
            {
                setchild(e.Node);
                setparent(e.Node);
            }               
}
ここでは、最初からすべてのサブノードをチェックしなければならないと聞かれるかもしれませんが、どうすればいいですか?ここで私は単独で関数を書いて、初期化してすべてのノードをチェックして、もし
treeView_AfterCheckは初期化して、とても乱れているように見えて、私は初期化とチェックの判断を分けます.
private void InitTreeView(TreeNode tn)
{
            foreach (TreeNode tnSub in tn.Nodes)
            {
                tnSub.Checked = true;
                InitTreeView(tnSub);

            }
}
実際に呼び出す過程で、最初のノードを初期化し、この関数を呼び出せばよい.
treeView.Nodes[0].Checked = true;
InitTreeView(treeView1.Nodes[0]);
(2)選択されていない(選択されている)ノードを格納し、選択されていない(選択されている)ノードを判断する
選択されていないノードを判断し、1の例にのみ判断を加えればよい
private void RecursionSaveUnCheckNode(TreeNode tn)
{
            foreach (TreeNode tnSub in tn.Nodes)
            {
                if (tnSub.Checked == false)
                {
                    m_SubUncheckedNode.Add(tnSub.Text);
                    RecursionSaveUnCheckNode(tnSub);
                }

            }
 }
private void RecursionSaveCheckNode(TreeNode tn)
{
            foreach (TreeNode tnSub in tn.Nodes)
            {
                if (tnSub.Checked == true)
                {
                    m_SubCheckedNode.Add(tnSub.Text);
                    RecursionSaveCheckNode(tnSub);
                }
            }
}

実際の呼び出し中
m_SubUnCheckedNode.Clear();
RecursionSaveUnCheckNode(treeView.SelectedNode);

m_SubCheckedNode.Clear();
RecursionSaveCheckNode(treeView.SelectedNode);

3.ノードへのアクセス
TreeViewのノードは配列によってアクセスすることができ、例えばルートノードにアクセスする場合はtreeViewと書くことができる.Nodes[0]、またはルートノードの下の3番目のノードにアクセスします.Nodes[0].Nodes[2]ノードXXX.NodesはノードXXXの子ノードのあるノードの親ノードtreeViewを表す.Nodes[XXX].Parent