Megosztás a következőn keresztül:


Fa nézet

A fa nézet vezérlő lehetővé teszi hierarchikus listák készítését, amelyeknél a csomópontok kibonthatók és összehajthatók, és beágyazott elemeket tartalmazhatnak. Segítségével a felhasználói felületen lévő mappastruktúrát vagy beágyazott kapcsolatokat szemléltetheti.

A fás nézet behúzással és ikonokkal kombinálva jeleníti meg a szülő- és gyermekcsomópontok közötti beágyazott kapcsolatot. Az összecsukott csomópontok jobbra mutató sávjelet használnak, a kibontott csomópontok pedig lefelé mutató sávot.

A chevron ikon a TreeView nézetben

A csomópontokat ábrázoló ikont a fanézetelem adatsablonjában is megjelenítheti. Ha például egy fájlrendszer hierarchiát mutat be, a szülő csomópontokhoz használhat mappaikonokat, és a levélcsomópontokhoz fájlikonokat.

A sáv- és mappaikonok egy TreeView-ban

A TreeView API-k a következő funkciókat támogatják:

  • N szintű beágyazás
  • Egy vagy több csomópont kijelölése
  • Adatkötés a TreeView és a TreeViewItemItemsSource tulajdonságához
  • TreeViewItem a TreeView elemsablon gyökere
  • Tetszőleges típusú tartalom a TreeViewItemben
  • Húzás és ejtés a fanézetek között

Ez a megfelelő vezérlő?

  • Használjon TreeView-t, ha az elemek beágyazott listaelemekkel rendelkeznek, és ha fontos, hogy bemutassa az elemek hierarchikus kapcsolatát a társukkal és a csomópontjukkal.

  • Kerülje a TreeView használatát, ha egy elem beágyazott kapcsolatának kiemelése nem prioritás. A legtöbb részletezési forgatókönyv esetében megfelelő a normál listanézet.

A fa nézet létrehozása

A fanézetet úgy hozhatja létre, hogy az ItemsSource-t egy hierarchikus adatforráshoz köti, vagy létrehozza és kezeli a TreeViewNode-objektumokat saját maga.

Fanézet létrehozásához TreeView-vezérlőt és TreeViewNode-objektumok hierarchiáját kell használnia. A csomóponthierarchiát úgy hozhatja létre, hogy hozzáad egy vagy több gyökércsomópontot a TreeView-vezérlőgyökércsomópontjai gyűjteményéhez. Az egyes TreeViewNode-csomópontok ezután több csomópontot adhatnak hozzá a Gyermek gyűjteményhez. A fa nézet elemeket tetszőleges mélységben beágyazhatja.

A hierarchikus adatforrásokat az ItemsSource tulajdonsághoz kötve biztosíthatja a fanézet tartalmát, ugyanúgy, mint a ListViewItemsSource-jával. Hasonlóképpen, az ItemTemplate (és az opcionális ItemTemplateSelector) használatával adjon meg egy DataTemplate-et , amely megjeleníti az elemet.

Íme egy példa egy XAML-ben deklarált egyszerű fanézetre. Általában a kódban adja hozzá a csomópontokat, de itt az XAML-hierarchiát mutatjuk be, mert hasznos lehet a csomópontok hierarchiájának létrehozásának vizualizációjához.

<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>

A legtöbb esetben a fanézet adatokat jelenít meg egy adatforrásból, ezért általában deklarálja a root TreeView vezérlőt az XAML-ben, de a TreeViewNode-objektumokat kódban vagy adatkötéssel adja hozzá.

Hierarchikus adatforráshoz való kötés

Ha adatkötéssel szeretne fa-nézetet létrehozni, állítson be egy hierarchikus gyűjteményt a TreeView.ItemsSource tulajdonságra. Ezután az ItemTemplate-ban állítsa a gyermekelemek gyűjteményét a TreeViewItem.ItemsSource tulajdonságra .

<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>

Lásd a Fa nézetet adatkötéssel a teljes kódért.

Elemek és elemtárolók

