[C#] TreeViewで階層構造を実現する方法

C#でTreeViewを使用して階層構造を実現するには、Windows FormsアプリケーションでTreeViewコントロールを利用します。

まず、フォームにTreeViewコントロールを追加します。

次に、TreeNodeオブジェクトを作成し、これをTreeViewNodesコレクションに追加します。

TreeNodeは子ノードを持つことができ、これにより階層構造を表現します。

例えば、親ノードを作成し、そのNodesプロパティに子ノードを追加することで、ツリー状の構造を構築できます。

ノードのテキストやタグを設定することで、表示内容や関連データを管理できます。

この記事でわかること
  • C#のTreeViewで階層構造を構築
  • イベント処理の実装方法
  • TreeViewのカスタマイズ手法
  • 様々な応用例の紹介
  • 効率的なデータ保存方法

目次から探す

階層構造の構築

C#のTreeViewコントロールを使用すると、階層構造を簡単に表現できます。

ここでは、親ノードと子ノードの関係、ノードの追加方法、削除方法について詳しく解説します。

親ノードと子ノードの関係

TreeViewでは、ノードは親子関係を持つことができます。

親ノードは子ノードを持ち、子ノードはさらにその下に別の子ノードを持つことができます。

このようにして、階層的なデータ構造を表現することが可能です。

ノードの追加方法

ノードを追加するには、TreeNodeクラスを使用します。

以下のサンプルコードでは、親ノードと子ノードを追加する方法を示します。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
        // 親ノードを作成
        TreeNode parentNode = new TreeNode("親ノード");
        
        // 子ノードを作成
        TreeNode childNode1 = new TreeNode("子ノード1");
        TreeNode childNode2 = new TreeNode("子ノード2");
        // 親ノードに子ノードを追加
        parentNode.Nodes.Add(childNode1);
        parentNode.Nodes.Add(childNode2);
        // TreeViewに親ノードを追加
        myTreeView.Nodes.Add(parentNode);
    }
}

このコードを実行すると、TreeViewに「親ノード」とその下に「子ノード1」と「子ノード2」が表示されます。

ノードの削除方法

ノードを削除するには、RemoveメソッドRemoveAtメソッドを使用します。

以下のサンプルコードでは、特定のノードを削除する方法を示します。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
        // ノードの削除
        if (myTreeView.Nodes.Count > 0)
        {
            // 最初のノードを削除
            myTreeView.Nodes.RemoveAt(0);
        }
    }
}

このコードを実行すると、TreeViewの最初のノードが削除されます。

ノードを削除する際は、削除したいノードが存在するかどうかを確認することが重要です。

TreeViewのイベント処理

TreeViewコントロールでは、ユーザーの操作に応じてさまざまなイベントを処理することができます。

ここでは、ノード選択イベント、ノードの展開と折りたたみイベント、ノードのドラッグ&ドロップについて解説します。

ノード選択イベント

ノードが選択されたときに発生するイベントは、AfterSelectイベントです。

このイベントを利用することで、選択されたノードに基づいて特定の処理を行うことができます。

以下のサンプルコードでは、ノードが選択されたときにそのノードのテキストを表示する方法を示します。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
        // ノード選択イベントを登録
        myTreeView.AfterSelect += MyTreeView_AfterSelect;
    }
    private void MyTreeView_AfterSelect(object sender, TreeViewEventArgs e)
    {
        // 選択されたノードのテキストを表示
        MessageBox.Show("選択されたノード: " + e.Node.Text);
    }
}

このコードを実行すると、ノードを選択するたびにそのノードのテキストがメッセージボックスに表示されます。

ノード展開と折りたたみイベント

ノードが展開または折りたたまれたときに発生するイベントは、AfterExpandおよびAfterCollapseイベントです。

これらのイベントを使用して、ノードの状態に応じた処理を行うことができます。

以下のサンプルコードでは、ノードが展開または折りたたまれたときにメッセージを表示します。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
        // ノード展開イベントを登録
        myTreeView.AfterExpand += MyTreeView_AfterExpand;
        // ノード折りたたみイベントを登録
        myTreeView.AfterCollapse += MyTreeView_AfterCollapse;
    }
    private void MyTreeView_AfterExpand(object sender, TreeViewEventArgs e)
    {
        MessageBox.Show("展開されたノード: " + e.Node.Text);
    }
    private void MyTreeView_AfterCollapse(object sender, TreeViewEventArgs e)
    {
        MessageBox.Show("折りたたまれたノード: " + e.Node.Text);
    }
}

