Sdílet prostřednictvím


Stromové zobrazení

Ovládací prvek stromového zobrazení umožňuje hierarchický seznam s uzly, které mohou být rozbaleny a sbaleny a obsahují vnořené položky. Dá se použít k ilustraci struktury složek nebo vnořených relací v uživatelském rozhraní.

Stromové zobrazení používá kombinaci odsazení a ikon k reprezentaci vnořeného vztahu mezi nadřazenými a podřízenými uzly. Sbalené uzly používají dvojitou šipku směřující vpravo a rozbalené uzly používají dvojitou šipku směřující dolů.

Ikona dvojité šipky ve TreeView

Do šablony dat položky stromového zobrazení můžete zahrnout ikonu, která představuje uzly. Pokud například zobrazíte hierarchii systému souborů, můžete použít ikony složek pro nadřazené poznámky a ikony souborů pro uzly typu list.

Ikony šipky a složky v TreeViewu

Rozhraní API TreeView podporují následující funkce:

  • N-level vnoření
  • Výběr jednoho nebo více uzlů
  • Datová vazba na vlastnost ItemsSource ve TreeView a TreeViewItem
  • TreeViewItem jako kořen šablony položky TreeView
  • Různé typy obsahu v položce TreeViewItem
  • Přetažení mezi stromovými zobrazeními

Je to správná kontrola?

  • TreeView použijte, pokud mají položky vnořené položky seznamu, a když je důležité znázornit hierarchický vztah položek k jejich sousedním uzlům.

  • Nepoužívejte TreeView , pokud zvýraznění vnořené relace položky není prioritou. U většiny scénářů přechodu k podrobnostem je vhodné běžné zobrazení seznamu.

Vytvoření stromového zobrazení

Stromové zobrazení můžete vytvořit vytvořením vazby ItemsSource k hierarchickému zdroji dat nebo můžete vytvořit a spravovat objekty TreeViewNode sami.

Chcete-li vytvořit stromové zobrazení, použijte TreeView ovládací prvek a hierarchii TreeViewNode objekty. Hierarchii uzlů vytvoříte přidáním jednoho nebo více kořenových uzlů do kolekce RootNodes ovládacího prvku TreeView. Každý TreeViewNode může mít pak do své kolekce Children přidáno více uzlů. Uzly stromového zobrazení můžete vnořit do libovolné hloubky, kterou potřebujete.

Hierarchický zdroj dat můžete svázat s vlastností ItemsSource, abyste poskytli obsah stromového zobrazení, stejně jako byste to udělali s ListView a jeho vlastností ItemsSource. Podobně použijte ItemTemplate (a volitelný ItemTemplateSelector) k zadání DataTemplate , která vykreslí položku.

Důležité

ItemsSource a související rozhraní API vyžadují Windows 10 verze 1809 (SDK 17763) nebo novější nebo WinUI 2.

ItemsSource je alternativní mechanismus TreeView.RootNodes pro vložení obsahu do ovládacího prvku TreeView . Nelze nastavit jak ItemsSource, tak RootNodes současně. Pokud používáte ItemsSource, uzly jsou vytvořeny pro vás a můžete k nim přistupovat z TreeView.RootNodes vlastnost.

Tady je příklad jednoduchého stromového zobrazení deklarovaného v jazyce XAML. Obvykle přidáváte uzly v kódu, ale tady zobrazujeme hierarchii XAML, protože může být užitečné pro vizualizaci způsobu vytvoření hierarchie uzlů.

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

Ve většině případů stromové zobrazení zobrazuje data ze zdroje dat, takže obvykle deklarujete kořenový treeView ovládací prvek v XAML, ale přidáte TreeViewNode objekty v kódu nebo pomocí datové vazby.

Vytvoření vazby k hierarchickému zdroji dat

Chcete-li vytvořit stromové zobrazení pomocí datové vazby, nastavte hierarchickou kolekci na TreeView.ItemsSource vlastnost. Pak v ItemTemplate nastavte kolekci podřízených položek na vlastnost TreeViewItem.ItemsSource.

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

Zobrazení stromové struktury s využitím datové vazby pro celý kód

Položky a kontejnery na položky

Pokud používáte TreeView.ItemsSource, tato rozhraní API jsou k dispozici k získání uzlu nebo datové položky z kontejneru a naopak.

Objekt TreeViewItem Description
TreeView.ItemFromContainer Získá datovou položku pro zadaný kontejner TreeViewItem.
TreeView.ContainerFromItem Získá TreeViewItem kontejner pro zadanou datovou položku.
Uzel TreeViewNode Description
TreeView.NodeFromContainer Získá TreeViewNode pro zadaný TreeViewItem kontejner.
TreeView.ContainerFromNode Získá TreeViewItem kontejner pro zadaný TreeViewNode.

