TreeViewTreeView

XAML TreeView コントロールを使用すると、階層リストが有効になり、入れ子になった項目を含むノードを展開したり、折りたたんだりすることができるようになります。The XAML TreeView control enables a hierarchical list with expanding and collapsing nodes that contain nested items. フォルダー構造や入れ子になった関係を UI で視覚的に示すために使用できます。It can be used to illustrate a folder structure or nested relationships in your UI.

TreeView API は、以下の機能をサポートします。The TreeView APIs support the following features:

  • N レベルの入れ子N-level nesting
  • 1 つまたは複数のノードの選択Selection of single or multiple nodes
  • (プレビュー)ツリー ビューで TreeViewItem ItemsSource プロパティをデータ バインディング(Preview) Data binding to the ItemsSource property on TreeView and TreeViewItem
  • (プレビュー)ツリー ビュー項目テンプレートのルートとして TreeViewItem(Preview) TreeViewItem as the root of the TreeView item template
  • (プレビュー)TreeViewItem 内のコンテンツの任意の型(Preview) Arbitrary types of content in a TreeViewItem
  • (プレビュー)ドラッグ アンド ドロップ ツリー ビューの間で(Preview) Drag and drop between tree views
Windows UI のライブラリを入手します。Get the Windows UI Library
このコントロールは、Windows UI のライブラリ、新しいコントロールと UWP アプリの UI の機能が含まれている NuGet パッケージの一部として含まれています。This control is included as part of the Windows UI Library, a NuGet package that contains new controls and UI features for UWP apps. 詳しくは、インストールの手順を含む、 Windows UI のライブラリの概要をご覧ください。For more info, including installation instructions, see the Windows UI Library overview.
プラットフォーム ApiPlatform APIs Windows UI ライブラリ ApiWindows UI Library APIs
TreeView クラスTreeViewNode クラスTreeView.ItemsSource プロパティTreeView class, TreeViewNode class, TreeView.ItemsSource property TreeView クラスTreeViewNode クラスTreeView.ItemsSource プロパティTreeView class, TreeViewNode class, TreeView.ItemsSource property

適切なコントロールの選択Is this the right control?

  • 項目に入れ子になった一覧項目が含まれているとき、それらの項目とピアやノードとの階層関係を視覚的に示すことが重要になる場合は、ツリー ビューを使用します。Use a TreeView when items have nested list items, and if it is important to illustrate the hierarchical relationship of items to their peers and nodes.

  • 項目の入れ子になった関係を強調表示することが優先的な処理ではない場合は、ツリー ビューを使用しないでください。Avoid using TreeView if highlighting the nested relationship of an item is not a priority. ほとんどの演習用シナリオでは、標準的なリスト ビューが適していますFor most drill-in scenarios, a regular list view is appropriate

Examples

XAML コントロール ギャラリーXAML Controls Gallery
XAML controls gallery

XAML コントロール ギャラリーアプリがインストールされている場合は、ここをクリックしてアプリを開き、操作でのツリー ビューを参照してくださいIf you have the XAML Controls Gallery app installed, click here to open the app and see the TreeView in action.

TreeView UITreeView UI

ツリー ビューはインデントとアイコンを組み合わせて使用することで、フォルダー/親ノードとフォルダー以外の項目/子ノードとの間の入れ子になった関係を表します。The tree view uses a combination of indentation and icons to represent the nested relationship between folder/parent nodes and non-folder/child nodes. 折りたたまれているノードでは右向きの山形記号を使用し、展開されているノードでは下向きの山形記号を使用します。Collapsed nodes use a chevron pointing to the right, and expanded nodes use a chevron pointing down.

TreeView での山形記号アイコン

ツリー ビュー項目データ テンプレートにアイコンを含めてノードを表すことができます。You can include an icon in the tree view item data template to represent nodes. この場合、ディスク上のフォルダー構造などのリテラル フォルダーを表すノードに対してのみ、フォルダー アイコンのみを使用する必要があります。If you do this, you should use a folder icon only for nodes that represent literal folders, such as the folder structure on a disk.

TreeView で山形記号のアイコンとフォルダー アイコンの組み合わせ

ツリー ビューの作成Create a tree view

ツリー ビューを作成するには、階層データ ソースをItemsSourceをバインドまたはを作成して、自分で TreeViewNode オブジェクトを管理することができます。You can create a tree view by binding the ItemsSource to a hierarchical data source, or you can create and manage TreeViewNode objects yourself.

ツリー ビューを作成するには、TreeView コントロールと TreeViewNode オブジェクトの階層を使用します。To create a tree view, you use a TreeView control and a hierarchy of TreeViewNode objects. ノード階層を作成するには、ツリー ビュー コントロールのRootNodesコレクションに 1 つまたは複数のルート ノードを追加します。You create the node hierarchy by adding one or more root nodes to the TreeView control’s RootNodes collection. 各 TreeViewNode では、より多くのノードをその Children コレクションに追加することができます。Each TreeViewNode can then have more nodes added to its Children collection. ツリー ビュー ノードは、必要な任意の深さまで入れ子にすることができます。You can nest tree view nodes to whatever depth you require.

以降、Windows Insider Preview では、バインドできます階層データ ソース ツリー ビューのコンテンツを提供するItemsSourceプロパティをするリスト ビューの ItemsSource と同様です。Starting in the Windows Insider Preview, you can bind a hierarchical data source to the ItemsSource property to provide the tree view content, just as you would with ListView's ItemsSource. 同様に、項目を表示する DataTemplate を提供するItemTemplate (およびオプションのItemTemplateSelector) を使用します。Similarly, use ItemTemplate (and the optional ItemTemplateSelector) to provide a DataTemplate that renders the item.

重要

