C#

【WPF】TreeView(ツリービュー)の使用方法を徹底解説!

この記事ではフォルダの階層を表示する時に使ったりするTreeViewについて基本的な扱い方をまとめています。

名無し君
名無し君
TreeViewを使用する方法を知りたい方にお勧めです。

ぜひ最後まで読んで参考にしてみてください。

 他のUIコントロールの使い方も知りたい方はここをクリック!!

画面作成で使う「コントロール」一覧
(種類別に紹介)

\ WPFのコントロールについて詳しくみる /

TreeViewとは

TreeView(ツリービュー)は、階層構造をツリー形式で表示するコントロールです。ツリー形式で表示されるデータ項目を「ノード」と呼び、更に下にある階層のデータ項目を「子ノード」と呼びます。

名無し君
名無し君
身近なところの使用例で言うと、WindowsのエクスプローラーやVisual Studioのソリューション エクスプローラー、レジストリエディタのナビゲーションウィンドウで表示されているのがTreeViewです。

特徴として、階層構造を持った項目を必要な時に展開したり、折りたたむことができます。項目数が多い場合等に整理して表示することが可能です。

 

TreeViewの使用方法

ここからTreeView(ツリービュー)の使い方を紹介します。

WPFでTreeViewを扱う方法として、次の2つの方法があります。

  1. XAMLに直接ノードを書く静的な方法
  2. データバインディングでノードを追加する動的な方法

個人的には②の用途で使う機会が多いと思いますが、TreeViewについてより理解を深める為に、この記事では両方の使い方を紹介します。

 

①XAMLに直接ノードを書く静的な方法

WPFではTreeViewコントロールは標準搭載されています。ツールボックスの検索欄に「TreeView」と入力・選択してウィンドウに配置するか、XAMLのコード内に直接記述をします。

ノードを追加するには、TreeViewItemをTreeViewの子要素として書いて、Headerプロパティにノードの名称を記述します。

子ノードを追加するには、さらにTreeViewItemの子要素としてTreeViewItemを入れ子します。

こうすることで、上位の階層と下位の階層の関係性を定義します。

<Window x:Class="Sample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Sample"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="350">
    <StackPanel>
        <TreeView>
            <TreeViewItem Header="ノード1">
                <TreeViewItem Header="ノード1-1">
                    <TreeViewItem Header="ノード1-1-1"/>
                    <TreeViewItem Header="ノード1-1-2"/>
                </TreeViewItem>
                <TreeViewItem Header="ノード1-2">
                    <TreeViewItem Header="ノード1-2-1"/>
                    <TreeViewItem Header="ノード1-2-2"/>
                </TreeViewItem>
            </TreeViewItem>
        </TreeView>
    </StackPanel>
</Window>

このコードを実行した画面は次の通りです。

簡単にツリー状に項目を表示させることができました。

 

TreeViewにアイコンを表示する

WindowsのエクスプローラーやVisual Studioのソリューション エクスプローラーを見るとアイコンが付いています。

WPFのTreeViewもアイコンを表示することができますので、アイコンを追加してみましょう。

まずはアイコンを準備します。画像であれば何でもOKです。無料で商用利用可能な画像を探してインターネットで探します。(ここではこのサイトからダウンロードしました)

自プロジェクトにImagesディレクトリを作成し、アイコン用画像(ここではPhoto.jpeg)を追加します。

追加したアイコン画像のプロパティを開いて、ビルドアクションをResourceに変更します。

これでアイコンの準備は終了です。

続いてTreeViewにアイコンを表示するようにXAMLを修正します。

TreeViewItemのHeaderエリアの中に、StackPanelを設置してImageクラスとTextBlockクラスを子要素として追加します。

名無し君
名無し君
ButtonのContentは1つしかオブジェクトを追加できません。そのためStackPanelにImageとTextBlockを追加して1つのオブジェクトにします。

アイコン画像を表示するXAMLが次の通りです。