Správa uzlů stromového zobrazení

Toto stromové zobrazení je stejné jako to, které bylo dříve vytvořeno v XAML, ale uzly se vytvářejí v kódu.

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

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

Tato rozhraní API jsou k dispozici pro správu hierarchie dat ve stromovém zobrazení.

Pohled na strom Description
KořenovéUzly Stromové zobrazení může mít jeden nebo více kořenových uzlů. Přidejte Objekt TreeViewNode do kolekce RootNodes pro vytvoření kořenového uzlu. Nadřazený prvek kořenového uzlu je vždy null. Hloubka kořenového uzlu je 0.
Uzel TreeViewNode Description
Děti Přidejte objekty TreeViewNode do kolekce Children nadřazeného uzlu k vytvoření hierarchie uzlů. Uzel je rodič všech uzlů v kolekci potomků.
HasChildren true pokud uzel uvědomil podřízené položky. false označuje prázdnou složku nebo položku.
MáNeuskutečněnéDěti Tuto vlastnost použijte, pokud vyplňujete uzly během jejich rozbalování. Podívejte se na Vyplnění uzlu při rozbalování později v tomto článku.
Hloubka Určuje, jak daleko od kořenového uzlu se nachází podřízený uzel.
Rodič Získá TreeViewNode, který vlastní kolekci dětí, které je tento uzel součástí.

Stromové zobrazení používá vlastnosti HasChildren a HasUnrealizedChildren k určení, zda se zobrazí ikona pro rozbalení a sbalení. Pokud je tato vlastnost pravdivá, zobrazí se ikona; jinak se nezobrazí.

Obsah uzlu stromového zobrazení

Datovou položku, kterou uzel stromového zobrazení představuje, můžete uložit ve vlastnosti Obsah .

V předchozích příkladech byl obsah jednoduchou řetězcovou hodnotou. Uzel stromového zobrazení představuje složku Obrázky uživatele, takže knihovna obrázků StorageFolder je přiřazena k vlastnosti Obsah uzlu.

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

Poznámka:

Pokud chcete získat přístup ke složce Obrázky , musíte v manifestu aplikace zadat funkci Knihovna obrázků . Další informace najdete v deklarací funkcích aplikace .

Můžete zadat DataTemplate a určit způsob zobrazení datové položky ve stromovém zobrazení.

Poznámka:

Ve Windows 10 verze 1803 musíte znovu vytvořit šablonu ovládacího prvku TreeView a zadat vlastní ItemTemplate , pokud váš obsah není řetězec. V novějších verzích nastavte vlastnost ItemTemplate . Další informace najdete v tématu TreeView.ItemTemplate.

Styl kontejneru položek

Bez ohledu na to, zda používáte ItemsSource nebo RootNodes, skutečný prvek použitý k zobrazení každého uzlu – označovaného jako "kontejner" – je TreeViewItem objekt. Vlastnosti TreeViewItem můžete upravit, abyste mohli stylizovat kontejner pomocí vlastností TreeView, jako jsou ItemContainerStyle nebo ItemContainerStyleSelector.

Tento příklad ukazuje, jak změnit rozbalovací/sbalovací glyfy na oranžová znaménka +/-. Ve výchozí šabloně TreeViewItem jsou glyfy nastavené tak, aby používaly Segoe MDL2 Assets písmo. Vlastnost Setter.Value můžete nastavit zadáním znakové hodnoty Unicode ve formátu, který používá XAML, například takto: Value="&#xE948;".

<muxc:TreeView>
    <muxc:TreeView.ItemContainerStyle>
        <Style TargetType="muxc:TreeViewItem">
            <Setter Property="CollapsedGlyph" Value="&#xE948;"/>
            <Setter Property="ExpandedGlyph" Value="&#xE949;"/>
            <Setter Property="GlyphBrush" Value="DarkOrange"/>
        </Style>
    </muxc:TreeView.ItemContainerStyle>
    <muxc:TreeView.RootNodes>
        <muxc:TreeViewNode Content="Flavors"
               IsExpanded="True">
            <muxc:TreeViewNode.Children>
                <muxc:TreeViewNode Content="Vanilla"/>
                <muxc:TreeViewNode Content="Strawberry"/>
                <muxc:TreeViewNode Content="Chocolate"/>
            </muxc:TreeViewNode.Children>
        </muxc:TreeViewNode>
    </muxc:TreeView.RootNodes>
</muxc:TreeView>

Selektory šablon položek