ItemsSource は、TreeView コントロールにコンテンツを移行させるに TreeView.RootNodes 代替メカニズムです。ItemsSource is an alternative mechanism to TreeView.RootNodes for putting content into the TreeView control. 同時に ItemsSource と RootNodes の両方を設定することはできません。You cannot set both ItemsSource and RootNodes at the same time. ItemsSource を使用して、ノードが作成された TreeView.RootNodes プロパティからアクセスすることができます。When you use ItemsSource, nodes created for you, and you can access them from TreeView.RootNodes property.

XAML で宣言された単純なツリー ビューの例を以下に示します。Here's an example of a simple tree view declared in XAML. 通常は、コードにノードを追加しますが、ノードの階層を作成する方法を視覚化するうえで役立つため、XAML の階層をここに示します。You typically add the nodes in code, but we show the XAML hierarchy here because it can be helpful for visualizing how the hierarchy of nodes is created.

<TreeView>
    <TreeView.RootNodes>
        <TreeViewNode Content="Flavors" IsExpanded="True">
            <TreeViewNode.Children>
                <TreeViewNode Content="Vanilla"/>
                <TreeViewNode Content="Strawberry"/>
                <TreeViewNode Content="Chocolate"/>
            </TreeViewNode.Children>
        </TreeViewNode>
    </TreeView.RootNodes>
</TreeView>

ほとんどの場合、ツリー ビューでは、通常、ルート TreeView コントロールを XAML で宣言しますが、TreeViewNode オブジェクトを追加コードやデータ バインディングを使うために、データ ソースからデータが表示されます。In most cases, your tree view displays data from a data source, so you typically declare the root TreeView control in XAML, but add the TreeViewNode objects in code or using data binding.

階層データ ソースにバインドします。Bind to a hierarchical data source

データ バインディングを使用して、ツリー ビューを作成するには、階層のコレクションを TreeView.ItemsSource プロパティに設定します。To create a tree view using data binding, set a hierarchical collection to the TreeView.ItemsSource property. ItemTemplate で子項目のコレクション プロパティに設定 TreeViewItem.ItemsSource します。Then in the ItemTemplate, set the child items collection to the TreeViewItem.ItemsSource property.

<TreeView ItemsSource="{x:Bind DataSource}">
    <TreeView.ItemTemplate>
        <DataTemplate x:DataType="local:Item">
            <TreeViewItem ItemsSource="{x:Bind Children}"
                          Content="{x:Bind Name}"/>
        </DataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

ツリー ビューのデータ バインディングを使用して_完全なコードの例」を参照してください。See _Tree view using data binding the Examples section for the full code.

項目と項目コンテナーItems and item containers

これらの Api は、コンテナーからノードまたはデータ項目を取得できる TreeView.ItemsSource を使用する場合と逆も同様です。If you use TreeView.ItemsSource, these APIs are available to get the node or data item from the container, and vice versa.

TreeViewItemTreeViewItem
TreeView.ItemFromContainerTreeView.ItemFromContainer 指定した TreeViewItem コンテナーのデータ項目を取得します。Gets the data item for the specified TreeViewItem container.
TreeView.ContainerFromItemTreeView.ContainerFromItem 指定したデータ項目の TreeViewItem コンテナーを取得します。Gets the TreeViewItem container for the specified data item.
TreeViewNodeTreeViewNode
TreeView.NodeFromContainerTreeView.NodeFromContainer 指定した TreeViewItem コンテナーの TreeViewNode を取得します。Gets the TreeViewNode for the specified TreeViewItem container.
TreeView.ContainerFromNodeTreeView.ContainerFromNode 指定した TreeViewNode TreeViewItem コンテナーを取得します。Gets the TreeViewItem container for the specified TreeViewNode.

ツリー ビュー ノードを管理します。Manage tree view nodes

このツリー ビューは、XAML で作成されたものと同じですが、ノードはコードで作成されています。This tree view is the same as the one created previously in XAML, but the nodes are created in code instead.

<TreeView x:Name="sampleTreeView"/>
private void InitializeTreeView()
{
    TreeViewNode rootNode = new TreeViewNode() { Content = "Flavors" };
    rootNode.IsExpanded = true;
    rootNode.Children.Add(new TreeViewNode() { Content = "Vanilla" });
    rootNode.Children.Add(new TreeViewNode() { Content = "Strawberry" });
    rootNode.Children.Add(new TreeViewNode() { Content = "Chocolate" });

    sampleTreeView.RootNodes.Add(rootNode);
}
Private Sub InitializeTreeView()
    Dim rootNode As New TreeViewNode With {.Content = "Flavors", .IsExpanded = True}
    With rootNode.Children
        .Add(New TreeViewNode With {.Content = "Vanilla"})
        .Add(New TreeViewNode With {.Content = "Strawberry"})
        .Add(New TreeViewNode With {.Content = "Chocolate"})
    End With
    sampleTreeView.RootNodes.Add(rootNode)
End Sub

これらの API は、ツリー ビューのデータの階層の管理に使用できます。These APIs are available for managing the data hierarchy of your tree view.

TreeViewTreeView
RootNodesRootNodes ツリー ビューは、1 つまたは複数のルート ノードの場合があります。A tree view can have one or more root nodes. TreeViewNode オブジェクトを RootNodes コレクションに追加し、ルート ノードを作成します。Add a TreeViewNode object to the RootNodes collection to create a root node. ルート ノードの Parent は常に null です。The Parent of a root node is always null. ルート ノードの奥行きは0です。The Depth of a root node is 0.
TreeViewNodeTreeViewNode
ChildrenChildren TreeViewNode オブジェクトを親ノードの Children コレクションに追加し、ノード階層を作成します。Add TreeViewNode objects to the Children collection of a parent node to create your node hierarchy. ノードは、その Children コレクションのすべてのノードの Parent です。A node is the Parent of all nodes in its Children collection.
HasChildrenHasChildren ノードが子を実体化した場合は truetrue if the node has realized children. false は空のフォルダーまたは項目を示します。false indicates an empty folder or an item.
HasUnrealizedChildrenHasUnrealizedChildren ノードが展開されているときにノードに入力している場合は、このプロパティを使用します。Use this property if you're filling nodes as they're expanded. この記事の後半にある「展開時にノードを入力する」をご覧ください。See Fill a node when it's expanding later in this article.
奥行きDepth 子ノードとルート ノードの距離を示します。Indicates how far from the root node a child node is.
ParentParent このノードが含まれている Children コレクションを所有する TreeViewNode を取得します。Gets the TreeViewNode that owns the Children collection that this node is part of.

