CodeZine(コードジン)

特集ページ一覧

TreeView for WinFormsで高機能なツリービューを実現

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2017/09/05 14:00

 ツリー状に項目を表示できるツリービューは、階層構造を持った項目を表示する際に便利です。下位のメニューを折りたたむことができる構造なので、項目数が多い場合などに整理して表示することができます。Windows Formsには標準でTreeViewという、ツリー表示に対応したコントロールがありますが、今回は標準のTreeViewにはない機能を備えた、ComponentOne StudioのTreeView for WinFormsについて紹介します。

今回紹介するコンポーネント

 ComponentOne StudioはWFP、Windows Forms、UWPといったさまざまなアプリケーションに便利な機能を追加できるコンポーネント集です。今回紹介するのは、Windows Formsアプリケーションにツリービュー機能を追加できるコンポーネントがTreeView for WinFormsです。

 2017年5月にリリースされた「ComponentOne Studio 2017J v1」では、TreeView for WinFormsの新機能「カスタムノードの表示」が追加され、より便利になりました。

 2017年7月にリリースされた最新版「ComponentOne Studio 2017J v2」では、前回の記事で取り上げたGanttView for WinFormの新機能など、さらに便利な機能が拡充されています。

TreeView for WinForms

 TreeView for WinFormsは、Windows Formsアプリケーションに高い拡張性を持ったツリービューを追加することができるコンポーネントです。標準のコントロールにはない機能を多く備えています。

 新機能としてノードのカスタマイズが可能となりました。これにより、ツリービューの見た目を柔軟にカスタマイズすることができます。本記事でもノードのカスタマイズについて紹介します。

 機能の概要は以下の公式ページを参考にしてください。

 また本記事のサンプルを実行する際は、公式のドキュメントも参考にしてください。

対象読者

 Visual Studioを利用してアプリケーションを作成した経験がある、またはC#、Visual Basicなどの.NET系言語での開発経験がある方。

必要な環境

 TreeView for WinFormsを利用するには以下の環境が必要となります。

  • Visual Studio 2012/2013/2015/2017 日本語版
  • .NET Framework 4.5.2/4.6/4.6.1/4.6.2/4.7

 本記事はVisual Studio Enterprise 2017、.NET Framework 4.6環境で画像キャプチャーの取得、動作検証を行っています。

ComponentOne Studioの導入

 すでにComponentOne Studioを導入済みの場合も、アカウントでサインイン後に「ダウンロード」→「製品版」から最新のComponentOne Studioをダウンロードしてください。

 トライアル版として導入する場合は、以下のURLのフォームからトライアル版を申し込んでください。

 フォームに入力したメールアドレスにトライアル版のダウンロードアドレスが送信されるので、それを元にダウンロードを行います。

ComponentOne Studioのインストール

 ダウンロードしたZipファイルを展開し、解凍されたファイルからC1StudiosInstaller.exeをダブルクリックしてインストーラーを起動します。

インストーラーの起動
インストーラーの起動

 「ComponentOne Studioのインストール」ボタンをクリックします。

導入するプラットフォームの選択
導入するプラットフォームの選択

 導入するプラットフォームを選択します。

 今回はWinFormsを選択し右下の「次へ」をクリックします。各プラットフォームに赤い三角とエクスクラメーションマークのアイコンが出ている場合、すでにインストールされているコンポーネントを上書きするという警告です。新規インストール時は表示されていません。

インストールを開始する
インストールを開始する

 以下の画面が表示されれば、インストールの完了です。「完了」ボタンを押してウィンドウを閉じます。

インストールの完了
インストールの完了

TreeView for WinFormsを使ってみる

 それでは簡単なサンプルを作成してみましょう。

 Visual Studioを起動し上部メニューの「ファイル」→「新規作成」→「プロジェクト」をクリックします。

プロジェクトの作成

プロジェクトの作成
プロジェクトの作成

 「新しいプロジェクト」ポップアップウィンドウの左ナビから「インストール済み」→「テンプレート」→「Visual C#」→「Windows クラシック デスクトップ」を選択し、中央の一覧から「Windows フォーム アプリケーション」テンプレートを選択します。

テンプレートの選択
テンプレートの選択

 名前の項目は任意ですが、本記では「TreeViewSample」という名前でプロジェクトを作成して進めます。

 ウィンドウの右下「OK」をクリックします。