TreeView ve výchozím nastavení zobrazuje řetězcovou reprezentaci datové položky pro každý uzel. Vlastnost ItemTemplate můžete nastavit tak, aby změnila, co se zobrazí pro všechny uzly. Nebo můžete pomocí ItemTemplateSelector zvolit pro položky stromového zobrazení jinou hodnotu DataTemplate na základě typu položky nebo jiných zadaných kritérií.

V aplikaci Průzkumníka souborů můžete například použít jednu šablonu dat pro složky a jinou pro soubory.

Složky a soubory používající různé šablony dat

Zde je příklad, jak vytvořit a použít selektor šablony položky. Další informace naleznete v DataTemplateSelector třída.

Poznámka:

Tento kód je součástí většího příkladu a nebude fungovat samostatně. Úplný příklad včetně kódu, který definuje ExplorerItem, najdete v úložišti Xaml-Controls-Gallery na GitHubu. TreeViewPage.xaml a TreeViewPage.xaml.cs obsahují příslušný kód.

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

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

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

<Grid>
    <muxc: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;
    }
}

Typ objektu předaného metodě SelectTemplateCore závisí na tom, zda vytváříte stromovou strukturu nastavením vlastnosti ItemsSource, nebo vytvořením a správou objektů TreeViewNode sami.

  • Pokud je položka ItemsSource nastavená, bude objekt libovolného typu datové položky. V předchozím příkladu byl objekt objektem ExplorerItem, takže jej bylo možné použít po jednoduchém přetypování na ExplorerItem: var explorerItem = (ExplorerItem)item;.
  • Pokud ItemsSource není nastaven a spravujete uzly stromového zobrazení sami, objekt předaný SelectTemplateCore je TreeViewNode. V tomto případě můžete získat datovou položku z vlastnosti TreeViewNode.Content.

Tady je volba šablony dat ze stromového zobrazení v knihovně obrázků a hudby příkladu, který je předveden později. Metoda SelectTemplateCore obdržíTreeViewNode , který může mít buď StorageFolder, nebo StorageFile jako svůj obsah. Na základě obsahu můžete vrátit výchozí šablonu nebo konkrétní šablonu pro hudební složku, složku obrázků, hudební soubory nebo soubory obrázků.

protected override DataTemplate SelectTemplateCore(object item)
{
    var node = (TreeViewNode)item;
    if (node.Content is StorageFolder)
    {
        var content = node.Content as StorageFolder;
        if (content.DisplayName.StartsWith("Pictures")) return PictureFolderTemplate;
        if (content.DisplayName.StartsWith("Music")) return MusicFolderTemplate;
    }
    else if (node.Content is StorageFile)
    {
        var content = node.Content as StorageFile;
        if (content.ContentType.StartsWith("image")) return PictureItemTemplate;
        if (content.ContentType.StartsWith("audio")) return MusicItemTemplate;
    }
    return DefaultTemplate;
}
Protected Overrides Function SelectTemplateCore(ByVal item As Object) As DataTemplate
    Dim node = CType(item, muxc.TreeViewNode)

    If TypeOf node.Content Is StorageFolder Then
        Dim content = TryCast(node.Content, StorageFolder)
        If content.DisplayName.StartsWith("Pictures") Then Return PictureFolderTemplate
        If content.DisplayName.StartsWith("Music") Then Return MusicFolderTemplate
    ElseIf TypeOf node.Content Is StorageFile Then
        Dim content = TryCast(node.Content, StorageFile)
        If content.ContentType.StartsWith("image") Then Return PictureItemTemplate
        If content.ContentType.StartsWith("audio") Then Return MusicItemTemplate
    End If

    Return DefaultTemplate
End Function

Interakce se stromovým zobrazením

Stromové zobrazení můžete nakonfigurovat tak, aby s ním uživatel mohl pracovat několika různými způsoby:

  • Rozbalit nebo sbalit uzly
  • Položky s jedním nebo vícenásobným výběrem
  • Kliknutím vyvoláte položku.

Rozbalit nebo sbalit

Libovolný uzel stromového zobrazení, který obsahuje podřízené položky, lze kdykoli rozbalit nebo sbalit kliknutím na ikonu rozbalení nebo sbalení. Uzel můžete také rozbalit nebo sbalit programově a reagovat na změnu stavu uzlu.

Rozbalení/sbalení uzlu programově

V kódu můžete uzel stromového zobrazení rozbalit nebo sbalit dvěma způsoby.

  • TreeView třída má Sbalit a Rozbalit metody. Při volání těchto metod předáte TreeViewNode , který chcete rozbalit nebo sbalit.

  • Každý TreeViewNodeIsExpanded vlastnost. Tuto vlastnost můžete použít ke kontrole stavu uzlu nebo k jeho nastavení pro změnu stavu. Tuto vlastnost můžete také nastavit v JAZYCE XAML a nastavit tak počáteční stav uzlu.