このコードを実行すると、ノードを展開または折りたたむたびに、そのノードのテキストがメッセージボックスに表示されます。

ノードのドラッグ&ドロップ

TreeViewでは、ノードをドラッグ&ドロップすることも可能です。

これを実現するためには、ItemDragDragEnterDragDropイベントを使用します。

以下のサンプルコードでは、ノードをドラッグして別の位置にドロップする方法を示します。

partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
        // ドラッグ開始イベントを登録
        myTreeView.ItemDrag += MyTreeView_ItemDrag;
        // ドラッグエンターイベントを登録
        myTreeView.DragEnter += MyTreeView_DragEnter;
        // ドラッグドロップイベントを登録
        myTreeView.DragDrop += MyTreeView_DragDrop;
    }
    private void MyTreeView_ItemDrag(object sender, ItemDragEventArgs e)
    {
        // ドラッグを開始
        DoDragDrop(e.Item, DragDropEffects.Move);
    }
    private void MyTreeView_DragEnter(object sender, DragEventArgs e)
    {
        // ドラッグエンター時の処理
        if (e.Data.GetDataPresent(typeof(TreeNode)))
        {
            e.Effect = DragDropEffects.Move;
        }
    }
    private void MyTreeView_DragDrop(object sender, DragEventArgs e)
    {
        // ドロップ時の処理
        TreeNode targetNode = myTreeView.GetNodeAt(myTreeView.PointToClient(new Point(e.X, e.Y)));
        if (targetNode != null && e.Data.GetDataPresent(typeof(TreeNode)))
        {
            TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
            targetNode.Nodes.Add((TreeNode)draggedNode.Clone());
            draggedNode.Remove();
        }
    }
}

このコードを実行すると、ノードをドラッグして別のノードの下にドロップすることができ、ノードの位置を変更できます。

ドラッグ&ドロップの操作は、ユーザーにとって直感的なインターフェースを提供します。

完成したプログラム

ここでは、C#のWindowsフォームアプリケーションにおけるTreeViewの基本的な機能を実装した完成プログラムを示します。

このプログラムでは、ノードの追加、削除、選択、展開、折りたたみ、ドラッグ&ドロップの機能を持つTreeViewを作成します。

以下のサンプルコードは、すべての機能を統合したMyFormクラスの実装です。

using System;
using System.Drawing;
using System.Windows.Forms;
partial class MyForm : Form
{
    private TreeView myTreeView;
    private Button addButton;
    private Button removeButton;
    public MyForm()
    {
        InitializeComponent();
        InitializeTreeView();
        InitializeButtons();
    }
    private void InitializeTreeView()
    {
        myTreeView = new TreeView
        {
            Dock = DockStyle.Fill
        };
        // ドラッグ&ドロップイベントの登録
        myTreeView.ItemDrag += MyTreeView_ItemDrag;
        myTreeView.DragEnter += MyTreeView_DragEnter;
        myTreeView.DragDrop += MyTreeView_DragDrop;
        myTreeView.AfterSelect += MyTreeView_AfterSelect;
        myTreeView.AfterExpand += MyTreeView_AfterExpand;
        myTreeView.AfterCollapse += MyTreeView_AfterCollapse;
        this.Controls.Add(myTreeView);
    }
    private void InitializeButtons()
    {
        addButton = new Button
        {
            Text = "ノード追加",
            Dock = DockStyle.Top
        };
        addButton.Click += AddButton_Click;
        removeButton = new Button
        {
            Text = "ノード削除",
            Dock = DockStyle.Top
        };
        removeButton.Click += RemoveButton_Click;
        this.Controls.Add(removeButton);
        this.Controls.Add(addButton);
    }
    private void AddButton_Click(object sender, EventArgs e)
    {
        TreeNode newNode = new TreeNode("新しいノード");
        if (myTreeView.SelectedNode != null)
        {
            myTreeView.SelectedNode.Nodes.Add(newNode);
            myTreeView.SelectedNode.Expand();
        }
        else
        {
            myTreeView.Nodes.Add(newNode);
        }
    }
    private void RemoveButton_Click(object sender, EventArgs e)
    {
        if (myTreeView.SelectedNode != null)
        {
            myTreeView.Nodes.Remove(myTreeView.SelectedNode);
        }
    }
    private void MyTreeView_ItemDrag(object sender, ItemDragEventArgs e)
    {
        DoDragDrop(e.Item, DragDropEffects.Move);
    }
    private void MyTreeView_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(typeof(TreeNode)))
        {
            e.Effect = DragDropEffects.Move;
        }
    }
    private void MyTreeView_DragDrop(object sender, DragEventArgs e)
    {
        TreeNode targetNode = myTreeView.GetNodeAt(myTreeView.PointToClient(new Point(e.X, e.Y)));
        if (targetNode != null && e.Data.GetDataPresent(typeof(TreeNode)))
        {
            TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
            targetNode.Nodes.Add((TreeNode)draggedNode.Clone());
            draggedNode.Remove();
        }
    }
    private void MyTreeView_AfterSelect(object sender, TreeViewEventArgs e)
    {
        MessageBox.Show("選択されたノード: " + e.Node.Text);
    }
    private void MyTreeView_AfterExpand(object sender, TreeViewEventArgs e)
    {
        MessageBox.Show("展開されたノード: " + e.Node.Text);
    }
    private void MyTreeView_AfterCollapse(object sender, TreeViewEventArgs e)
    {
        MessageBox.Show("折りたたまれたノード: " + e.Node.Text);
    }
}