ツリー ビューは、HasChildren プロパティと HasUnrealizedChildren プロパティを使用して、開く/閉じるアイコンを表示するかどうかを確認します。The tree view uses the HasChildren and HasUnrealizedChildren properties to determine whether the expand/collapse icon is shown. いずれかのプロパティが true である場合、アイコンが表示されます。それ以外の場合は表示されません。If either property is true, the icon is shown; otherwise, it's not shown.

ツリー ビュー ノード コンテンツTree view node content

ツリー ビュー ノードが Content プロパティで表すデータ項目を保存することができます。You can store the data item that a tree view node represents in its Content property.

前の例では、コンテンツは単純な文字列値でした。In the previous examples, the content was a simple string value. ここでは、ツリー ビュー ノードはユーザーのピクチャ フォルダーを表すため、ピクチャ ライブラリ StorageFolder はノードの Content プロパティに割り当てられます。Here, a tree view node represents the user's Pictures folder, so the pictures library StorageFolder is assigned to the node's Content property.

StorageFolder picturesFolder = KnownFolders.PicturesLibrary;
TreeViewNode pictureNode = new TreeViewNode();
pictureNode.Content = picturesFolder;
Dim picturesFolder As StorageFolder = KnownFolders.PicturesLibrary
Dim pictureNode As New TreeViewNode With {.Content = picturesFolder}

DataTemplate を指定して、ツリー ビューでのデータ項目の表示方法を指定することができます。You can provide a DataTemplate to specify how the data item is displayed in the tree view.

注意

Windows 10 バージョン 1803 では、コンテンツが文字列ではない場合は、TreeView コントロールを再テンプレート化し、カスタム ItemTemplate を指定する必要があります。In Windows 10, version 1803, you have to retemplate the TreeView control and specify a custom ItemTemplate if your content is not a string. 詳細については、この記事の終わりにある完全な例を参照してください。For more info, see the full example at the end of this article. それ以降のバージョンでは、 TreeView.ItemTemplateプロパティを設定します。In later versions, set the TreeView.ItemTemplate property.

項目コンテナーのスタイルItem container style

ItemsSource または RootNodes、– 各ノードを表示するために使用する実際の要素を使用するかどうか、「コンテナー」と呼ばれる – はTreeViewItemオブジェクトです。Whether you use ItemsSource or RootNodes, the actual elements used to display each node – called the "container" – is a TreeViewItem object. ツリー ビューを使用してコンテナーにスタイルを設定する ItemContainerStyle または ItemContainerStyleSelector プロパティ。You can style the container using the TreeView's ItemContainerStyle or ItemContainerStyleSelector properties.

項目テンプレート セレクターItem template selectors

項目の種類に基づいてツリー ビューの項目のさまざまな DataTemplate を設定することができます。You can choose to set a different DataTemplate for the tree view items based on the type of item. たとえば、アプリでは、ファイル エクスプ ローラーには、そのフォルダー、およびファイル用に別の 1 つのデータ テンプレートを使用します。For example, in a file explorer app, you could use one data template for folders, and another for files.

フォルダーとファイルの異なるデータ テンプレートを使用します。

作成して、項目テンプレート セレクターを使用する方法の例を次に示します。Here is an example of how to create and use an item template selector.

<Page.Resources>
    <DataTemplate x:Key="FolderTemplate" x:DataType="local:ExplorerItem">
        <TreeViewItem ItemsSource="{x:Bind Children}">
            <StackPanel Orientation="Horizontal">
                <Image Width="20" Source="Assets/folder.png"/>
                <TextBlock Text="{x:Bind Name}" />
            </StackPanel>
        </TreeViewItem>
    </DataTemplate>

    <DataTemplate x:Key="FileTemplate" x:DataType="local:ExplorerItem">
        <TreeViewItem>
            <StackPanel Orientation="Horizontal">
                <Image Width="20" Source="Assets/file.png"/>
                <TextBlock Text="{Binding Name}"/>
            </StackPanel>
        </TreeViewItem>
    </DataTemplate>

    <local:ExplorerItemTemplateSelector
            x:Key="ExplorerItemTemplateSelector"
            FolderTemplate="{StaticResource FolderTemplate}"
            FileTemplate="{StaticResource FileTemplate}" />
</Page.Resources>

<Grid>
    <TreeView ItemsSource="{x:Bind DataSource}"
              ItemTemplateSelector="{StaticResource ExplorerItemTemplateSelector}"/>
</Grid>
public class ExplorerItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate FolderTemplate { get; set; }
    public DataTemplate FileTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        var explorerItem = (ExplorerItem)item;
        if (explorerItem.Type == ExplorerItem.ExplorerItemType.Folder) return FolderTemplate;

        return FileTemplate;
    }
}

ツリー ビューの操作Interacting with a tree view

ユーザーが操作できるようにツリー ビューを構成する方法はいくつかあります。You can configure a tree view to let a user interact with it in several different ways:

  • ノードの展開と折りたたみexpand or collapse nodes
  • 項目の単一選択または複数選択single- or multi-select items
  • クリックして項目を呼び出すclick to invoke an item

展開/折りたたみExpand/collapse