Vyplňte uzel, když se rozšiřuje

Možná budete muset ve stromovém zobrazení zobrazit velký počet uzlů nebo nemusíte předem vědět, kolik uzlů bude obsahovat. Ovládací prvek TreeView není virtualizovaný, takže prostředky můžete spravovat vyplněním každého uzlu při jeho rozbalení a odebráním podřízených uzlů, když je sbalený.

Zpracovat událost Expanding a použít vlastnost HasUnrealizedChildren k přidání podřízených položek do uzlu při jeho rozbalení. HasUnrealizedChildren vlastnost označuje, zda uzel musí být vyplněn, nebo zda je jeho Children kolekce již naplněna. Je důležité si uvědomit, že TreeViewNode nenastavuje tuto hodnotu, musíte ji spravovat v kódu aplikace.

Tady je příklad těchto rozhraní API, která se používají. Úplný ukázkový kód na konci tohoto článku najdete v kontextu, včetně implementace FillTreeNode.

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

Není to povinné, ale možná budete chtít také zpracovat sbalenou událost a odebrat podřízené uzly při zavření nadřazeného uzlu. To může být důležité, pokud stromové zobrazení obsahuje mnoho uzlů nebo pokud data uzlu používají velké množství prostředků. Měli byste zvážit dopad plnění uzlu při každém jeho otevření oproti ponechání podřízených uzlů na uzavřeném uzlu. Nejlepší možnost bude záviset na vaší aplikaci.

Tady je příklad obslužné rutiny pro sbalenou událost.

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

Vyvolání položky

Uživatel může vyvolat akci (zacházet s položkou jako s tlačítkem) namísto výběru položky. Zpracováváte událost ItemInvolat za účelem reakce na tuto interakci uživatele.

Poznámka:

Na rozdíl od ListView, který má IsItemClickEnabled vlastnost, vyvolání položky je vždy povoleno ve stromovém zobrazení. Stále můžete zvolit, jestli se má událost zpracovat, nebo ne.

TreeViewItemInvokedEventArgs – třída

Argumenty události ItemInvoked umožňují přístup k aktivované položce. Vlastnost InvokedItem má uzel, který byl vyvolán. Můžete jej přetypovat na TreeViewNode a získat datovou položku z vlastnosti TreeViewNode.Content.

Tady je příklad obslužné rutiny události ItemInvoked. Datová položka je IStorageItem a v tomto příkladu se zobrazí jenom některé informace o souboru a stromu. Pokud je uzel uzlem složky, rozbalí nebo sbalí uzel současně. V opačném případě se uzel rozbalí nebo sbalí pouze po kliknutí na šipku.