<Window
    x:Class="Sample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:Sample"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="350"
    Height="200"
    mc:Ignorable="d">
    <StackPanel>
        <TreeView>
            <TreeViewItem>
                <TreeViewItem.Header>
                    <StackPanel Orientation="Horizontal">
                        <Image Height="16" Source="Images\Photo.jpeg" Margin="0,0,5,0"/>
                        <TextBlock Text="ノード1" />
                    </StackPanel>
                </TreeViewItem.Header>
                <TreeViewItem>
                    <TreeViewItem.Header>
                        <StackPanel Orientation="Horizontal">
                            <Image Height="16" Source="Images\Photo.jpeg" Margin="0,0,5,0"/>
                            <TextBlock Text="ノード1-1" />
                        </StackPanel>
                    </TreeViewItem.Header>
                    <TreeViewItem >
                        <TreeViewItem.Header>
                            <StackPanel Orientation="Horizontal">
                                <Image Height="16" Source="Images\Photo.jpeg" Margin="0,0,5,0"/>
                                <TextBlock Text="ノード1-1-1" />
                            </StackPanel>
                        </TreeViewItem.Header>
                    </TreeViewItem>
                </TreeViewItem>
            </TreeViewItem>
        </TreeView>
    </StackPanel>
</Window>

このコードを実行した画面は次の通りです。

文字列の前にアイコンが表示されました。

 

TreeViewにチェックボックスを表示する

今度はアイコンではなく、チェックボックスを表示します。

チェックボックスを表示するのは簡単で、先ほどアイコンを表示する為に設定したImageクラスの部分を丸ごとCheckBoxクラスに変更するだけです。

ここではチェックボックスにチェックされたらTreeViewを展開し、チェックが外されたらTreeViewを折りたたむように簡単なバインドを行います。

展開するかどうかを設定するには、TreeViewのIsExpandedプロパティを使います。

プロパティ名内容
bool IsExpanded { get; set; }要素が展開されているかどうかを取得または設定します。

チェックボックスを表示するXAMLが次の通りです。

<Window
    x:Class="Sample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:Sample"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="350"
    Height="200"
    mc:Ignorable="d">
    <StackPanel>
        <TreeView>
            <TreeViewItem IsExpanded="{Binding ElementName=chk1, Path=IsChecked}">
                <TreeViewItem.Header>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox Name="chk1" Margin="1" />
                        <TextBlock Text="ノード1" />
                    </StackPanel>
                </TreeViewItem.Header>
                <TreeViewItem IsExpanded="{Binding ElementName=chk2, Path=IsChecked}">
                    <TreeViewItem.Header>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox Name="chk2" Margin="1" />
                            <TextBlock Text="ノード1-1" />
                        </StackPanel>
                    </TreeViewItem.Header>
                    <TreeViewItem IsExpanded="{Binding ElementName=chk3, Path=IsChecked}">
                        <TreeViewItem.Header>
                            <StackPanel Orientation="Horizontal">
                                <CheckBox Name="chk3" Margin="1" />
                                <TextBlock Text="ノード1-1-1" />
                            </StackPanel>
                        </TreeViewItem.Header>
                    </TreeViewItem>
                </TreeViewItem>
            </TreeViewItem>
        </TreeView>
    </StackPanel>
</Window>

このコードを実行した動作は次の通りです。

 

スクロールバーを表示する

TreeViewを展開していくと縦に長くなってしまい、下部に表示されたノードが画面に隠れてしまうことがあります。

名無し君
名無し君
画面に隠れてしまったノードを表示するためにはスクロールバーが必要不可欠です。

WPFではスクロールを表示するScrollViewerコントロールが標準搭載されているので、ScrollViewerの子要素としてTreeViewを追加します。

<Window
    x:Class="Sample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:Sample"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="350"
    Height="200"
    mc:Ignorable="d">
    <ScrollViewer
        Margin="0"
        HorizontalScrollBarVisibility="Hidden"
        VerticalScrollBarVisibility="Visible">
        <TreeView>
            <TreeViewItem Header="ノード1">
                <TreeViewItem Header="ノード1-1">
                    <TreeViewItem Header="ノード1-1-1" />
                    <TreeViewItem Header="ノード1-1-2" />
                    <TreeViewItem Header="ノード1-1-3" />
                    <TreeViewItem Header="ノード1-1-4" />
                </TreeViewItem>
                <TreeViewItem Header="ノード1-2">
                    <TreeViewItem Header="ノード1-2-1" />
                    <TreeViewItem Header="ノード1-2-2" />
                    <TreeViewItem Header="ノード1-2-3" />
                    <TreeViewItem Header="ノード1-2-4" />
                    <TreeViewItem Header="ノード1-2-5" />
                    <TreeViewItem Header="ノード1-2-6" />
                    <TreeViewItem Header="ノード1-2-7" />
                    <TreeViewItem Header="ノード1-2-8" />
                </TreeViewItem>
            </TreeViewItem>
        </TreeView>
    </ScrollViewer>