プログラムの説明

  • TreeViewの初期化: InitializeTreeViewメソッドでTreeViewを作成し、各種イベントを登録します。
  • ボタンの初期化: InitializeButtonsメソッドでノードの追加と削除を行うボタンを作成します。
  • ノードの追加: AddButton_Clickメソッドで、選択されたノードの下に新しいノードを追加します。
  • ノードの削除: RemoveButton_Clickメソッドで、選択されたノードを削除します。
  • イベント処理: ノードの選択、展開、折りたたみ、ドラッグ&ドロップに関するイベントを処理します。

このプログラムを実行すると、ユーザーはTreeViewを操作してノードを追加、削除、選択、展開、折りたたむことができ、直感的なインターフェースを体験できます。

TreeViewのカスタマイズ

TreeViewコントロールは、デフォルトのスタイルだけでなく、さまざまなカスタマイズが可能です。

ここでは、ノードのアイコン設定、テキストフォーマット、チェックボックス機能について解説します。

ノードのアイコン設定

ノードにアイコンを設定することで、視覚的に情報を伝えることができます。

アイコンはImageListを使用して管理します。

以下のサンプルコードでは、ノードにアイコンを設定する方法を示します。

using System;
using System.Drawing;
using System.Windows.Forms;
partial class MyForm : Form
{
    private TreeView myTreeView;
    private ImageList imageList;
    public MyForm()
    {
        InitializeComponent();
        InitializeImageList();
        InitializeTreeView();
    }
    private void InitializeImageList()
    {
        imageList = new ImageList();
        imageList.Images.Add("folder", Image.FromFile("folder.png")); // フォルダアイコン
        imageList.Images.Add("file", Image.FromFile("file.png"));     // ファイルアイコン
        myTreeView.ImageList = imageList; // TreeViewにImageListを設定
    }
    private void InitializeTreeView()
    {
        myTreeView = new TreeView
        {
            Dock = DockStyle.Fill
        };
        // ノードを作成しアイコンを設定
        TreeNode folderNode = new TreeNode("フォルダ", 0, 0); // フォルダアイコン
        TreeNode fileNode = new TreeNode("ファイル", 1, 1);   // ファイルアイコン;
        folderNode.Nodes.Add(fileNode);
        myTreeView.Nodes.Add(folderNode);
        this.Controls.Add(myTreeView);
    }
}

このコードを実行すると、TreeViewにフォルダとファイルのアイコンが表示されます。

アイコンはImageListに追加した画像を使用しています。

ノードのテキストフォーマット

ノードのテキストをカスタマイズすることで、より見やすくすることができます。

以下のサンプルコードでは、ノードのテキストを太字にする方法を示します。

private void InitializeTreeView()
{
    myTreeView = new TreeView
    {
        Dock = DockStyle.Fill
    };
    // ノードを作成
    TreeNode node = new TreeNode("カスタマイズされたノード");
    myTreeView.Nodes.Add(node);
    // ノードのテキストを太字にする
    node.NodeFont = new Font(myTreeView.Font, FontStyle.Bold);
    this.Controls.Add(myTreeView);
}

このコードを実行すると、ノードのテキストが太字で表示されます。

