ソフト関連Trial−No.103
        CheckBox付きTreeViewのTips紹介(C#)

トップページへ

 はじめに

ファイルバックアップソフト「CKBackup」 の制作において、TreeViewコントロール(以下、単にTreeViewと略)でCheckBox付きのものを初めて使用してみました。
TreeViewは階層構造の情報を表示するのに便利なコントロールですが、 通常のCheckBoxの無いTreeViewでは要素(以下、ノード)を1つしか選択をすることができません。
これをCheckBox付きにすると、複数のノードの選択が可能になります。
「CKBackup」の制作では、複数の除外フォルダーを選択、設定する際にこのコントロールが役に立ちました。
そこで、「CKBackup」の制作で習得したCheckBox付きTreeViewのコーディング方法の一例を、 このページでTipsとして紹介することにしました。
使用した開発言語は、Visual C# 2008(.NET Framework 2.0)です。

 CheckBox 付きTreeView とは


上図にCheckBox付きTreeViewの一例を示します。
通常は複数個のルートノードの下に、階層的に子ノードが配置されて構成されています。
各ノードのチェック欄をチェックすることにより、複数個のノードが選択された(チェックされた)状態を作ることができます。

 Tips紹介

この項では、以下の2つのTipsを紹介します。

@ ノードのチェック状態変更を全ての下位ノードに反映させる方法
「CKBackup」では、あるノードのチェック状態が変更された場合、その下位のノードが全て同じチェック状態になるように構成しました。
このようにするためのコードは、Microsoft社の下記サイトに紹介されています。
   http://msdn.microsoft.com/ja-jp/library/system.windows.forms.treeview.aftercheck(VS.80).aspx
「CKBackup」で使用したチェック状態変更に関するもう一つの設定は、あるノードがチェックされた状態にあるときに、 その下位のノードのチェックを外してはいけないというものです。
これらの構成、設定は次の[TreeView1_AfterCheck]イベント(プロシージャー)と[CheckChildNodes]メソッドで実施が可能になりました。


    // [TreeView1_AfterCheck] イベント
    private void TreeView1_AfterCheck(object sender, TreeViewEventArgs e)
    {
      if(e.Action != TreeViewAction.Unknown)
      {
        TreeNode active = e.Node;     // チェックされたノード

        // 上位ノードが Checked の場合、下位ノードのチェックを外せない
        try
        {
          TreeNode parent = active.Parent;
          if (parent != null)
          {
            if (parent.Checked && !active.Checked)
            {
              MessageBox.Show("上位と異なるCheck状態はとれません。");
              active.Checked = true;
              return;
            }
          }
        }
        catch
        { }
          
        // Check状態を全ての下位ノードに反映させる
        if (active.Nodes.Count > 0)
        {
          CheckChildNodes(active, active.Checked);
        }
      }
    }

    // [CheckChildNodes]メソッド
    private void CheckChildNodes(TreeNode vnode, bool vchecked)
    {
      foreach (TreeNode node in vnode.Nodes)
      {
        node.Checked = vchecked;
        if (node.Nodes.Count > 0)
        {
          CheckChildNodes(node, vchecked);
        }
      }
    }


A フルパスで指定されたノードを取得する方法
TreeViewの各ノードは、FullPathプロパティで参照することができます。
このFullPathプロパティは、ルートノードから対象ノードまでの全ノードのTextプロパティをPathSeparator(通常は「\」) で結合して得られます。
指定されたノードのFullPathプロパティは容易に取得できますが、 指定されたFullPathプロパティのノードを取得するのには工夫が必要です。
次の[GetNodeFromFullPath]メソッドは、FullPathプロパティからノードを取得するために作成したメソッドです。

    // [GetNodeFromFullPath]メソッド
    private TreeNode GetNodeFromFullPath(string vpath)
    {
      try
      {
        // ルートノード〜対象ノードまでの各ノードのTextを配列snode[]に取得する
        string[] snodes = vpath.Split('\\');   // vpath:フルパス
        
        TreeNode tn = new TreeNode();
        // 対象ノードのルートノードを取得する
        foreach (TreeNode node in TreeView1.Nodes)
        {
          if (node.Text == snodes[0])
          {
            tn = node;
            break;
          }
        }
        if (tn.Text.Length == 0)
        {
          MessageBox.Show("このルートノードは存在しません。");
          return null;
        }
        
        // 子ノードを取得する
        for (int i = 1; i < snodes.Length; i++)
        {
          tn = GetChildNode(tn, snodes[i]);
          if (tn == null)
          {
            MessageBox.Show("このノードは存在しません。");
            break;
          }
        }
        return tn;
      }
      catch
      { return null; }
    }
    
    // [GetChildNode]メソッド
    private TreeNode GetChildNode(TreeNode vnode, string vtext)
    {
      foreach (TreeNode node in vnode.Nodes)
      {
        if (node.Text == vtext) return node;
      }
      return null;
    }
    

 ご質問・ご意見・ご感想

ご質問、ご意見、ご感想、バグ等のご連絡は、 こちらへ

トップページへ