Binden von hierarchischen Daten und Erstellen einer Master/Details-AnsichtBind hierarchical data and create a master/details view

Hinweis Weitere Informationen finden Sie im Master/Detail-Beispiel.Note  Also see the Master/detail sample.

Sie können eine Master/Details-Ansicht mit mehreren Ebenen (auch bekannt als Listen-Details-Ansicht) von hierarchischen Daten erstellen, indem Sie Elementsteuerelemente an CollectionViewSource-Instanzen binden, die in einer Kette verbunden sind.You can make a multi-level master/details (also known as list-details) view of hierarchical data by binding items controls to CollectionViewSource instances that are bound together in a chain. In diesem Thema verwenden wir nach Möglichkeit die {x:Bind}-Markuperweiterung und die flexiblere (aber weniger leistungsfähige) {Binding}-Markuperweiterung, wenn nötig.In this topic we use the {x:Bind} markup extension where possible, and the more flexible (but less performant) {Binding} markup extension where necessary.

Eine häufig verwendete Struktur für UWP-Apps (Universelle Windows-Plattform) ist die Navigation zu unterschiedlichen Detailseiten, wenn der Benutzer in einer Masterliste eine Auswahl trifft.One common structure for Universal Windows Platform (UWP) apps is to navigate to different details pages when a user makes a selection in a master list. Dies ist hilfreich, wenn Sie eine anschauliche visuelle Darstellung jedes Elements auf allen Ebenen in einer Hierarchie erzielen möchten.This is useful when you want to provide a rich visual representation of each item at every level in a hierarchy. Eine weitere Möglichkeit ist die Anzeige von mehreren Datenebenen auf einer einzelnen Seite.Another option is to display multiple levels of data on a single page. Dies ist nützlich, wenn Sie einige einfache Listen anzeigen möchten, in denen der Benutzer schnell Detailinformationen für ein bestimmtes Element anzeigen kann.This is useful when you want to display a few simple lists that let the user quickly drill down to an item of interest. In diesem Thema wird die Implementierung dieser Interaktion beschrieben.This topic describes how to implement this interaction. Die CollectionViewSource-Instanzen verfolgen die aktuelle Auswahl auf jeder Hierarchieebene nach.The CollectionViewSource instances keep track of the current selection at each hierarchical level.

Wir erstellen eine Ansicht einer Sportmannschaftshierarchie, die in Listen für Ligen, Divisionen und Mannschaften unterteilt ist und eine Detailansicht für Mannschaften enthält.We'll create a view of a sports team hierarchy that is organized into lists for leagues, divisions, and teams, and includes a team details view. Wenn Sie ein Element in einer Liste auswählen, werden die nachfolgenden Ansichten automatisch aktualisiert.When you select an item from any list, the subsequent views update automatically.

Master/Details-Ansicht einer Sporthierarchie

VoraussetzungenPrerequisites

In diesem Thema wird vorausgesetzt, dass Sie mit dem Erstellen von UWP-Apps vertraut sind.This topic assumes that you know how to create a basic UWP app. Anweisungen zum Erstellen Ihrer ersten UWP-App finden Sie unter Erstellen Ihrer ersten UWP-App mit C# oder Visual Basic.For instructions on creating your first UWP app, see Create your first UWP app using C# or Visual Basic.

Erstellen des ProjektsCreate the project

Erstellen Sie ein neues Projekt vom Typ Leere Anwendung (Windows Universal) .Create a new Blank Application (Windows Universal) project. Weisen Sie ihm den Namen „MasterDetailsBinding“ zu.Name it "MasterDetailsBinding".

Erstellen des DatenmodellsCreate the data model

Fügen Sie Ihrem Projekt eine neue Klasse hinzu, nennen Sie sie „ViewModel.cs“, und fügen Sie ihr diesen Code hinzu.Add a new class to your project, name it ViewModel.cs, and add this code to it. Dies ist die Bindungsquellklasse.This will be your binding source class.

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

Erstellen der AnsichtCreate the view

Machen Sie als Nächstes die Bindungsquellklasse aus der Klasse verfügbar, die die Markupseite darstellt.Next, expose the binding source class from the class that represents your page of markup. Zu diesem Zweck fügen Sie eine Eigenschaft vom Typ LeagueList zu MainPage hinzu.We do that by adding a property of type LeagueList to 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; }
    }
}

Schließlich ersetzen Sie den Inhalt der Datei „MainPage.xaml“ durch das folgende Markup, mit dem drei CollectionViewSource-Instanzen deklariert und zu einer Kette verbunden werden.Finally, replace the contents of the MainPage.xaml file with the following markup, which declares three CollectionViewSource instances and binds them together in a chain. Die nachfolgenden Steuerelemente können dann abhängig von der Hierarchieebene an die entsprechende CollectionViewSource-Instanz gebunden werden.The subsequent controls can then bind to the appropriate CollectionViewSource, depending on its level in the hierarchy.

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

Beachten Sie, dass Sie durch die direkte Bindung an die CollectionViewSource-Instanz implizieren, dass Sie in Bindungen, in denen der Pfad in der Sammlung selbst nicht gefunden werden kann, an das aktuelle Element binden möchten.Note that by binding directly to the CollectionViewSource, you're implying that you want to bind to the current item in bindings where the path cannot be found on the collection itself. Die CurrentItem-Eigenschaft muss nicht als Pfad für die Bindung angegeben werden, obwohl dies im Zweifelsfall möglich ist.There's no need to specify the CurrentItem property as the path for the binding, although you can do that if there's any ambiguity. Beispielsweise wird die Content-Eigenschaft der ContentControl-Klasse, welche die Teamansicht darstellt, an TeamsCollectionViewSource gebunden.For example, the ContentControl representing the team view has its Content property bound to the TeamsCollectionViewSource. Die Steuerelemente in der DataTemplate werden jedoch an Eigenschaften der Team-Klasse gebunden, da die CollectionViewSource bei Bedarf automatisch das aktuell aus der Teamliste ausgewählte Team liefert.However, the controls in the DataTemplate bind to properties of the Team class because the CollectionViewSource automatically supplies the currently selected team from the teams list when necessary.