NodeFontプロパティを使用して、フォントスタイルを変更できます。

ノードのチェックボックス機能

TreeViewでは、ノードにチェックボックスを表示することも可能です。

これにより、ユーザーがノードの選択状態を視覚的に確認できるようになります。

以下のサンプルコードでは、チェックボックスを有効にする方法を示します。

private void InitializeTreeView()
{
    myTreeView = new TreeView
    {
        Dock = DockStyle.Fill,
        CheckBoxes = true // チェックボックスを有効にする
    };
    // ノードを作成
    TreeNode node1 = new TreeNode("チェックボックス付きノード1");
    TreeNode node2 = new TreeNode("チェックボックス付きノード2");
    myTreeView.Nodes.Add(node1);
    myTreeView.Nodes.Add(node2);
    this.Controls.Add(myTreeView);
}

このコードを実行すると、各ノードにチェックボックスが表示され、ユーザーはノードを選択することができます。

チェックボックスの状態は、Checkedプロパティを使用して取得または設定できます。

これらのカスタマイズを行うことで、TreeViewコントロールをより使いやすく、視覚的に魅力的なものにすることができます。

応用例

TreeViewコントロールは、さまざまなデータを階層的に表示するのに適しています。

ここでは、ファイルシステムの表示、組織図の作成、カテゴリツリーの実装についての応用例を紹介します。

ファイルシステムの表示

ファイルシステムをTreeViewで表示することで、ユーザーはフォルダやファイルの構造を視覚的に把握できます。

以下のサンプルコードでは、指定したディレクトリの内容をTreeViewに表示する方法を示します。

using System.IO;
using System.Windows.Forms;
partial class MyForm : Form
{
    private TreeView myTreeView;
    public MyForm()
    {
        InitializeComponent();
        InitializeTreeView();
        LoadFileSystem("C:\\"); // 表示するルートディレクトリ
    }
    private void InitializeTreeView()
    {
        myTreeView = new TreeView
        {
            Dock = DockStyle.Fill
        };
        this.Controls.Add(myTreeView);
    }
    private void LoadFileSystem(string path)
    {
        DirectoryInfo dirInfo = new DirectoryInfo(path);
        TreeNode rootNode = new TreeNode(dirInfo.Name) { Tag = dirInfo };
        myTreeView.Nodes.Add(rootNode);
        LoadDirectories(dirInfo.GetDirectories(), rootNode);
    }
    private void LoadDirectories(DirectoryInfo[] directories, TreeNode parentNode)
    {
        foreach (var dir in directories)
        {
            TreeNode node = new TreeNode(dir.Name) { Tag = dir };
            parentNode.Nodes.Add(node);
            LoadDirectories(dir.GetDirectories(), node); // 再帰的にサブディレクトリを追加
        }
    }
}

このコードを実行すると、指定したディレクトリのフォルダ構造がTreeViewに表示されます。

ユーザーはフォルダを展開して、内部のファイルやサブフォルダを確認できます。

組織図の作成

TreeViewを使用して組織図を作成することも可能です。

以下のサンプルコードでは、組織の階層構造をTreeViewに表示する方法を示します。

private void InitializeTreeView()
{
    myTreeView = new TreeView
    {
        Dock = DockStyle.Fill
    };
    // 組織の階層構造を作成
    TreeNode ceoNode = new TreeNode("CEO");
    TreeNode ctoNode = new TreeNode("CTO");
    TreeNode cfoNode = new TreeNode("CFO");
    TreeNode devNode = new TreeNode("開発部門");
    TreeNode hrNode = new TreeNode("人事部門");
    ceoNode.Nodes.Add(ctoNode);
    ceoNode.Nodes.Add(cfoNode);
    ctoNode.Nodes.Add(devNode);
    cfoNode.Nodes.Add(hrNode);
    myTreeView.Nodes.Add(ceoNode);
    this.Controls.Add(myTreeView);
}

このコードを実行すると、CEOをトップにした組織図がTreeViewに表示されます。

各ノードを展開することで、組織の階層を視覚的に確認できます。

カテゴリツリーの実装

TreeViewを使用して商品やサービスのカテゴリを表示することもできます。

以下のサンプルコードでは、カテゴリツリーを作成する方法を示します。