A TreeView.ItemsSource használata esetén ezek az API-k elérhetők a csomópont vagy adatelem tárolóból való lekéréséhez, és fordítva.

TreeViewItem Description
TreeView.ItemFromContainer Lekéri a megadott TreeViewItem konténer adatelemét.
TreeView.ContainerFromItem Lekéri a megadott adatelemHez tartozó TreeViewItem-tárolót .
TreeViewNode Description
TreeView.NodeFromContainer Lekéri a TreeViewNode-t a megadott TreeViewItem tárolóhoz.
TreeView.ContainerFromNode Megszerzi a megadott TreeViewNode számára a TreeViewItem tárolót.

Fa nézet csomópontok kezelése

Ez a fa nézet megegyezik a korábban az XAML-ben létrehozott nézetével, de a csomópontok ezúttal programkódban jönnek létre.

<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

Ezek az API-k a fanézet adathierarchiájának kezelésére használhatók.

TreeView Description
Gyökércsomópontok A fa nézet egy vagy több gyökérpontot tartalmazhat. Gyökércsomópont létrehozásához adjon hozzá egy TreeViewNode-objektumot a Gyökércsomópontok gyűjteményhez. A gyökércsomópont szülő mindig null. A gyökércsomópont mélysége 0.
TreeViewNode Description
Children Adjon hozzá TreeViewNode-objektumokat egy szülőcsomópont Gyermek gyűjteményéhez a csomóponthierarchia létrehozásához. A csomópont a szülő az összes csomópontnak a Gyermekek gyűjteményében.
GyermekeiVannak igaz , ha a csomópont gyermekeket észlelt. a false (hamis ) üres mappát vagy elemet jelöl.
Valósulatlan gyermekek Ezt a tulajdonságot akkor használja, amikor a csomópontokat kibontáskor tölti be. A cikk későbbi részében lásd a Csomópont kitöltése bővítéskor részt.
Mélység Azt jelzi, hogy a gyermekcsomópont milyen messze van a gyökércsomóponttól.
Szülő Lekéri a TreeViewNode-ot, amely annak a Gyermekek gyűjteményének a tulajdonosa, amelyhez ez a csomópont tartozik.

A fa nézet a HasChildren és a HasUnrealizedChildren tulajdonságokat használja annak meghatározására, hogy megjelenik-e a kibontás/összecsukás ikonja. Ha bármelyik tulajdonság igaz, megjelenik az ikon; ellenkező esetben nem jelenik meg.

Fanézeti csomópont tartalma

A fanézeti csomópont által képviselt adatelemet a Content tulajdonságban tárolhatja.

Az előző példákban a tartalom egy egyszerű sztringérték volt. Itt egy fanézeti csomópont a felhasználó Pictures mappáját jelöli, így a képtár StorageFolder a csomópont Content tulajdonságához van rendelve.

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}

Megjegyzés:

Az Pictures mappához való hozzáférés megszerzéséhez meg kell adnia a Képek könyvtára képességet az alkalmazás-nyilvántartásban. További információt az alkalmazásképesség-deklarációkban talál.

Megadhatja a DataTemplate-et annak megadásához, hogy az adatelem hogyan jelenjen meg a fa nézetben.

Elemtároló stílusa

Függetlenül attól, hogy ItemsSource-t vagy RootNodes-t használ, az egyes csomópontok megjelenítéséhez használt tényleges elem – az úgynevezett "tároló" – egy TreeViewItem objektum. A TreeViewItem tulajdonságai a TreeViewItemContainerStyle vagy Az ItemContainerStyleSelector tulajdonságaival módosíthatók a tároló stílusához.

Ez a példa bemutatja, hogyan módosíthatja a kibontott/összecsukott karakterjeleket narancssárga +/- jelekre. Az alapértelmezett TreeViewItem sablonban a karakterjelek a Segoe MDL2 Assets betűtípus használatára vannak beállítva. A Setter.Value tulajdonságot úgy állíthatja be, hogy megadja a Unicode karakter értékét az XAML által használt formátumban, a következőképpen: 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>