コントロールの追加

 これまでTreeView for WinFormsを利用したことがない場合は、コントロールを追加します。

 上部メニューの「ツール」→「ツールボックスアイテムの選択」をクリックします。

「ツールボックスアイテムの選択」をクリック
「ツールボックスアイテムの選択」をクリック

 「ツールボックスアイテムの選択」ウィドンウの「.NET Frameworkコンポーネント」タブから、C1TreeViewにチェックを入れて「OK」ボタンをクリックします。

 C1TreeView項目は2つ表示される場合もありますが、名前空間が「C1.Win.TreeView」のものを選択します。

C1TreeViewの追加
C1TreeViewの追加

コントロールの配置

 プロジェクトを作成すると、初期状態でForm1.csが中央のデザイナー画面に表示された状態で始まります。Form1.csが表示されていない場合は、Visual Studioの右ナビの「ソリューションエクスプローラー」ウィンドウの一覧から「Form1.cs」上で右クリック→「ビューデザイナー」をクリックします。

Form1.csが開かれたデザイナー画面
Form1.csが開かれたデザイナー画面

 左側のツールボックスから「C1TreeView」をドラッグしてデザイナー画面にドロップします。

ツールボックスからC1TreeViewをドラッグする
ツールボックスからC1TreeViewをドラッグする

エディタからノードを追加する

 C1TreeViewはエディタ画面からプログラムコード無しで、ツリービューの項目(ノード)を追加することができます。

 ノードを追加するにはデザイナー画面の配置されたC1TreeViewコントロール上で右クリック→「ノードの編集」をクリックします。

「ノードの編集」をクリック
「ノードの編集」をクリック

 「ノードの編集」をクリックすると「ツリーノードエディター」ウィンドウが表示されます。

 「ツリーノードエディター」ウィンドウの左下の「追加」ボタンをクリックするとノードが追加されます。

ノードを追加
ノードを追加

 ノードを選択し、ウィンドウ左下の「子の追加」ボタンをクリックすると、選択したノードの子ノードが追加されます。

子ノードを追加
子ノードを追加

 ウィンドウ右下の「OK」ボタンを押して編集を終了します。

プログラムからノードを追加する

 ノードの追加はプログラムコードから行うこともできます。

 デザイナー画面に追加したC1TreeViewは、デフォルトで「c1TreeView1」という値がNameプロパティに指定されています(複数配置した場合などは末尾の数字が異なります)。Windows Formsの標準のコントロール同様、プログラム側でNameプロパティの値を用いてコントロールにアクセスできます。

 まず、先にプログラムからノードを追加した結果を見ておきましょう。

 下の画像のように、ツリーノードエディターであらかじめ追加してあった「親ノード」というノードの他に「親ノード2」というノードと、その下に子ノードが追加されています。

プログラムからノードを追加した結果
プログラムからノードを追加した結果

 以下がツリービューにノードを追加するコードです。

 C1TreeViewに「親ノード2」という名前のノードを追加し、その子ノードとして「子ノード3」というノードを追加しています。

プログラムからノードを追加する
private void Form1_Load(object sender, EventArgs e)
{
    // using句に「using C1.Win.TreeView;」を追加
    C1TreeNode node1 = new C1TreeNode();

    node1.SetValue("親ノード2");

    // ツリービューにノードを追加する
    c1TreeView1.Nodes.Add(node1);

    // 子ノードを追加する
    C1TreeNode node2 = new C1TreeNode();

    node2.SetValue("子ノード3");

    node1.Nodes.Add(node2);
}

 アプリケーションを実行すると、以下のようにノードが追加されていることを確認できます。

アプリケーションの実行結果
アプリケーションの実行結果

TreeView for WinFormsの特徴[1]

チェックボックスの表示

チェックボックス
チェックボックス

 C1TreeViewのCheckBoxesプロパティをtrueにすることで、項目にチェックボックスを表示することができます。

チェックボックスの表示(デザイナー)
チェックボックスの表示(デザイナー)
チェックボックスの表示(コード)
// チェックボックスを表示
c1TreeView1.CheckBoxes = true;

ノードの選択

ノードの選択
ノードの選択

 チェックボックスを使わない場合でも、ノードの選択は可能です。その場合、SelectionModeプロパティで複数選択を許可などの設定を行うことができます。