子を持つ任意のツリー ビュー ノードは常に、展開/折りたたみグリフをクリックして展開または折りたたむことができます。Any tree view node that has children can always be expanded or collapsed by clicking the expand/collapse glyph. ノードをプログラムにより展開するか折りたたみ、ノードの状態が変化したときに対応することもできます。You can also expand or collapse a node programmatically, and respond when a node changes state.

ノードをプログラムにより展開/折りたたみExpand/collapse a node programmatically

コードでツリー ビュー ノードを展開したり、折りたたんだりする 2 つの方法があります。There are 2 ways you can expand or collapse a tree view node in your code.

  • TreeView クラスには Collapse メソッドと Expand メソッドが含まれています。The TreeView class has the Collapse and Expand methods. これらのメソッドを呼び出すと、展開または折りたたむ TreeViewNode を渡します。When you call these methods, you pass in the TreeViewNode that you want to expand or collapse.

  • TreeViewNode には IsExpanded プロパティが含まれています。Each TreeViewNode has the IsExpanded property. このプロパティを使用して、ノードの状態を確認したり、状態を変更するように設定したりできます。You can use this property to check the state of a node, or set it to change the state. このプロパティを XAML で設定し、ノードの初期状態に設定することもできます。You can also set this property in XAML to set the initial state of a node.

展開時にノードを入力するFill a node when it's expanding

ツリー ビューで多数のノードを表示しなければならない場合があります。または含まれるノードの数が前もってわからない場合があります。You might need to show a large number of nodes in your tree view, or you might not know ahead of time how many nodes it will have. TreeView コントロールは仮想化されていないため、リソースを管理するには、展開時に各ノードを入力し、折りたたみ時に子ノードを削除します。The TreeView control is not virtualized, so you can manage resources by filling each node as it's expanded, and removing the child nodes when it's collapsed.

展開 イベントを処理し、HasUnrealizedChildren プロパティを使用して展開時に子をノードに追加します。Handle the Expanding event and use the HasUnrealizedChildren property to add children to a node when it's being expanded. HasUnrealizedChildren プロパティは、ノードを入力する必要があるか、その Children コレクションが既に設定されているかどうかを示します。The HasUnrealizedChildren property indicates whether the node needs to be filled, or if its Children collection has already been populated. ことが重要 TreeViewNode はこの値を設定しない、アプリのコードで管理する必要があることに注意してください。It's important to remember that the TreeViewNode doesn't set this value, you need to manage it in your app code.

次の例は、使用中のこれらの API を示しています。Here's an example of these APIs in use. 'FillTreeNode' の実装を含むコンテキストについては、この記事の最後の完全なコード例をご覧ください。See the complete example code at the end of this article for context, including the implemetation of 'FillTreeNode'.

private void SampleTreeView_Expanding(TreeView sender, TreeViewExpandingEventArgs args)
{
    if (args.Node.HasUnrealizedChildren)
    {
        FillTreeNode(args.Node);
    }
}
Private Sub SampleTreeView_Expanding(sender As TreeView, args As TreeViewExpandingEventArgs)
    If args.Node.HasUnrealizedChildren Then
        FillTreeNode(args.Node)
    End If
End Sub

これは必須ではありませんが、Collapsed イベントを処理して、親ノードが閉じられたときに子ノードを削除することもできます。It's not required, but you might want to also handle the Collapsed event and remove the child nodes when the parent node is closed. これは、ツリー ビューに多くのノードがある場合、またはノード データが大量のリソースを使用している場合に重要です。This can be important if your tree view has many nodes, or if the node data uses a lot of resources. ノードを開くたびに入力することと、子をクローズド ノードにしたままにすることのパフォーマンスへの影響を考慮する必要があります。You should consider the performance impact of filling a node each time it's opened versus leaving the children on a closed node. 最適な選択肢は、アプリによって異なります。The best option will depend on your app.

この例では Collapsed イベントに対応するハンドラーを示します。Here's an example of a handler for the Collapsed event.

private void SampleTreeView_Collapsed(TreeView sender, TreeViewCollapsedEventArgs args)
{
    args.Node.Children.Clear();
    args.Node.HasUnrealizedChildren = true;
}
Private Sub SampleTreeView_Collapsed(sender As TreeView, args As TreeViewCollapsedEventArgs)
    args.Node.Children.Clear()
    args.Node.HasUnrealizedChildren = True
End Sub

項目の呼び出しInvoking an item

ユーザーは、項目を選択する代わりに操作 (ボタンのように項目を扱う) を呼び出すことができます。A user can invoke an action (treating the item like a button) instead of selecting the item. ItemInvoked イベントを処理してこのユーザー操作に対応します。You handle the ItemInvoked event to respond to this user interaction.

注意

IsItemClickEnabled プロパティが含まれる ListView とは異なり、アイテムの呼び出しとはツリー ビューで常に有効になっています。Unlike ListView, which has the IsItemClickEnabled property, invoking an item is always enabled on the tree view. イベントを処理するかどうか選択することができます。You can still choose whether to handle the event or not.

TreeViewItemInvokedEventArgs クラスTreeViewItemInvokedEventArgs class

ItemInvoked イベント引数は、呼び出された項目にアクセスを提供します。The ItemInvoked event args give you access to the invoked item. InvokedItem プロパティには呼び出されたノードが含まれています。The InvokedItem property has the node that was invoked. これを TreeViewNode にキャストし、データ項目を TreeViewNode.Content プロパティから取得できます。You can cast it to TreeViewNode and get the data item from the TreeViewNode.Content property.

ItemInvoked イベント ハンドラーの例を次に示します。Here's an example of an ItemInvoked event handler. データ項目は IStorageItem です。この例では、ファイルおよびツリーについての情報だけが表示されます。The data item is an IStorageItem, and this example just displays some info about the file and tree. また、ノードがフォルダー ノードの場合は、これを展開またはノードを同時に折りたたまれますです。Also, if the node is a folder node, it expands or collapses the node at the same time. それ以外の場合、ノードは山形マークをクリックした場合にのみ展開または折りたたまれます。Otherwise, the node expands or collapses only when the chevron is clicked.