Elemsablon-választók

Alapértelmezés szerint a TreeView megjeleníti az egyes csomópontok adatelemének sztringképét. Az ItemTemplate tulajdonság beállításával módosíthatja az összes csomóponton megjelenő elemeket. Az ItemTemplateSelector használatával másik DataTemplate-adattáblát is választhat a fanézet elemeihez az elem típusa vagy más megadott feltételek alapján.

Egy file explorer alkalmazásban például használhat egy adatsablont mappákhoz, egy másikat fájlokhoz.

Mappák és fájlok különböző adatsablonokkal

Íme egy példa egy elemsablon-választó létrehozására és használatára. További információ: DataTemplateSelector osztály.

Megjegyzés:

Ez a kód egy nagyobb példa része, és önmagában nem fog működni. A teljes példa megtekintéséhez, beleértve a ExplorerItem definiáló kódot, tekintse meg a WinUI 3 katalógust a GitHub. TreeViewPage.xaml és TreeViewPage.xaml.cs tartalmazza a megfelelő kódot.

<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;
    }
}

A SelectTemplateCore metódusnak átadott objektum típusa attól függ, hogy az ItemsSource tulajdonság beállításával vagy a TreeViewNode-objektumok létrehozásával és kezelésével hozza-e létre a fanézetet.

  • Ha ItemsSource be van állítva, az objektum az adatelem típusának megfelelően alakul. Az előző példában az objektum egy ExplorerItemvolt, így egyszerű leadás után használható ExplorerItem:var explorerItem = (ExplorerItem)item;.
  • Ha ItemsSource nincs beállítva, és saját maga kezeli a fa nézet csomópontjait, a SelectTemplateCore-nak átadott objektum egy TreeViewNode. Ebben az esetben lekérheti az adatelemet a TreeViewNode.Content tulajdonságból.

Íme egy adatsablon-választó a Képek és zenék könyvtárának fa nézetéből, amelyet később láthat. A SelectTemplateCore metódus kap egy TreeViewNode objektumot, amely tartalmazhat akár egy StorageFolder vagy egy StorageFile elemet. A tartalom alapján visszaadhat egy alapértelmezett sablont vagy egy adott sablont a zenemappához, a képmappához, a zenefájlokhoz vagy a képfájlokhoz.

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

Fanézettel való interakció

Egy fanézet úgy konfigurálható, hogy a felhasználók többféleképpen is interakcióba léphessenek vele:

  • Csomópontok kibontása vagy összecsukása
  • Egy- vagy többválasztásos elemek
  • Kattintással meghívhat egy elemet

Kibontás/összecsukás

A gyermekeket tartalmazó fanézeti csomópontok mindig kibonthatók vagy összecsukhatók a kibontás/összecsukás jelre kattintva. Programozott módon is kibonthat vagy összecsukhat egy csomópontot, és válaszolhat, ha egy csomópont állapota megváltozik.

Csomópont programozott kibontása/összecsukása

Kétféleképpen bővíthet vagy csukhat össze egy fa nézet csomópontot a kódjában.

  • A TreeView osztály összecsukási és kibontási metódusokkal rendelkezik. Amikor meghívja ezeket a metódusokat, átadja a kibontani vagy összecsukni kívánt TreeViewNode-et .

  • Minden TreeViewNodeisExpanded tulajdonsággal rendelkezik. Ezzel a tulajdonságmal ellenőrizheti egy csomópont állapotát, vagy beállíthatja az állapot módosítására. Ezt a tulajdonságot az XAML-ben is beállíthatja a csomópont kezdeti állapotának beállításához.

Csomópont kitöltése bővítéskor

Előfordulhat, hogy sok csomópontot kell megjelenítenie a fanézetben, vagy lehet, hogy nem tudja előre, hogy hány csomópontja lesz. A TreeView vezérlő nincs virtualizálva, így az erőforrásokat úgy kezelheti, hogy betölti az egyes csomópontokat, amikor azok kibontásra kerülnek, és eltávolítja a gyermekcsomópontokat, amikor összecsukódnak.

