WPF 標準コントロールデモアプリ › TreeView

TreeView List

TreeView は階層的なデータを木構造で表示するコントロールです。TreeViewItem をネストして静的な木構造を作るか、HierarchicalDataTemplate を使って動的な階層データをバインドできます。ファイルエクスプローラーや組織図の表示に使われます。

概要

WPF の TreeViewItemsControl を継承したコントロールで、階層的なデータを木構造として表示します。各ノードは TreeViewItem で表現され、ノードを展開・折りたたみして子ノードを表示・非表示にできます。

静的な木構造は XAML で TreeViewItem を直接ネストして作成します。動的な階層データには ItemsSourceHierarchicalDataTemplate を組み合わせます。HierarchicalDataTemplate は各ノードの表示方法と子ノードのコレクションプロパティを指定します。

選択されたノードは SelectedItem で取得できます(読み取り専用)。双方向バインドはサポートされていないため、SelectedItemChanged イベントをコードビハインドで処理するか、ビヘイビアを使って ViewModel に通知します。

TreeView は VirtualizingStackPanel を ItemsPanel として使うことで、大量のノードでもパフォーマンスを維持できます。また、TreeViewItem の IsExpandedIsSelected プロパティを ItemContainerStyle でバインドすることで、展開・選択状態を ViewModel で管理できます。

画面キャプチャ

treeview demo screen

デモしているプロパティ

以下のプロパティが WPF 標準コントロールデモアプリでインタラクティブにデモされています。

プロパティ設定値説明
ItemsSource (ItemsControl)IEnumerableルートノードのコレクションをバインドします。動的な階層データを表示する場合は常に HierarchicalDataTemplate と組み合わせて使い、各ノードの表示と子ノードのコレクションプロパティを定義します。HierarchicalDataTemplate を設定すると、どの深さのノードにも同じテンプレートが再帰的に適用されます。落とし穴として、HierarchicalDataTemplate の DataType にはルートノードの ViewModel の型を正確に指定する必要があり、型が一致しないとノードが正しく描画されません。
SelectedItem (ReadOnly)object現在選択されているノードのオブジェクトを取得します。WPF の設計上、SelectedItem は読み取り専用であり、プログラムから直接設定できません。SelectedItem を TwoWay バインドしようとすると実行時例外がスローされます。代わりに ItemContainerStyle で各 TreeViewItem の IsSelected プロパティを ViewModel の対応するプロパティに TwoWay バインドすることで、ViewModel から選択を制御できます。
IsExpanded (TreeViewItem)boolTreeViewItem の展開状態を取得・設定します。アプリセッション間で展開状態を保存・復元したい場合や、プログラムで特定のノードまでパスを展開したい場合に ItemContainerStyle で ViewModel のプロパティに TwoWay バインドして管理します。True に設定するとそのノードが展開されて子アイテムが表示されます。落とし穴として、仮想化が有効な TreeView では、まだ描画されていない折りたたまれたノードに IsExpanded を設定しても反映されないことがあります。
IsSelected (TreeViewItem)boolTreeViewItem の選択状態を取得・設定します。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>

主な使用例

ヒントとベストプラクティス

関連コントロール

ソースコード

このデモ画面のソースコードは GitHub で公開しています。

GitHub で TreeView のソースコードを見る →