private void InitializeTreeView()
{
    myTreeView = new TreeView
    {
        Dock = DockStyle.Fill
    };
    // カテゴリツリーを作成
    TreeNode electronicsNode = new TreeNode("電子機器");
    TreeNode clothingNode = new TreeNode("衣料品");
    TreeNode booksNode = new TreeNode("書籍");
    electronicsNode.Nodes.Add(new TreeNode("スマートフォン"));
    electronicsNode.Nodes.Add(new TreeNode("ノートパソコン"));
    clothingNode.Nodes.Add(new TreeNode("シャツ"));
    clothingNode.Nodes.Add(new TreeNode("パンツ"));
    booksNode.Nodes.Add(new TreeNode("小説"));
    booksNode.Nodes.Add(new TreeNode("ビジネス書"));
    myTreeView.Nodes.Add(electronicsNode);
    myTreeView.Nodes.Add(clothingNode);
    myTreeView.Nodes.Add(booksNode);
    this.Controls.Add(myTreeView);
}

このコードを実行すると、商品カテゴリがTreeViewに表示され、各カテゴリを展開することで、さらに詳細な情報を確認できます。

これらの応用例を通じて、TreeViewコントロールの柔軟性と使いやすさを実感できるでしょう。

さまざまなデータを階層的に表示するために、TreeViewを活用してみてください。

よくある質問

TreeViewのパフォーマンスを向上させるには?

TreeViewのパフォーマンスを向上させるためには、以下の方法を検討できます。

  • 遅延読み込み: ノードを展開する際にのみ、その子ノードを読み込むようにします。

これにより、初期表示時の負荷を軽減できます。

  • VirtualModeの使用: 大量のデータを扱う場合、VirtualModeを使用して、必要なデータのみを表示することができます。
  • ノードの非表示: 不要なノードを非表示にすることで、表示するノード数を減らし、パフォーマンスを向上させます。

ノードの動的な追加はどう行う?

ノードを動的に追加するには、TreeNodeクラスを使用して新しいノードを作成し、親ノードに追加します。

以下の手順で行います。

  1. 新しいTreeNodeを作成します。
  2. 追加したい親ノードを取得します。
  3. 親ノードのNodesコレクションに新しいノードを追加します。
TreeNode newNode = new TreeNode("新しいノード");
myTreeView.SelectedNode.Nodes.Add(newNode);

TreeViewのデータを保存する方法は?

TreeViewのデータを保存する方法はいくつかありますが、一般的な方法は以下の通りです。

  • XMLファイルへの保存: ノードの情報をXML形式で保存し、後で読み込むことができます。

これにより、階層構造を保持したままデータを保存できます。

  • JSONファイルへの保存: JSON形式でデータを保存することも可能です。

特にWebアプリケーションとの連携が必要な場合に便利です。

  • データベースへの保存: SQLデータベースなどにノード情報を保存し、必要に応じて読み込むことができます。

これにより、大量のデータを効率的に管理できます。

例:XMLファイルへの保存

using System.Xml;
using System.IO;
private void SaveTreeViewToXml(string filePath)
{
    XmlDocument xmlDoc = new XmlDocument();
    XmlNode rootNode = xmlDoc.CreateElement("TreeViewData");
    xmlDoc.AppendChild(rootNode);
    SaveNodeToXml(myTreeView.Nodes, rootNode, xmlDoc);
    xmlDoc.Save(filePath);
}
private void SaveNodeToXml(TreeNodeCollection nodes, XmlNode xmlNode, XmlDocument xmlDoc)
{
    foreach (TreeNode node in nodes)
    {
        XmlNode newNode = xmlDoc.CreateElement("Node");
        newNode.InnerText = node.Text;
        xmlNode.AppendChild(newNode);
        SaveNodeToXml(node.Nodes, newNode, xmlDoc); // 再帰的にノードを保存
    }
}

これらの方法を活用することで、TreeViewのデータを効率的に保存し、必要に応じて再利用することができます。

まとめ

この記事では、C#のTreeViewコントロールを使用して階層構造を実現する方法について詳しく解説しました。

TreeViewの基本的な機能からカスタマイズ、応用例まで幅広く取り上げ、実際のプログラム例を通じて具体的な実装方法を紹介しました。

これを機に、TreeViewを活用して自分のアプリケーションに階層的なデータ表示を取り入れてみてはいかがでしょうか。

当サイトはリンクフリーです。出典元を明記していただければ、ご自由に引用していただいて構いません。

関連カテゴリーから探す

  • URLをコピーしました!
目次から探す