private void SampleTreeView_ItemInvoked(muxc.TreeView sender, muxc.TreeViewItemInvokedEventArgs args)
{
    var node = args.InvokedItem as muxc.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 muxc.TreeView, args As muxc.TreeViewItemInvokedEventArgs)
    Dim node = TryCast(args.InvokedItem, muxc.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

Výběr položky

Ovládací prvek TreeView podporuje jeden výběr i vícenásobný výběr. Ve výchozím nastavení je výběr uzlů vypnutý, ale můžete nastavit TreeView.SelectionMode vlastnost povolit výběr uzlů. Hodnoty TreeViewSelectionMode jsou None, Singlea Multiple.

Vícenásobný výběr

Pokud je povoleno více výběrů, zobrazí se vedle každého uzlu stromového zobrazení zaškrtávací políčko a vybrané položky se zvýrazní. Uživatel může vybrat nebo zrušit výběr položky pomocí zaškrtávacího políčka; kliknutím na položku je stále vyvolána.

Výběrem nebo zrušením výběru nadřazeného uzlu vyberete nebo zrušíte výběr všech podřízených uzlů. Pokud jsou zaškrtnuté některé, ale ne všechny děti pod nadřazeným uzlem, zobrazí se zaškrtávací políčko nadřazeného uzlu v neurčitém stavu.

Vícenásobný výběr ve stromovém zobrazení

Vybrané uzly se přidají do kolekce SelectedNodes zobrazení stromu. K výběru všech uzlů ve stromovém zobrazení můžete zavolat metodu SelectAll.

Poznámka:

Pokud provedete SelectAll, jsou vybrány všechny realizované uzly bez ohledu na SelectionMode. Pokud chcete zajistit konzistentní uživatelské prostředí, měli byste volat pouze SelectAll, pokud je SelectionModeMultiple.

Výběr a realizované/nerealizované uzly

Pokud má stromové zobrazení nerealizované uzly, nejsou při výběru brány v úvahu. Tady je několik věcí, které je potřeba mít na paměti, pokud jde o výběr s nerealizovanými uzly.

  • Pokud uživatel vybere nadřazený uzel, vyberou se také všechny realizované podřízené položky v rámci daného nadřazeného objektu. Podobně pokud jsou všechny podřízené uzly vybrány, nadřazený uzel se rovněž vybere.
  • Metoda SelectAll přidá do kolekce SelectedNodes pouze realizované uzly .
  • Pokud je vybrán nadřazený uzel s nerealizovanými podřízenými uzly, budou podřízené uzly postupně vybírány při jejich realizaci.

VybranýPrvek/VybranéPrvky

TreeView má SelectedItem a SelectedItems vlastnosti. Tyto vlastnosti můžete použít k přímému získání obsahu vybraných uzlů. Pokud je povoleno více výběrů, SelectedItem obsahuje první položku v kolekci SelectedItems.

ZměnaVýběru

Událost SelectionChanged můžete zpracovat tak, aby reagovala, když se kolekce vybraných položek změní programově nebo prostřednictvím interakce uživatele.

<TreeView ItemsSource="{x:Bind Folders}"
          SelectionMode="Multiple"
          SelectionChanged="TreeView_SelectionChanged"/>
public void TreeView_SelectionChanged(TreeView sender, TreeViewSelectionChangedEventArgs args)
{
    foreach (object item in args.RemovedItems)
    {
        this.SelectedFolders.Remove((Folder)item);
    }

    foreach (object item in args.AddedItems)
    {
        this.SelectedFolders.Add((Folder)item);
    }
}

Příklady kódu

Následující příklady kódu ukazují různé funkce ovládacího prvku stromového zobrazení.

Stromové zobrazení s využitím XAML

Tento příklad ukazuje, jak vytvořit jednoduchou strukturu stromového zobrazení v XAML. Stromové zobrazení ukazuje zmrzlinové příchutě a posypy, ze kterých si uživatel může vybrat, uspořádané do kategorií. Je povoleno vícenásobný výběr a když uživatel klikne na tlačítko, zobrazí se vybrané položky v hlavním uživatelském rozhraní aplikace.

<Page
    x:Class="TreeViewTest.MainPage"
    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:muxc="using:Microsoft.UI.Xaml.Controls"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

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

                        <muxc:TreeViewNode Content="Toppings">
                            <muxc:TreeViewNode.Children>
                                <muxc:TreeViewNode Content="Candy">
                                    <muxc:TreeViewNode.Children>
                                        <muxc:TreeViewNode Content="Chocolate"/>
                                        <muxc:TreeViewNode Content="Mint"/>
                                        <muxc:TreeViewNode Content="Sprinkles"/>
                                    </muxc:TreeViewNode.Children>
                                </muxc:TreeViewNode>
                                <muxc:TreeViewNode Content="Fruits">
                                    <muxc:TreeViewNode.Children>
                                        <muxc:TreeViewNode Content="Mango"/>
                                        <muxc:TreeViewNode Content="Peach"/>
                                        <muxc:TreeViewNode Content="Kiwi"/>
                                    </muxc:TreeViewNode.Children>
                                </muxc:TreeViewNode>
                                <muxc:TreeViewNode Content="Berries">
                                    <muxc:TreeViewNode.Children>
                                        <muxc:TreeViewNode Content="Strawberry"/>
                                        <muxc:TreeViewNode Content="Blueberry"/>
                                        <muxc:TreeViewNode Content="Blackberry"/>
                                    </muxc:TreeViewNode.Children>
                                </muxc:TreeViewNode>
                            </muxc:TreeViewNode.Children>
                        </muxc:TreeViewNode>
                    </muxc:TreeView.RootNodes>
                </muxc: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>
</Page>
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using muxc = Microsoft.UI.Xaml.Controls;

namespace TreeViewTest
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void OrderButton_Click(object sender, RoutedEventArgs e)
        {
            FlavorList.Text = string.Empty;
            ToppingList.Text = string.Empty;

            foreach (muxc.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 == muxc.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 muxc.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 = muxc.TreeViewSelectionMode.Multiple Then
        DessertTree.SelectAll()
    End If
End Sub

Stromové zobrazení s využitím datové vazby

Tento příklad ukazuje, jak vytvořit stejné stromové zobrazení jako v předchozím příkladu. Místo vytvoření hierarchie dat v xaml se však data vytvoří v kódu a jsou svázaná s vlastností ItemsSource zobrazení stromové struktury. (Obslužné rutiny událostí tlačítka zobrazené v předchozím příkladu platí také pro tento příklad.)

<Page
    x:Class="TreeViewTest.MainPage"
    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:muxc="using:Microsoft.UI.Xaml.Controls"
    xmlns:local="using:TreeViewTest"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

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

</Page>
using System.Collections.ObjectModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using muxc = Microsoft.UI.Xaml.Controls;

namespace TreeViewTest
{
    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;
        }

        private void OrderButton_Click(object sender, RoutedEventArgs e)
        {
            FlavorList.Text = string.Empty;
            ToppingList.Text = string.Empty;

            foreach (muxc.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 == muxc.TreeViewSelectionMode.Multiple)
            {
                DessertTree.SelectAll();
            }
        }
    }

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

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

Stromové zobrazení knihovny obrázků a hudby

Tento příklad ukazuje, jak vytvořit stromové zobrazení, které zobrazuje obsah a strukturu knihoven Obrázků a hudby uživatele. Počet položek nelze předem určit, takže se každý uzel naplní při rozbalení a vyprázdní při sbalení.

Šablona vlastní položky slouží k zobrazení datových položek, které jsou typu IStorageItem.

Důležité

Kód v tomto příkladu vyžaduje možnosti picturesLibrary a musicLibrary . Další informace o přístupu k souborům najdete v tématech Oprávnění k přístupu k souborům, výčet a dotazování souborů a složek a souborů a složek v knihovnách Hudba, Obrázky a Videa.

<Page
    x:Class="TreeViewTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TreeViewTest"
    xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
    xmlns:storage="using:Windows.Storage"
    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" x:DataType="muxc:TreeViewNode">
            <Grid Height="44">
                <TextBlock Text="{x:Bind ((storage:IStorageItem)Content).Name}"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Center"
                           Style="{ThemeResource BodyTextBlockStyle}"/>
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="MusicItemDataTemplate" x:DataType="muxc:TreeViewNode">
            <StackPanel Height="44" Orientation="Horizontal">
                <SymbolIcon Symbol="Audio" Margin="0,0,4,0"/>
                <TextBlock Text="{x:Bind ((storage:StorageFile)Content).DisplayName}"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Center"
                           Style="{ThemeResource BodyTextBlockStyle}"/>
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="PictureItemDataTemplate" x:DataType="muxc:TreeViewNode">
            <StackPanel Height="44" Orientation="Horizontal">
                <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xEB9F;"
                          Margin="0,0,4,0"/>
                <TextBlock Text="{x:Bind ((storage:StorageFile)Content).DisplayName}"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Center"
                           Style="{ThemeResource BodyTextBlockStyle}"/>
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="MusicFolderDataTemplate" x:DataType="muxc:TreeViewNode">
            <StackPanel Height="44" Orientation="Horizontal">
                <SymbolIcon Symbol="MusicInfo" Margin="0,0,4,0"/>
                <TextBlock Text="{x:Bind ((storage:StorageFolder)Content).DisplayName}"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Center"
                           Style="{ThemeResource BodyTextBlockStyle}"/>
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="PictureFolderDataTemplate" x:DataType="muxc:TreeViewNode">
            <StackPanel Height="44" Orientation="Horizontal">
                <SymbolIcon Symbol="Pictures" Margin="0,0,4,0"/>
                <TextBlock Text="{x:Bind ((storage:StorageFolder)Content).DisplayName}"
                           HorizontalAlignment="Left"
                           VerticalAlignment="Center"
                           Style="{ThemeResource BodyTextBlockStyle}"/>
            </StackPanel>
        </DataTemplate>

        <local:ExplorerItemTemplateSelector
            x:Key="ExplorerItemTemplateSelector"
            DefaultTemplate="{StaticResource TreeViewItemDataTemplate}"
            MusicItemTemplate="{StaticResource MusicItemDataTemplate}"
            MusicFolderTemplate="{StaticResource MusicFolderDataTemplate}"
            PictureItemTemplate="{StaticResource PictureItemDataTemplate}"
            PictureFolderTemplate="{StaticResource PictureFolderDataTemplate}"/>
    </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"/>
                    <muxc:TreeView x:Name="sampleTreeView" Grid.Row="1" SelectionMode="Single"
                              ItemTemplateSelector="{StaticResource ExplorerItemTemplateSelector}"
                              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>
using System;
using System.Collections.Generic;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using muxc = Microsoft.UI.Xaml.Controls;

namespace TreeViewTest
{
    public sealed partial class MainPage : 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;
            muxc.TreeViewNode pictureNode = new muxc.TreeViewNode();
            pictureNode.Content = picturesFolder;
            pictureNode.IsExpanded = true;
            pictureNode.HasUnrealizedChildren = true;
            sampleTreeView.RootNodes.Add(pictureNode);
            FillTreeNode(pictureNode);

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

        private async void FillTreeNode(muxc.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 muxc.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(muxc.TreeView sender, muxc.TreeViewExpandingEventArgs args)
        {
            if (args.Node.HasUnrealizedChildren)
            {
                FillTreeNode(args.Node);
            }
        }

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

        private void SampleTreeView_ItemInvoked(muxc.TreeView sender, muxc.TreeViewItemInvokedEventArgs args)
        {
            var node = args.InvokedItem as muxc.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 class ExplorerItemTemplateSelector : DataTemplateSelector
    {
        public DataTemplate DefaultTemplate { get; set; }
        public DataTemplate MusicItemTemplate { get; set; }
        public DataTemplate PictureItemTemplate { get; set; }
        public DataTemplate MusicFolderTemplate { get; set; }
        public DataTemplate PictureFolderTemplate { get; set; }

        protected override DataTemplate SelectTemplateCore(object item)
        {
            var node = (muxc.TreeViewNode)item;

            if (node.Content is StorageFolder)
            {
                var content = node.Content as StorageFolder;
                if (content.DisplayName.StartsWith("Pictures")) return PictureFolderTemplate;
                if (content.DisplayName.StartsWith("Music")) return MusicFolderTemplate;
            }
            else if (node.Content is StorageFile)
            {
                var content = node.Content as StorageFile;
                if (content.ContentType.StartsWith("image")) return PictureItemTemplate;
                if (content.ContentType.StartsWith("audio")) return MusicItemTemplate;

            }
            return DefaultTemplate;
        }
    }
}
Public NotInheritable Class MainPage
    Inherits Page

    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 muxc.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 muxc.TreeViewNode With {
        .Content = musicFolder,
        .IsExpanded = True,
        .HasUnrealizedChildren = True
    }
        sampleTreeView.RootNodes.Add(musicNode)
        FillTreeNode(musicNode)
    End Sub

    Private Async Sub FillTreeNode(node As muxc.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 muxc.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 muxc.TreeView, args As muxc.TreeViewExpandingEventArgs)
        If args.Node.HasUnrealizedChildren Then
            FillTreeNode(args.Node)
        End If
    End Sub

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

    Private Sub SampleTreeView_ItemInvoked(sender As muxc.TreeView, args As muxc.TreeViewItemInvokedEventArgs)
        Dim node = TryCast(args.InvokedItem, muxc.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

End Class

Public Class ExplorerItemTemplateSelector
    Inherits DataTemplateSelector

    Public Property DefaultTemplate As DataTemplate
    Public Property MusicItemTemplate As DataTemplate
    Public Property PictureItemTemplate As DataTemplate
    Public Property MusicFolderTemplate As DataTemplate
    Public Property PictureFolderTemplate As DataTemplate

    Protected Overrides Function SelectTemplateCore(ByVal item As Object) As DataTemplate
        Dim node = CType(item, muxc.TreeViewNode)

        If TypeOf node.Content Is StorageFolder Then
            Dim content = TryCast(node.Content, StorageFolder)
            If content.DisplayName.StartsWith("Pictures") Then Return PictureFolderTemplate
            If content.DisplayName.StartsWith("Music") Then Return MusicFolderTemplate
        ElseIf TypeOf node.Content Is StorageFile Then
            Dim content = TryCast(node.Content, StorageFile)
            If content.ContentType.StartsWith("image") Then Return PictureItemTemplate
            If content.ContentType.StartsWith("audio") Then Return MusicItemTemplate
        End If

        Return DefaultTemplate
    End Function
End Class

Přetáhněte a pusťte položky mezi stromová zobrazení

Následující příklad ukazuje, jak vytvořit dvě stromová zobrazení, jejichž položky lze přetáhnout a přetáhnout mezi sebou. Když je položka přetažena do jiného stromového zobrazení, přidá se na konec seznamu. Položky se ale dají v zobrazení stromové struktury znovu uspořádat. Tento příklad také bere v úvahu pouze zobrazení stromu s jedním kořenovým uzlem.

<Page
    x:Class="TreeViewTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <TreeView x:Name="treeView1"
                  AllowDrop="True"
                  CanDragItems="True"
                  CanReorderItems="True"
                  DragOver="TreeView_DragOver"
                  Drop="TreeView_Drop"
                  DragItemsStarting="TreeView_DragItemsStarting"
                  DragItemsCompleted="TreeView_DragItemsCompleted"/>
        <TreeView x:Name="treeView2"
                  AllowDrop="True"
                  Grid.Column="1"
                  CanDragItems="True"
                  CanReorderItems="True"
                  DragOver="TreeView_DragOver"
                  Drop="TreeView_Drop"
                  DragItemsStarting="TreeView_DragItemsStarting"
                  DragItemsCompleted="TreeView_DragItemsCompleted"/>

    </Grid>

</Page>
using System;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace TreeViewTest
{
    public sealed partial class MainPage : Page
    {
        private TreeViewNode deletedItem;
        private TreeView sourceTreeView;

        public MainPage()
        {
            this.InitializeComponent();
            InitializeTreeView();
        }

        private void InitializeTreeView()
        {
            TreeViewNode parentNode1 = new TreeViewNode() { Content = "tv1" };
            TreeViewNode parentNode2 = new TreeViewNode() { Content = "tv2" };

            parentNode1.Children.Add(new TreeViewNode() { Content = "tv1FirstChild" });
            parentNode1.Children.Add(new TreeViewNode() { Content = "tv1SecondChild" });
            parentNode1.Children.Add(new TreeViewNode() { Content = "tv1ThirdChild" });
            parentNode1.Children.Add(new TreeViewNode() { Content = "tv1FourthChild" });
            parentNode1.IsExpanded = true;
            treeView1.RootNodes.Add(parentNode1);

            parentNode2.Children.Add(new TreeViewNode() { Content = "tv2FirstChild" });
            parentNode2.Children.Add(new TreeViewNode() { Content = "tv2SecondChild" });
            parentNode2.IsExpanded = true;
            treeView2.RootNodes.Add(parentNode2);
        }

        private void TreeView_DragOver(object sender, DragEventArgs e)
        {
            if (e.DataView.Contains(StandardDataFormats.Text))
            {
                e.AcceptedOperation = DataPackageOperation.Move;
            }
        }

        private async void TreeView_Drop(object sender, DragEventArgs e)
        {
            if (e.DataView.Contains(StandardDataFormats.Text))
            {
                string text = await e.DataView.GetTextAsync();
                TreeView destinationTreeView = sender as TreeView;

                if (destinationTreeView.RootNodes != null)
                {
                    TreeViewNode newNode = new TreeViewNode() { Content = text };
                    destinationTreeView.RootNodes[0].Children.Add(newNode);
                    deletedItem = newNode;
                }
            }
        }

        private void TreeView_DragItemsStarting(TreeView sender, TreeViewDragItemsStartingEventArgs args)
        {
            if (args.Items.Count == 1)
            {
                args.Data.RequestedOperation = DataPackageOperation.Move;
                sourceTreeView = sender;

                foreach (var item in args.Items)
                {
                    args.Data.SetText(item.ToString());
                }
            }
        }

        private void TreeView_DragItemsCompleted(TreeView sender, TreeViewDragItemsCompletedEventArgs args)
        {
            var children = sourceTreeView.RootNodes[0].Children;

            if (deletedItem != null)
            {
                for (int i = 0; i < children.Count; i++)
                {
                    if (children[i].Content.ToString() == deletedItem.Content.ToString())
                    {
                        children.RemoveAt(i);
                        break;
                    }
                }
            }

            sourceTreeView = null;
            deletedItem = null;
        }
    }
}

Univerzální platforma Windows a WinUI 2

Důležité

Informace a příklady v tomto článku jsou optimalizované pro aplikace, které používají Windows App SDK a WinUI 3, ale obecně platí pro aplikace pro UPW, které používají WinUI 2. Informace o konkrétních platformách a příklady najdete v referenčních informacích k rozhraní API pro UPW.

Tato část obsahuje informace potřebné pro použití ovládacího prvku v aplikacích UWP nebo WinUI 2.

TreeView pro aplikace pro UPW je součástí WinUI 2. Další informace, včetně pokynů k instalaci, najdete v tématu WinUI 2. Rozhraní API pro tento ovládací prvek existují jak v oboru názvů Windows.UI.Xaml.Controls (UWP), tak v oboru názvů Microsoft.UI.Xaml.Controls (WinUI).

K získání nejnovějších stylů, šablon a funkcí pro všechny ovládací prvky doporučujeme použít nejnovější winUI 2 .

Pokud chcete použít kód v tomto článku s WinUI 2, použijte alias v JAZYCE XAML (používáme muxc) k reprezentaci rozhraní API knihovny uživatelského rozhraní Systému Windows, která jsou součástí vašeho projektu. Další informace najdete v tématu Začínáme s WinUI 2 .

xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

<muxc:TreeView>
    <muxc:TreeView.RootNodes>
        <muxc:TreeViewNode Content="Flavors">
            <muxc:TreeViewNode.Children>
                <muxc:TreeViewNode Content="Vanilla"/>
            </muxc:TreeViewNode.Children>
        </muxc:TreeViewNode>
    </muxc:TreeView.RootNodes>
</muxc:TreeView>