private void SampleTreeView_ItemInvoked(TreeView sender, TreeViewItemInvokedEventArgs args)
{
    var node = args.InvokedItem as TreeViewNode;
    if (node.Content is IStorageItem item)
    {
        FileNameTextBlock.Text = item.Name;
        FilePathTextBlock.Text = item.Path;
        TreeDepthTextBlock.Text = node.Depth.ToString();

        if (node.Content is StorageFolder)
        {
            node.IsExpanded = !node.IsExpanded;
        }
    }
}
Private Sub SampleTreeView_ItemInvoked(sender As TreeView, args As TreeViewItemInvokedEventArgs)
    Dim node = TryCast(args.InvokedItem, TreeViewNode)
    Dim item = TryCast(node.Content, IStorageItem)
    If item IsNot Nothing Then
        FileNameTextBlock.Text = item.Name
        FilePathTextBlock.Text = item.Path
        TreeDepthTextBlock.Text = node.Depth.ToString()
        If TypeOf node.Content Is StorageFolder Then
            node.IsExpanded = Not node.IsExpanded
        End If
    End If
End Sub

項目の選択Item selection

TreeView コントロールでは、単一選択と複数選択の両方がサポートされています。The TreeView control supports both single-selection and multi-selection. 既定では、ノードの選択はオフになっていますが、TreeView.SelectionMode プロパティを設定してノードの選択を許可することができます。By default, selection of nodes is turned off, but you can set the TreeView.SelectionMode property to allow selection of nodes. TreeViewSelectionMode 値は NoneSingle、および Multiple です。The TreeViewSelectionMode values are None, Single, and Multiple.

複数選択Multiple selection

複数選択を有効にすると、各ツリー ビュー ノードの横にあるチェック ボックスを表示し、選択した項目が強調表示されています。When multiple selection is enabled, a checkbox is shown next to each tree view node, and selected items are highlighted. ユーザーは、チェック ボックスを使用して項目を選択または選択解除できます。項目は引き続きクリックして呼び出すことができます。A user can select or de-select an item by using the checkbox; clicking the item still causes it to be invoked.

選択、または親ノードを選択解除がオンまたはそのノードの下のすべての子の選択を解除します。Selecting or de-selecting a parent node will select or de-select all children under that node. 場合は、いくつかが、すべての親ノードの下の子が選択されて、親ノードのチェック ボックスが表示される、不確定 (黒のボックスに入力されます)。If some, but not all, of the children under a parent node are selected, the checkbox for the parent node is shown as indeterminate (filled with a black box).

ツリー ビューでの複数選択

選択、または親ノードを選択解除がオンまたはそのノードの下のすべての子の選択を解除します。Selecting or de-selecting a parent node will select or de-select all children under that node. 場合は、いくつかが、すべての親ノードの下の子が選択されて、親ノードのチェック ボックスが表示される、不確定 (黒のボックスに入力されます)。If some, but not all, of the children under a parent node are selected, the checkbox for the parent node is shown as indeterminate (filled with a black box).

ツリー ビューでの複数選択

選択したノードは、ツリー ビューの SelectedNodes コレクションに追加されます。Selected nodes are added to the tree view's SelectedNodes collection. SelectAll メソッドを呼び出して、ツリー ビューですべてのノードを選択できます。You can call the SelectAll method to select all the nodes in a tree view.

注意

SelectAll を呼び出した場合、SelectionMode にかかわらず、実体化されたすべてのノードが選択されます。If you call SelectAll, all realized nodes are selected, regardless of the SelectionMode. 一貫したユーザー エクスペリエンスを提供するため、SelectionMode が Multiple である場合にのみ SelectAll を呼び出す必要があります。To provide a consistent user experience, you should only call SelectAll if SelectionMode is Multiple.

選択と実体化された/実体化されていないノードSelection and realized/unrealized nodes

ツリー ビューに実体化されていないノードが含まれる場合、それらは選択肢として考慮されません。If your tree view has unrealized nodes, they are not taken into account for selection. 実体化されていないノードを選択する際に留意すべき点がいくつかあります。Here are some things you need to keep in mind regarding selection with unrealized nodes.

  • ユーザーが親ノードを選択すると、その親の下で実体化されたすべての子も選択されます。If a user selects a parent node, all the realized children under that parent are also selected. 同様に、すべての子ノードが選択されている場合、親ノードも選択されます。Similarly, if all the child nodes are selected, the parent node also becomes selected.
  • SelectAll メソッドは、実体化されたノードのみを SelectedNodes コレクションに追加します。The SelectAll method only adds realized nodes to the SelectedNodes collection.
  • 実体化されていない子を含む親ノードが選択された場合、子は実体化されたときに選択されます。If a parent node with unrealized children is selected, the children will be selected as they are realized.

コード例Code examples

XAML を使用して、ツリー ビューTree view using XAML

