WPF 標準コントロールデモアプリ › TreeView
TreeView List
TreeView は階層的なデータを木構造で表示するコントロールです。TreeViewItem をネストして静的な木構造を作るか、HierarchicalDataTemplate を使って動的な階層データをバインドできます。ファイルエクスプローラーや組織図の表示に使われます。
概要
WPF の TreeView は ItemsControl を継承したコントロールで、階層的なデータを木構造として表示します。各ノードは TreeViewItem で表現され、ノードを展開・折りたたみして子ノードを表示・非表示にできます。
静的な木構造は XAML で TreeViewItem を直接ネストして作成します。動的な階層データには ItemsSource と HierarchicalDataTemplate を組み合わせます。HierarchicalDataTemplate は各ノードの表示方法と子ノードのコレクションプロパティを指定します。
選択されたノードは SelectedItem で取得できます(読み取り専用)。双方向バインドはサポートされていないため、SelectedItemChanged イベントをコードビハインドで処理するか、ビヘイビアを使って ViewModel に通知します。
TreeView は VirtualizingStackPanel を ItemsPanel として使うことで、大量のノードでもパフォーマンスを維持できます。また、TreeViewItem の IsExpanded と IsSelected プロパティを ItemContainerStyle でバインドすることで、展開・選択状態を ViewModel で管理できます。
画面キャプチャ

デモしているプロパティ
以下のプロパティが WPF 標準コントロールデモアプリでインタラクティブにデモされています。
| プロパティ | 設定値 | 説明 |
|---|---|---|
ItemsSource (ItemsControl) | IEnumerable | ルートノードのコレクションをバインドします。動的な階層データを表示する場合は常に HierarchicalDataTemplate と組み合わせて使い、各ノードの表示と子ノードのコレクションプロパティを定義します。HierarchicalDataTemplate を設定すると、どの深さのノードにも同じテンプレートが再帰的に適用されます。落とし穴として、HierarchicalDataTemplate の DataType にはルートノードの ViewModel の型を正確に指定する必要があり、型が一致しないとノードが正しく描画されません。 |
SelectedItem (ReadOnly) | object | 現在選択されているノードのオブジェクトを取得します。WPF の設計上、SelectedItem は読み取り専用であり、プログラムから直接設定できません。SelectedItem を TwoWay バインドしようとすると実行時例外がスローされます。代わりに ItemContainerStyle で各 TreeViewItem の IsSelected プロパティを ViewModel の対応するプロパティに TwoWay バインドすることで、ViewModel から選択を制御できます。 |
IsExpanded (TreeViewItem) | bool | TreeViewItem の展開状態を取得・設定します。アプリセッション間で展開状態を保存・復元したい場合や、プログラムで特定のノードまでパスを展開したい場合に ItemContainerStyle で ViewModel のプロパティに TwoWay バインドして管理します。True に設定するとそのノードが展開されて子アイテムが表示されます。落とし穴として、仮想化が有効な TreeView では、まだ描画されていない折りたたまれたノードに IsExpanded を設定しても反映されないことがあります。 |
IsSelected (TreeViewItem) | bool | TreeViewItem の選択状態を取得・設定します。ItemContainerStyle に Setter を定義して ViewModel のプロパティに TwoWay バインドすることで、ViewModel からノードを選択状態にできます。TreeView では複数選択がサポートされていないため、IsSelected=True にするノードは常に 1 つだけになります。すべてのノードの IsSelected バインドを ViewModel で一元管理して競合しないように注意する必要があります。 |
XAML 使用例
<TreeView ItemsSource="{Binding RootNodes}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:FolderNode}"
ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image Source="/Icons/folder.png" Width="16" Margin="0,0,4,0" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded"
Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>主な使用例
- ファイルエクスプローラー — フォルダとファイルの階層構造をツリー表示するファイルナビゲーションに使用します。
- 組織図・ナビゲーション — 会社の組織図や製品カテゴリの階層をツリーで表示します。
- XML/JSON ビューアー — XML や JSON の木構造をツリービューで可視化するデータビューアーに使用します。
- 設定ツリー — 設定カテゴリの階層をツリー表示して、選択したカテゴリの設定を右ペインに表示する 2 ペイン設定画面に使用します。
- プロジェクト構造ビュー — IDE 風のプロジェクトツリー(ソリューション・プロジェクト・ファイル)を表示します。
ヒントとベストプラクティス
- HierarchicalDataTemplate を活用する — 再帰的な階層データには HierarchicalDataTemplate を使うと、どの深さのノードにも同じテンプレートが適用されます。
- SelectedItem を ViewModel にバインドする方法 — SelectedItem は読み取り専用のため、ItemContainerStyle で各 TreeViewItem の IsSelected を ViewModel のプロパティに TwoWay バインドします。
- 展開状態の永続化 — IsExpanded を ViewModel のノードクラスに TwoWay バインドして、アプリ終了時に展開状態を保存・復元できます。
- 遅延ロード(Lazy Loading) — 初期ロードを高速にするため、子ノードをダミーアイテムで初期化し、ノード展開時(IsExpanded 変化)に実際の子ノードをロードする遅延ロードを実装します。
- 仮想化でパフォーマンス向上 — ノード数が多い場合は VirtualizingStackPanel をItemsPanel に設定して描画コストを削減します。
- 検索・フィルタリングの実装 — ツリーのフィルタリングは、ViewModel 側で各ノードの IsVisible フラグを更新し、一致したノードからルートまでの親ノードを IsExpanded=True にプログラムで展開することで実現します。
- TreeViewItem へのコンテキストメニュー — 右クリックメニューを追加するには ItemContainerStyle 内で ContextMenu を定義します。ContextMenu の DataContext はそのノードの ViewModel になるため、コマンドのバインドも自然に機能します。
関連コントロール
ソースコード
このデモ画面のソースコードは GitHub で公開しています。