ノードの選択設定(デザイナー)
ノードの選択設定(デザイナー)
ノードの選択設定(コード)
// ノードの選択設定
c1TreeView1.SelectionMode = C1TreeViewSelectionMode.Multi;

 SelectionModeは、C1TreeViewSelectionMode列挙体の値を指定します。C1TreeViewSelectionMode列挙体は、以下の値を取ります。

Multi すべてのノードから複数のノードを選択できます
MultiSibling 1つの親ノード以下から複数選択できます
None ノードを選択できません
Single 1 つのノードを選択できます

ノードの編集

ノードの編集
ノードの編集

  ノードのテキストを編集可能にすることができます。編集を可能にするにはAllowEditingプロパティをtrueに設定します。

ノードの編集設定(デザイナー)
ノードの編集設定(デザイナー)
ノードの編集設定(コード)
// ノードの編集
c1TreeView1.AllowEditing = true;

TreeView for WinFormsの特徴[2]

列ヘッダーの非表示

 列ヘッダーの表示・非表示を切り替えることができます。

列ヘッダーの表示非表示を切り替える
列ヘッダーの表示非表示を切り替える

 列ヘッダーの表示・非表示を切り替えるにはShowColumnHeadersプロパティにtrue(表示)またはfalse(非表示)を指定します。

ShowColumnHeadersプロパティ
ShowColumnHeadersプロパティ

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

 各ノードのドラッグ&ドロップもプロパティの変更で実現できます。

 C1TreeViewのAllowDropとEnableDragDropをtrueに設定します。

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

データ連結

 配列やコレクションデータを利用して、ノードを生成することができます。

 例えば、以下のような学校のクラスを表すクラスがあったとします。

学校のクラスを表す
public class Class
{
    // クラス名
    private string _name;

    public string name
    {
        get { return _name; }
        set { _name = value; }
    }
}

 1組、2組といったクラスをコレクションで表現し、C1TreeViewにデータ連結します。

データ連結する
List<Class> classList = new List<Class>();

classList.Add(new Class() { name = "1組"});
classList.Add(new Class() { name = "2組" });
classList.Add(new Class() { name = "3組" });

// データソースとしてclassListを指定する
c1TreeView1.DataSource = classList;

// フィールド名にnameプロパティを使用する
c1TreeView1.Columns[0].DisplayFieldName = "name";

 プログラムを実行すると以下のようにノードが表示されます。

データの連結結果
データの連結結果

階層化データの連結

 先ほどのクラス名を表示したノードの下に、生徒名を表示させる階層構造を持ったデータを連結することもできます。

階層化データの連結結果
階層化データの連結結果

 クラスと生徒は以下のように定義されています。

クラスと生徒の定義
public class Class
{
    // クラス名
    private string _name;

    public string name
    {
        get { return _name; }
        set { _name = value; }
    }

    private BindingList<Student> _studentList;

    public BindingList<Student> studentList
    {
        get { return _studentList; }
        set { _studentList = value; }
    }
}

public class Student
{
    private string _name;

    public string name
    {
        get { return _name; }
        set { _name = value; }
    }

    public override string ToString()
    {
        return name;
    }
}

 C1TreeViewに連結するコードは以下です。

データを連結する
List<Class> classList = new List<Class>();

// クラスとクラスに所属する生徒のコレクションを作成する
Class class1 = new Class() { name = "1組" };

class1.studentList = new BindingList<Student>();
class1.studentList.Add(new Student() { name = "山田" });
class1.studentList.Add(new Student() { name = "田中" });

classList.Add(class1);

Class class2 = new Class() { name = "2組" };

class2.studentList = new BindingList<Student>();
class2.studentList.Add(new Student() { name = "西村" });

classList.Add(class2);

classList.Add(new Class() { name = "3組" });

// データソースとしてclassListを指定する
c1TreeView1.DataSource = classList;

// フィールド名にnameプロパティを使用する
c1TreeView1.Columns[0].DisplayFieldName = "name";

// データメンバーにstudentListを指定
c1TreeView1.DataMember = "\\studentList";

TreeView for WinFormsの特徴[3]

列を持ったツリービュー表示

 C1TreeViewでは、項目ごとに複数の列を持つことができます。

 2列目に各クラスの生徒数を表示する列を追加します。

列を追加
列を追加

 以下のように総生徒数を返すcountプロパティを追加します。

総生徒数を返すプロパティを追加する
public class Class
{
    // クラス名
    private string _name;

    public string name
    {
        get { return _name; }
        set { _name = value; }
    }

    private BindingList<Student> _studentList = new BindingList<Student>();