次の例は、XAML で 1 つのツリー ビュー構造を作成する方法を示しています。This example shows how to create a simple tree view structure in XAML. ツリー ビューは、カテゴリに配置されており、ユーザーが選択できるアイスクリームのフレーバーとトッピングを示しています。The tree view shows ice cream flavors and toppings that the user can choose from, arranged in categories. 複数選択が有効になっており、ユーザーがボタンをクリックすると、SelectedItems がメイン アプリ UI に表示されます。Multi-selection is enabled, and when the user clicks a button, the SelectedItems are displayed in the main app UI.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Padding="100">
    <SplitView IsPaneOpen="True"
               DisplayMode="Inline"
               OpenPaneLength="296">
        <SplitView.Pane>
            <TreeView x:Name="DessertTree" SelectionMode="Multiple">
                <TreeView.RootNodes>
                    <TreeViewNode Content="Flavors" IsExpanded="True">
                        <TreeViewNode.Children>
                            <TreeViewNode Content="Vanilla"/>
                            <TreeViewNode Content="Strawberry"/>
                            <TreeViewNode Content="Chocolate"/>
                        </TreeViewNode.Children>
                    </TreeViewNode>

                    <TreeViewNode Content="Toppings">
                        <TreeViewNode.Children>
                            <TreeViewNode Content="Candy">
                                <TreeViewNode.Children>
                                    <TreeViewNode Content="Chocolate"/>
                                    <TreeViewNode Content="Mint"/>
                                    <TreeViewNode Content="Sprinkles"/>
                                </TreeViewNode.Children>
                            </TreeViewNode>
                            <TreeViewNode Content="Fruits">
                                <TreeViewNode.Children>
                                    <TreeViewNode Content="Mango"/>
                                    <TreeViewNode Content="Peach"/>
                                    <TreeViewNode Content="Kiwi"/>
                                </TreeViewNode.Children>
                            </TreeViewNode>
                            <TreeViewNode Content="Berries">
                                <TreeViewNode.Children>
                                    <TreeViewNode Content="Strawberry"/>
                                    <TreeViewNode Content="Blueberry"/>
                                    <TreeViewNode Content="Blackberry"/>
                                </TreeViewNode.Children>
                            </TreeViewNode>
                        </TreeViewNode.Children>
                    </TreeViewNode>
                </TreeView.RootNodes>
            </TreeView>
        </SplitView.Pane>

        <StackPanel Grid.Column="1" Margin="12,0">
            <Button Content="Select all" Click="SelectAllButton_Click"/>
            <Button Content="Create order" Click="OrderButton_Click" Margin="0,12"/>
            <TextBlock Text="Your flavor selections:" Style="{StaticResource CaptionTextBlockStyle}"/>
            <TextBlock x:Name="FlavorList" Margin="0,0,0,12"/>
            <TextBlock Text="Your topping selections:" Style="{StaticResource CaptionTextBlockStyle}"/>
            <TextBlock x:Name="ToppingList"/>
        </StackPanel>
    </SplitView>
</Grid>
private void OrderButton_Click(object sender, RoutedEventArgs e)
{
    FlavorList.Text = string.Empty;
    ToppingList.Text = string.Empty;

    foreach (TreeViewNode node in DessertTree.SelectedNodes)
    {
        if (node.Parent.Content?.ToString() == "Flavors")
        {
            FlavorList.Text += node.Content + "; ";
        }
        else if (node.HasChildren == false)
        {
            ToppingList.Text += node.Content + "; ";
        }
    }
}

private void SelectAllButton_Click(object sender, RoutedEventArgs e)
{
    if (DessertTree.SelectionMode == TreeViewSelectionMode.Multiple)
    {
        DessertTree.SelectAll();
    }
}
Private Sub OrderButton_Click(sender As Object, e As RoutedEventArgs)
    FlavorList.Text = String.Empty
    ToppingList.Text = String.Empty
    For Each node As TreeViewNode In DessertTree.SelectedNodes
        If node.Parent.Content?.ToString() = "Flavors" Then
            FlavorList.Text += node.Content & "; "
        ElseIf node.HasChildren = False Then
            ToppingList.Text += node.Content & "; "
        End If
    Next
End Sub

Private Sub SelectAllButton_Click(sender As Object, e As RoutedEventArgs)
    If DessertTree.SelectionMode = TreeViewSelectionMode.Multiple Then
        DessertTree.SelectAll()
    End If
End Sub

データ バインディングを使用して、ツリー ビューTree view using data binding

この例では、前の例と同じツリー ビューを作成する方法を示します。This example shows how to create the same tree view as the previous example. ただし、XAML でのデータの階層を作成するのではなく、データはコードで作成され、ツリー ビューの ItemsSource プロパティにバインドされています。However, instead of creating the data hierarchy in XAML, the data is created in code and bound to the tree view's ItemsSource property. (前の例に示すように、ボタンのイベント ハンドラーに次の例も適用されます。)(The button event handlers shown in the previous example apply to this example also.)

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Padding="100">
    <SplitView IsPaneOpen="True"
               DisplayMode="Inline"
               OpenPaneLength="296">
        <SplitView.Pane>
            <TreeView Name="DessertTree"
                      SelectionMode="Multiple"
                      ItemsSource="{x:Bind DataSource}">
                <TreeView.ItemTemplate>
                    <DataTemplate x:DataType="local:Item">
                        <TreeViewItem ItemsSource="{x:Bind Children}"
                                      Content="{x:Bind Name}"/>
                    </DataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </SplitView.Pane>

        <StackPanel Grid.Column="1" Margin="12,0">
            <Button Content="Select all" Click="SelectAllButton_Click"/>
            <Button Content="Create order" Click="OrderButton_Click" Margin="0,12"/>
            <TextBlock Text="Your flavor selections:" Style="{StaticResource CaptionTextBlockStyle}"/>
            <TextBlock x:Name="FlavorList" Margin="0,0,0,12"/>
            <TextBlock Text="Your topping selections:" Style="{StaticResource CaptionTextBlockStyle}"/>
            <TextBlock x:Name="ToppingList"/>
        </StackPanel>
    </SplitView>
</Grid>
public sealed partial class MainPage : Page
{
    private ObservableCollection<Item> DataSource = new ObservableCollection<Item>();

    public MainPage()
    {
        this.InitializeComponent();
        DataSource = GetDessertData();
    }