</Window>

このコードを実行した動作は次の通りです。

 

データバインディングでノードを追加する動的な方法

TreeViewを動的に扱うにはItemsSourceプロパティにコレクションを設定することで、任意の型のコレクションデータを表示することができます。

まずはデータバインディングを行うための型となるクラスを作成します。

CTreeViewDataクラスにはノード名を表示する為のNameプロパティと、階層を表すChildernプロパティがあります。

using System.Collections.Generic;

namespace Sample.CTreeView
{
    public class CTreeViewData
    {
        public string Name { get; set; }
        public IEnumerable<CTreeViewData> Children { get; set; }
    }
}

MainWindowのコンストラクタで、CTreeViewDataクラスのコレクションを作成します。子ノードを追加する場合は、CTreeViewDataクラスのリストを設定します。Childernプロパティにリストを追加していくことで、下位の階層をつくることが可能です。

using System.Collections.Generic;
using System.Windows;
using Sample.CTreeView;

namespace Sample
{
    public partial class MainWindow : Window
    {
        private List<CTreeViewData> cTreeViewDatas { get; } = new List<CTreeViewData>();

        public MainWindow()
        {
            InitializeComponent();

            CTreeViewData data = new CTreeViewData
            {
                Name = "ノード1",
                Children = new List<CTreeViewData>
                {
                    new CTreeViewData
                    {
                        Name = "ノード1-1",
                        Children = new List<CTreeViewData>
                        {
                            new CTreeViewData { Name = "ノード1-1-1" },
                            new CTreeViewData { Name = "ノード1-1-2" }
                        },
                    },
                }
            };

            cTreeViewDatas.Add(data);
            treeview.ItemsSource = cTreeViewDatas;
        }
    }
}

データバインディングする場合は、階層構造を扱う為にDataTamplateを拡張したHierarchicalDataTemplateを使用します。

HierarchicalDataTemplateのItemSourceに階層プロパティであるChildernプロパティを設定し、ノード名を表示するTextBlockにNameプロパティをバインドします。

名無し君
名無し君
HierarchicalDataTemplateはルート要素しか表示しないのでItemSourceプロパティにはChildernプロパティをバインドします。

以上の事を踏まえて記述したXAMLが次の通りです。

<Window
    x:Class="Sample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:Sample"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="350"
    Height="200"
    mc:Ignorable="d">
    <StackPanel>
        <TreeView Name="treeview">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Name}" />
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </StackPanel>
</Window>

このコードを実行した画面は次の通りです。

 

まとめ

この記事ではTreeViewの使用法について静的な方法と動的な方法を紹介しました。

静的な方法ではTreeViewItemで階層構造をつくり、動的な方法ではTreeViewItemのDataTamplateを拡張したHierarchicalDataTemplateで階層構造をつくりました。

フォルダのような階層構造を画面に表示して操作する場合は、TreeViewを扱うことになるでしょう。

次回はエクスプローラーのようなフォルダツリーを作成してみたいと思います。

以上、最後まで読んでいただきありがとうございました。

プログラミングを学習したいなら…

プログラミングスキルを身に付けるなら、プログラミングを効率良く学べる
プログラミングスクール」がオススメです。

特にこんな方にオススメ!!
これからエンジニアを目指したい
プログラミングの専門性を高めたい
プログラミングを学んで副業をしたい
エンジニアに転職して年収をアップさせたい

プログラミングを触ったことがない未経験からでも、プログラミングスクールで学習すれば、エンジニアへ就職・転職することも可能です。

あなたの「行動力」と「やる気」で、あなたの人生を大きく変えるチャンスになることでしょう。

プログラミングスクールに興味がある方は是非チェックしてみてください。

> プログラミングを学ぶ <

COMMENT

メールアドレスが公開されることはありません。

CAPTCHA