    public BindingList<Student> studentList
    {
        get { return _studentList; }
        set { _studentList = value; }
    }

    // 総生徒数を返す
    public int count
    {
        get{ return studentList.Count; }
    }
}

 列(column)を追加し、追加した列に総生徒数を表示するように指定します。

総生徒数を表示する列を追加する
// 列の指定を一旦クリアクリア
c1TreeView1.Columns.Clear();

C1TreeColumn clumn1 = new C1TreeColumn();
clumn1.HeaderText = "クラス";
c1TreeView1.Columns.Add(clumn1);

C1TreeColumn clumn2 = new C1TreeColumn();
clumn2.HeaderText = "総生徒数";
clumn2.DisplayFieldName = "count\\count";
c1TreeView1.Columns.Add(clumn2);

カスタムノード

カスタムノードの実行結果
カスタムノードの実行結果

  カスタムノードの機能を利用すると、ノードの表示をカスタマイズすることができます。

 カスタムノードの設定は、CustomContentPresenterを継承したクラスで表示内容を定義します。

 CustomContentPresenterを継承したクラスは、以下のメソッドをオーバーライドすることで固有の表示を定義します。

ToolTipText ツールチップの表示を指定します
SetStyle スタイルを定義します
SetValue 各ノード毎のデータを指定します
SetFormat フォーマットを指定します

 CustomContentPresenterを継承した、以下のようなクラスを用意します。

カスタムノードの見た目を定義したクラス
public class SampleCustomNode : CustomContentPresenter
{
    // 階層1
    private TextElement _text1;
    private ImageElement _img1;

    private RowPanel _rowPanel;

    // 階層2
    private TextBoxElement _text2;

    public SampleCustomNode()
    {
        // 階層1の初期化
        _text1 = new TextElement();
        _text1.Style = new Style();

        _img1 = new ImageElement();
        _img1.Style = new Style();
        _img1.Size = new Size(45, 45);

        _rowPanel = new RowPanel();
        _rowPanel.Children.Add(_text1);
        _rowPanel.Children.Add(_img1);

        _rowPanel.Style = new Style();
        _rowPanel.Style.VerticalAlignment = Alignment.Center;

        // 階層2の初期化初期化
        _text2 = new TextBoxElement();
        _text2.Style = new Style();
    }

    public override string ToolTipText
    {
        get
        {
            return this.ToString();
        }
    }

    public override void SetStyle(TreeNodeCellStyles styles)
    {
        // 階層1
        _text1.Style.Margins = new Thickness(1);
        _text1.Style.Font = new Font("Calibri", 10, FontStyle.Bold);

        _img1.Style.ImageScaling = ImageScaling.Scale;
        _img1.Style.ImageAlignment = ImageAlignment.CenterCenter;

        // 階層2
        _text2.Style.Font = new Font("Calibri", 10, FontStyle.Bold);
        _text2.Style.HorizontalAlignment = Alignment.Center;
        _text2.Style.VerticalAlignment = Alignment.Center;

    }

    // 各ノードに利用するデータを設定する
    // 引数のobjectは表示に利用するデータが渡される。
    public override void SetValue(object value)
    {
        // 階層1なら
        if (Node.Level == 0)
        {
            _text1.Text = (string)value;
            _img1.Image = Image.FromFile("logo.png");

            Child = _rowPanel;
        }
        // 階層2なら
        else
        {
            _text2.Text = (string)value;

            Child = _text2;
        }
    }

    public override void SetFormat(string str)
    {
    }
}

 上記のSampleCustomNodeクラスを1列目の見た目に設定します。

1列目のカスタムノードに指定する
c1TreeView1.Columns[0].CustomContentPresenter = new SampleCustomNode();

まとめ

 TreeView for WinFormsはツリービューに必要な基本的な機能に加えて、ツリービューの表示に複数列を用いることができ、それぞれの列の表示を柔軟にカスタマイズできます。

 高機能なツリービューを自社で開発するのは大変です。本記事で紹介したTreeView for WinFormsを利用し、開発コスト・開発期間の短縮に活かしてみてください。

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 西村 誠(ニシムラ マコト)

     Microsoft MVP Windows Platform Development。  Flash、PHPの開発経験もあり国産ECサイト構築フレームワーク「EC-CUBE」の公式エバンジェリストでもある。  ブログ:眠るシーラカンスと水底のプログラマー  著書:基礎から学ぶ Windows...

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5