Kezelje a kibontási eseményt, és a HasUnrealizedChildren tulajdonság segítségével adjon hozzá gyermekeket egy csomóponthoz, amikor azt kibontják. A HasUnrealizedChildren tulajdonság azt jelzi, hogy a csomópontot ki kell-e tölteni, vagy hogy a Gyermek gyűjtemény már ki van-e töltve. Fontos megjegyezni, hogy a TreeViewNode nem állítja be ezt az értéket, azt az alkalmazáskódban kell kezelnie.

Íme egy példa a használatban lévő API-kra. Tekintse meg a cikk végén található teljes példakódot a környezethez, beleértve a FillTreeNode implementációját is.

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

Ez nem kötelező, de érdemes lehet az Összecsukott eseményt is kezelni, és eltávolítani a gyermekcsomópontokat, amikor a szülőcsomópont bezárul. Ez akkor lehet fontos, ha a fanézet sok csomópontot használ, vagy ha a csomópont adatai sok erőforrást használnak. Figyelembe kell vennie a csomópontok minden egyes megnyitásakor való kitöltésének teljesítménybeli hatását, és nem szabad bezárt csomóponton hagyni a gyerekeket. A legjobb megoldás az alkalmazástól függ.

Íme egy példa az összecsukott esemény kezelőjének példájára.

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

Elem meghívása

A felhasználó az elem kijelölése helyett meghívhat egy műveletet (az elemet gombként kezelve). Az ItemInvoked eseményt úgy kezeli, hogy reagáljon erre a felhasználói beavatkozásra.

Megjegyzés:

Az IsItemClickEnabled tulajdonságot tartalmazó ListView-nal ellentétben az elem meghívása mindig engedélyezve van a fanézetben. Továbbra is eldöntheti, hogy kezeli-e az eseményt.

TreeViewItemInvokedEventArgs osztály

Az ItemInvoked esemény a meghívott elemhez access ad. Az InvokedItem tulajdonságban található az a csomópont, amelyet meghívtak. Átadhatja egy TreeViewNode-fájlba , és lekérheti az adatelemet a TreeViewNode.Content tulajdonságból.

Íme egy példa egy ItemInvoked eseménykezelőre. Az adatelem egy IStorageItem, és ez a példa csak néhány információt jelenít meg a fájlról és a fáról. Továbbá, ha a csomópont egy mappa, akkor a csomópontot egyszerre nyitja ki vagy csukja össze. Ellenkező esetben a csomópont csak akkor bontódik ki vagy csukódik össze, ha a sávjelre kattint.

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

Elem kijelölése

A TreeView vezérlő támogatja az egyszeri és a többszörös kijelölést is. Alapértelmezés szerint a csomópontok kijelölése ki van kapcsolva, de beállíthatja a TreeView.SelectionMode tulajdonságot a csomópontok kijelölésének engedélyezéséhez. A TreeViewSelectionMode értéke Nincs, Egy és Többszörös.

Több kijelölés

Ha több kijelölés is engedélyezve van, minden fanézeti csomópont mellett megjelenik egy jelölőnégyzet, és a kijelölt elemek ki vannak emelve. A felhasználó kijelölhet vagy törölhet egy elemet a jelölőnégyzet használatával; az elemre való kattintás továbbra is meghívja az elemet.

Ha kijelöl vagy megszünteti a kijelölését egy szülőcsomópontnak, akkor az adott csomópont alatt lévő összes gyermek kijelölése vagy kijelölésének megszüntetése is megtörténik. Ha a szülőcsomópont alatti gyermekek közül néhányan, de nem az összes, vannak kiválasztva, akkor a szülőcsomópont jelölőnégyzete határozatlan állapotban jelenik meg.

Több kijelölés a fa nézetben

A rendszer hozzáadja a kijelölt csomópontokat a fanézet SelectedNodes gyűjteményéhez. A SelectAll metódus meghívásával kijelölheti az összes csomópontot egy fanézetben.

Megjegyzés:

A SelectAll hívása esetén az összes megvalósult csomópont ki lesz jelölve, a SelectionMode-tól függetlenül. Konzisztens felhasználói élmény biztosításához csak akkor hívja meg a SelectAll-t, ha a SelectionModeTöbbszörös.

Kiválasztás és realizált/nem realizált csomópontok

Ha a fa nézetben vannak nem realizált csomópontok, azok nincsenek figyelembe véve a kijelölésnél. Íme néhány dolog, amit szem előtt kell tartania a nem realizált csomópontok kiválasztásával kapcsolatban.

  • Ha egy felhasználó kiválaszt egy szülőcsomópontot, a rendszer az adott szülő alatti összes megvalósult gyermeket is kijelöli. Hasonlóképpen, ha az összes gyermekcsomópont ki van jelölve, a szülőcsomópont is ki lesz jelölve.
  • A SelectAll metódus csak realizált csomópontokat ad hozzá a SelectedNodes-gyűjteményhez .
  • Ha egy nem realizált gyermekekkel rendelkező szülőcsomópont van kiválasztva, a rendszer a megvalósításukkor kiválasztja a gyermekeket.

KiválasztottElem/KiválasztottElemek

A TreeView a SelectedItem és a SelectedItems tulajdonsággal rendelkezik . Ezekkel a tulajdonságokkal közvetlenül lekérheti a kijelölt csomópontok tartalmát. Ha több kijelölés is engedélyezve van, a SelectedItem a SelectedItems gyűjtemény első elemét tartalmazza.

KiválasztásMegváltozott

A SelectionChanged eseményt úgy kezelheti, hogy reagáljon, amikor a kijelölt elemek gyűjteménye megváltozik, akár programozott módon, akár felhasználói beavatkozással.

<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éldakódok

Az alábbi példakódok a fa nézet vezérlő különböző jellemzőit mutatják be.

Fa nézet a XAML használatával

Ez a példa bemutatja, hogyan hozhat létre egyszerű fanézet-struktúrát az XAML-ben. A fanézetben azok a fagylaltízek és öntetek láthatók, amelyek közül a felhasználó választhat, kategóriákba rendezve. A többszörös kijelölés engedélyezve van, és amikor a felhasználó rákattint egy gombra, a kijelölt elemek megjelennek a főalkalmazás felhasználói felületén.

<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

Adatkötési fa nézet

Ez a példa bemutatja, hogyan hozható létre ugyanaz a fanézet, mint az előző példában. Az adathierarchia XAML-ben való létrehozása helyett azonban az adatok kódban jönnek létre, és a fanézet ItemsSource tulajdonságához lesznek kötve. (Az előző példában látható gombesemény-kezelők erre a példára is érvényesek.)

<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;
        }
    }
}

Képek és zenetárfa nézet

Ez a példa bemutatja, hogyan hozhat létre olyan fanézetet, amely a felhasználó Képek és Zene könyvtárainak tartalmát és szerkezetét jeleníti meg. A csomópontok tartalma előre nem ismert, ezért minden csomópont tartalommal töltődik fel, amikor kibontják, és kiürül, amikor összecsukják.

Az egyéni elemsablonok a IStorageItem típusú adatelemek megjelenítésére szolgálnak.

Fontos

A példában szereplő kódhoz a picturesLibrary és a musicLibrary képességek szükségesek. A fájlhozzáféréssel kapcsolatos további információkért lásd: Fájlhozzáférési engedélyek, Fájlok és mappák felsorolása és lekérdezése, és Fájlok és mappák a Zene, Képek és Videók könyvtáraiban.

<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

Elemek húzása és ejtése a fanézetek között

A következő példa szemlélteti, hogyan lehet létrehozni két fanézetet, amelyek elemei egymás között húzhatók és ejthetők. Amikor egy elemet áthúz a másik fanézetbe, az a lista végére kerül. Az elemek fanézetben azonban újrarendezhetők. Ez a példa csak az egy gyökércsomópontot tartalmazó fa nézeteket veszi figyelembe.

<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;
        }
    }
}