    private ObservableCollection<Item> GetDessertData()
    {
        var list = new ObservableCollection<Item>();
        Item flavorsCategory = new Item()
        {
            Name = "Flavors",
            Children =
            {
                new Item() { Name = "Vanilla" },
                new Item() { Name = "Strawberry" },
                new Item() { Name = "Chocolate" }
            }
        };
        Item toppingsCategory = new Item()
        {
            Name = "Toppings",
            Children =
            {
                new Item()
                {
                    Name = "Candy",
                    Children =
                    {
                        new Item() { Name = "Chocolate" },
                        new Item() { Name = "Mint" },
                        new Item() { Name = "Sprinkles" }
                    }
                },
                new Item()
                {
                    Name = "Fruits",
                    Children =
                    {
                        new Item() { Name = "Mango" },
                        new Item() { Name = "Peach" },
                        new Item() { Name = "Kiwi" }
                    }
                },
                new Item()
                {
                    Name = "Berries",
                    Children =
                    {
                        new Item() { Name = "Strawberry" },
                        new Item() { Name = "Blueberry" },
                        new Item() { Name = "Blackberry" }
                    }
                }
            }
        };

        list.Add(flavorsCategory);
        list.Add(toppingsCategory);
        return list;
    }

    // Button event handlers...
}

public class Item
{
    public string Name { get; set; }
    public ObservableCollection<Item> Children { get; set; } = new ObservableCollection<Item>();

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

画像やミュージック ライブラリのツリー ビューPictures and Music Library tree view

この例では、ユーザーの画像やミュージック ライブラリのコンテンツや構造を表示するツリー ビューを作成する方法を示します。This example shows how to create a tree view that shows the contents and structure of the users Pictures and Music libraries. 項目の数は事前に知ることができないため、各ノードは展開時に入力され、折りたたまれたときに空になります。The number of items can't be known ahead of time, so each node is filled when it's expanded, and emptied when it's collapsed.

カスタム項目テンプレートは、型が IStorageItem であるデータ項目を表示するために使用されます。A custom item template is used to display the data items, which are of type IStorageItem.

重要

この例のコードでは、picturesLibrary 機能と musicLibrary 機能が必要です。The code in this example requires the picturesLibrary and musicLibrary capabilities. ファイル アクセスの詳細については、ファイル アクセス許可ファイルとフォルダーの列挙と照会、およびミュージック、画像、およびビデオ ライブラリのファイルとフォルダー をご覧ください。For more info about file access, see File access permissions, Enumerate and query files and folders, and Files and folders in the Music, Pictures, and Videos libraries.

<Page
    x:Class="TreeViewApp1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TreeViewApp1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <DataTemplate x:Key="TreeViewItemDataTemplate">
            <Grid Height="44">
                <TextBlock
                    Text="{Binding Content.DisplayName}"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Center"
                    Style="{ThemeResource BodyTextBlockStyle}"/>
            </Grid>
        </DataTemplate>

        <Style TargetType="TreeView">
            <Setter Property="IsTabStop" Value="False" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TreeView">
                        <TreeViewList x:Name="ListControl"
                                      ItemTemplate="{StaticResource TreeViewItemDataTemplate}"
                                      ItemContainerStyle="{StaticResource TreeViewItemStyle}"
                                      CanDragItems="True"
                                      AllowDrop="True"
                                      CanReorderItems="True">
                            <TreeViewList.ItemContainerTransitions>
                                <TransitionCollection>
                                    <ContentThemeTransition />
                                    <ReorderThemeTransition />
                                    <EntranceThemeTransition IsStaggeringEnabled="False" />
                                </TransitionCollection>
                            </TreeViewList.ItemContainerTransitions>
                        </TreeViewList>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Page.Resources>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <SplitView IsPaneOpen="True"
                   DisplayMode="Inline"
                   OpenPaneLength="296">
            <SplitView.Pane>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Button Content="Refresh tree" Click="RefreshButton_Click" Margin="24,12"/>
                    <TreeView x:Name="sampleTreeView" Grid.Row="1" SelectionMode="Single"
                              Expanding="SampleTreeView_Expanding"
                              Collapsed="SampleTreeView_Collapsed"
                              ItemInvoked="SampleTreeView_ItemInvoked"/>
                </Grid>
            </SplitView.Pane>

            <StackPanel Grid.Column="1" Margin="12,72">
                <TextBlock Text="File name:" Style="{StaticResource CaptionTextBlockStyle}"/>
                <TextBlock x:Name="FileNameTextBlock" Margin="0,0,0,12"/>

                <TextBlock Text="File path:" Style="{StaticResource CaptionTextBlockStyle}"/>
                <TextBlock x:Name="FilePathTextBlock" Margin="0,0,0,12"/>

