TreeView の使い方について知りたい。
この記事ではフォルダの階層を表示する時に使ったりする TreeView について基本的な扱い方をまとめています。
ぜひ最後まで読んで参考にしてみてください。
オススメの参考書
C#の使い方が丁寧に解説しており、「基礎からしっかりと学びたい」という初心者の方にオススメの一冊です。サンプルコードも記載してあり、各章の最後に復習問題があるので理解度を確認しながら読み進めることができます。新しい C# のバージョンにも対応している書籍です。
TreeViewとは
TreeView(ツリービュー)は、階層構造をツリー形式で表示するコントロールです。ツリー形式で表示されるデータ項目を「ノード」と呼び、更に下にある階層のデータ項目を「子ノード」と呼びます。
特徴として、階層構造を持った項目を必要な時に展開したり、折りたたむことができます。項目数が多い場合等に整理して表示することが可能です。
他の UI コントロールの使い方も知りたい方はこの記事をチェック!!
TreeViewの使用方法
ここからTreeView(ツリービュー)の使い方を紹介します。
WPF で TreeView を扱う方法として、次の2つの方法があります。
- XAMLに直接ノードを書く静的な方法
- データバインディングでノードを追加する動的な方法
個人的には②の用途で使う機会が多いと思いますが、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
クラスを子要素として追加します。
アイコン画像を表示する 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を展開していくと縦に長くなってしまい、下部に表示されたノードが画面に隠れてしまうことがあります。
[chat face=”icon.png” name=”名無し君” align=”left” border=”blue” bg=”none” style=”maru”]画面に隠れてしまったノードを表示するためにはスクロールバーが必要不可欠です。[/chat]
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プロパティをバインドします。
[chat face=”icon.png” name=”名無し君” align=”left” border=”blue” bg=”none” style=”maru”]HierarchicalDataTemplateはルート要素しか表示しないのでItemSourceプロパティにはChildernプロパティをバインドします。[/chat]
以上の事を踏まえて記述した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 を扱うことになるでしょう。
次回はエクスプローラーのようなフォルダツリーを作成してみたいと思います。
以上、最後まで読んでいただきありがとうございました。