Delen via


Hiërarchische gegevens binden en een hoofd-/detailsweergave maken

Opmerking Zie ook het Master/detail voorbeeld.

U kunt een hoofd-/detailsweergave op meerdere niveaus (ook wel lijstdetails genoemd) van hiërarchische gegevens maken door besturingselementen voor items te binden aan CollectionViewSource exemplaren die aan elkaar zijn gebonden in een keten. In dit onderwerp gebruiken we de markup-extensie {x:Bind} waar mogelijk, en de meer flexibele (maar minder goed presterende) markup-extensie {Binding} waar nodig.

Een algemene structuur voor UWP-apps (Universal Windows Platform) is om naar verschillende detailpagina's te navigeren wanneer een gebruiker een selectie maakt in een hoofdlijst. Dit is handig als u een uitgebreide visuele weergave wilt bieden van elk item op elk niveau in een hiërarchie. Een andere optie is om meerdere gegevensniveaus op één pagina weer te geven. Dit is handig als u een paar eenvoudige lijsten wilt weergeven waarmee de gebruiker snel kan inzoomen op een interessant item. In dit onderwerp wordt beschreven hoe u deze interactie implementeert. De CollectionViewSource exemplaren houden de huidige selectie op elk hiërarchisch niveau bij.

We maken een weergave van een sportteamhiërarchie die is ingedeeld in lijsten voor competities, divisies en teams, en een weergave met teamdetails bevat. Wanneer u een item in een lijst selecteert, worden de volgende weergaven automatisch bijgewerkt.

hoofd-/detailsweergave van een sporthiërarchie

Vereiste voorwaarden

In dit onderwerp wordt ervan uitgegaan dat u weet hoe u een eenvoudige UWP-app maakt. Zie Uw eerste UWP-app maken met C# of Visual Basicvoor instructies over het maken van uw eerste UWP-app.

Het project maken

Maak een nieuw Blank Application (Windows Universal) project. Geef deze de naam MasterDetailsBinding.

Het gegevensmodel maken

Voeg een nieuwe klasse toe aan uw project, noem deze ViewModel.cs en voeg deze code eraan toe. Dit zal uw bronklasse voor bindingen zijn.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MasterDetailsBinding
{
    public class Team
    {
        public string Name { get; set; }
        public int Wins { get; set; }
        public int Losses { get; set; }
    }

    public class Division
    {
        public string Name { get; set; }
        public IEnumerable<Team> Teams { get; set; }
    }

    public class League
    {
        public string Name { get; set; }
        public IEnumerable<Division> Divisions { get; set; }
    }

    public class LeagueList : List<League>
    {
        public LeagueList()
        {
            this.AddRange(GetLeague().ToList());
        }

        public IEnumerable<League> GetLeague()
        {
            return from x in Enumerable.Range(1, 2)
                   select new League
                   {
                       Name = "League " + x,
                       Divisions = GetDivisions(x).ToList()
                   };
        }

        public IEnumerable<Division> GetDivisions(int x)
        {
            return from y in Enumerable.Range(1, 3)
                   select new Division
                   {
                       Name = String.Format("Division {0}-{1}", x, y),
                       Teams = GetTeams(x, y).ToList()
                   };
        }

        public IEnumerable<Team> GetTeams(int x, int y)
        {
            return from z in Enumerable.Range(1, 4)
                   select new Team
                   {
                       Name = String.Format("Team {0}-{1}-{2}", x, y, z),
                       Wins = 25 - (x * y * z),
                       Losses = x * y * z
                   };
        }
    }
}

De weergave maken

Maak vervolgens de bindingsbronklasse beschikbaar vanuit de klasse die uw pagina met markeringen vertegenwoordigt. Dat doen we door een eigenschap van het type LeagueList toe te voegen aan MainPage.

namespace MasterDetailsBinding
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.ViewModel = new LeagueList();
        }
        public LeagueList ViewModel { get; set; }
    }
}

Vervang ten slotte de inhoud van het bestand MainPage.xaml door de volgende markeringen, die drie CollectionViewSource- instanties declareert en deze in een keten verbindt. De volgende besturingselementen kunnen vervolgens worden gekoppeld aan de juiste CollectionViewSource, afhankelijk van het niveau in de hiërarchie.

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

    <Page.Resources>
        <CollectionViewSource x:Name="Leagues"
            Source="{x:Bind ViewModel}"/>
        <CollectionViewSource x:Name="Divisions"
            Source="{Binding Divisions, Source={StaticResource Leagues}}"/>
        <CollectionViewSource x:Name="Teams"
            Source="{Binding Teams, Source={StaticResource Divisions}}"/>

        <Style TargetType="TextBlock">
            <Setter Property="FontSize" Value="15"/>
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>

        <Style TargetType="ListBox">
            <Setter Property="FontSize" Value="15"/>
        </Style>

        <Style TargetType="ContentControl">
            <Setter Property="FontSize" Value="15"/>
        </Style>

    </Page.Resources>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <StackPanel Orientation="Horizontal">

            <!-- All Leagues view -->

            <StackPanel Margin="5">
                <TextBlock Text="All Leagues"/>
                <ListBox ItemsSource="{Binding Source={StaticResource Leagues}}" 
                    DisplayMemberPath="Name"/>
            </StackPanel>

            <!-- League/Divisions view -->

            <StackPanel Margin="5">
                <TextBlock Text="{Binding Name, Source={StaticResource Leagues}}"/>
                <ListBox ItemsSource="{Binding Source={StaticResource Divisions}}" 
                    DisplayMemberPath="Name"/>
            </StackPanel>

            <!-- Division/Teams view -->

            <StackPanel Margin="5">
                <TextBlock Text="{Binding Name, Source={StaticResource Divisions}}"/>
                <ListBox ItemsSource="{Binding Source={StaticResource Teams}}" 
                    DisplayMemberPath="Name"/>
            </StackPanel>

            <!-- Team view -->

            <ContentControl Content="{Binding Source={StaticResource Teams}}">
                <ContentControl.ContentTemplate>
                    <DataTemplate>
                        <StackPanel Margin="5">
                            <TextBlock Text="{Binding Name}" 
                                FontSize="15" FontWeight="Bold"/>
                            <StackPanel Orientation="Horizontal" Margin="10,10">
                                <TextBlock Text="Wins:" Margin="0,0,5,0"/>
                                <TextBlock Text="{Binding Wins}"/>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" Margin="10,0">
                                <TextBlock Text="Losses:" Margin="0,0,5,0"/>
                                <TextBlock Text="{Binding Losses}"/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ContentControl.ContentTemplate>
            </ContentControl>

        </StackPanel>

    </Grid>
</Page>

Door rechtstreeks aan de CollectionViewSourcete binden, impliceert u dat u wilt binden aan het huidige item in bindingen waar het pad niet kan worden gevonden in de verzameling zelf. U hoeft de eigenschap CurrentItem niet op te geven als het pad voor de binding, maar u kunt dit doen als er sprake is van dubbelzinnigheid. De ContentControl- die de teamweergave vertegenwoordigt, heeft bijvoorbeeld de eigenschap Inhoud gebonden aan de TeamsCollectionViewSource-. De besturingselementen in de DataTemplate binden echter aan eigenschappen van de Team klasse, omdat de CollectionViewSource het geselecteerde team automatisch in de lijst met teams levert wanneer dat nodig is.