                <TextBlock Text="Tree depth:" Style="{StaticResource CaptionTextBlockStyle}"/>
                <TextBlock x:Name="TreeDepthTextBlock" Margin="0,0,0,12"/>
            </StackPanel>
        </SplitView>
    </Grid>
</Page>
public MainPage()
{
    this.InitializeComponent();
    InitializeTreeView();
}

private void InitializeTreeView()
{
    // A TreeView can have more than 1 root node. The Pictures library
    // and the Music library will each be a root node in the tree.
    // Get Pictures library.
    StorageFolder picturesFolder = KnownFolders.PicturesLibrary;
    TreeViewNode pictureNode = new TreeViewNode();
    pictureNode.Content = picturesFolder;
    pictureNode.IsExpanded = true;
    pictureNode.HasUnrealizedChildren = true;
    sampleTreeView.RootNodes.Add(pictureNode);
    FillTreeNode(pictureNode);

    // Get Music library.
    StorageFolder musicFolder = KnownFolders.MusicLibrary;
    TreeViewNode musicNode = new TreeViewNode();
    musicNode.Content = musicFolder;
    musicNode.IsExpanded = true;
    musicNode.HasUnrealizedChildren = true;
    sampleTreeView.RootNodes.Add(musicNode);
    FillTreeNode(musicNode);
}

private async void FillTreeNode(TreeViewNode node)
{
    // Get the contents of the folder represented by the current tree node.
    // Add each item as a new child node of the node that's being expanded.

    // Only process the node if it's a folder and has unrealized children.
    StorageFolder folder = null;
    if (node.Content is StorageFolder && node.HasUnrealizedChildren == true)
    {
        folder = node.Content as StorageFolder;
    }
    else
    {
        // The node isn't a folder, or it's already been filled.
        return;
    }

    IReadOnlyList<IStorageItem> itemsList = await folder.GetItemsAsync();

    if (itemsList.Count == 0)
    {
        // The item is a folder, but it's empty. Leave HasUnrealizedChildren = true so
        // that the chevron appears, but don't try to process children that aren't there.
        return;
    }

    foreach (var item in itemsList)
    {
        var newNode = new TreeViewNode();
        newNode.Content = item;

        if (item is StorageFolder)
        {
            // If the item is a folder, set HasUnrealizedChildren to true. 
            // This makes the collapsed chevron show up.
            newNode.HasUnrealizedChildren = true;
        }
        else
        {
            // Item is StorageFile. No processing needed for this scenario.
        }
        node.Children.Add(newNode);
    }
    // Children were just added to this node, so set HasUnrealizedChildren to false.
    node.HasUnrealizedChildren = false;
}

private void SampleTreeView_Expanding(TreeView sender, TreeViewExpandingEventArgs args)
{
    if (args.Node.HasUnrealizedChildren)
    {
        FillTreeNode(args.Node);
    }
}

private void SampleTreeView_Collapsed(TreeView sender, TreeViewCollapsedEventArgs args)
{
    args.Node.Children.Clear();
    args.Node.HasUnrealizedChildren = true;
}

private void SampleTreeView_ItemInvoked(TreeView sender, TreeViewItemInvokedEventArgs args)
{
    var node = args.InvokedItem as TreeViewNode;
    if (node.Content is IStorageItem item)
    {
        FileNameTextBlock.Text = item.Name;
        FilePathTextBlock.Text = item.Path;
        TreeDepthTextBlock.Text = node.Depth.ToString();

        if (node.Content is StorageFolder)
        {
            node.IsExpanded = !node.IsExpanded;
        }
    }
}

private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
    sampleTreeView.RootNodes.Clear();
    InitializeTreeView();
}
Public Sub New()
    InitializeComponent()
    InitializeTreeView()
End Sub

Private Sub InitializeTreeView()
    ' A TreeView can have more than 1 root node. The Pictures library
    ' and the Music library will each be a root node in the tree.
    ' Get Pictures library.
    Dim picturesFolder As StorageFolder = KnownFolders.PicturesLibrary
    Dim pictureNode As New TreeViewNode With {
        .Content = picturesFolder,
        .IsExpanded = True,
        .HasUnrealizedChildren = True
    }
    sampleTreeView.RootNodes.Add(pictureNode)
    FillTreeNode(pictureNode)

    ' Get Music library.
    Dim musicFolder As StorageFolder = KnownFolders.MusicLibrary
    Dim musicNode As New TreeViewNode With {
        .Content = musicFolder,
        .IsExpanded = True,
        .HasUnrealizedChildren = True
    }
    sampleTreeView.RootNodes.Add(musicNode)
    FillTreeNode(musicNode)
End Sub

Private Async Sub FillTreeNode(node As TreeViewNode)
    ' Get the contents of the folder represented by the current tree node.
    ' Add each item as a new child node of the node that's being expanded.

    ' Only process the node if it's a folder and has unrealized children.
    Dim folder As StorageFolder = Nothing
    If TypeOf node.Content Is StorageFolder AndAlso node.HasUnrealizedChildren Then
        folder = TryCast(node.Content, StorageFolder)
    Else
        ' The node isn't a folder, or it's already been filled.
        Return
    End If

    Dim itemsList As IReadOnlyList(Of IStorageItem) = Await folder.GetItemsAsync()
    If itemsList.Count = 0 Then
        ' The item is a folder, but it's empty. Leave HasUnrealizedChildren = true so
        ' that the chevron appears, but don't try to process children that aren't there.
        Return
    End If

    For Each item In itemsList
        Dim newNode As New TreeViewNode With {
            .Content = item
        }
        If TypeOf item Is StorageFolder Then
            ' If the item is a folder, set HasUnrealizedChildren to True.
            ' This makes the collapsed chevron show up.
            newNode.HasUnrealizedChildren = True
        Else
            ' Item is StorageFile. No processing needed for this scenario.
        End If
        node.Children.Add(newNode)
    Next

    ' Children were just added to this node, so set HasUnrealizedChildren to False.
    node.HasUnrealizedChildren = False
End Sub

Private Sub SampleTreeView_Expanding(sender As TreeView, args As TreeViewExpandingEventArgs)
    If args.Node.HasUnrealizedChildren Then
        FillTreeNode(args.Node)
    End If
End Sub

Private Sub SampleTreeView_Collapsed(sender As TreeView, args As TreeViewCollapsedEventArgs)
    args.Node.Children.Clear()
    args.Node.HasUnrealizedChildren = True
End Sub

Private Sub SampleTreeView_ItemInvoked(sender As TreeView, args As TreeViewItemInvokedEventArgs)
    Dim node = TryCast(args.InvokedItem, TreeViewNode)
    Dim item = TryCast(node.Content, IStorageItem)
    If item IsNot Nothing Then
        FileNameTextBlock.Text = item.Name
        FilePathTextBlock.Text = item.Path
        TreeDepthTextBlock.Text = node.Depth.ToString()
        If TypeOf node.Content Is StorageFolder Then
            node.IsExpanded = Not node.IsExpanded
        End If
    End If
End Sub

Private Sub RefreshButton_Click(sender As Object, e As RoutedEventArgs)
    sampleTreeView.RootNodes.Clear()
    InitializeTreeView()
End Sub