Windows Dev Center

So wird’s gemacht: Gruppieren von Elementen in einer Liste oder einem Raster (XAML)

Wenn eine ListView oder GridView an eine Datenquelle mit gruppierten Daten gebunden ist, können Sie die gruppierten Daten als Liste oder Raster anzeigen. Die in Ihre App eingehenden Daten können auf unterschiedliche Weise gruppiert werden. Die Datenquelle kann eine Liste aus Elementen sein, bei der jedes Element wiederum eine Liste von Elementen enthält. Sie können z. B. eine Projektliste anzeigen, bei der jedem Projekt eine Eigenschaft in Form einer Liste von Aktivitäten zugewiesen ist. Sie können auch eine LINQ-Abfrage verwenden, die gruppierte Elemente zurückgibt. Nachfolgend erläutern wir, wie diese Gruppen als Liste oder Raster angezeigt werden.

Roadmap: Wie hängt dieses Thema mit anderen zusammen? Informationen finden Sie unter:

Wissenswertes

Technologien

Voraussetzungen

Anweisungen

Schritt 1: Binden der ItemsSource an eine CollectionViewSource

Um gruppierte Daten anzuzeigen, müssen Sie die ItemsControl.ItemsSource-Eigenschaft auf eine CollectionViewSource festlegen, deren IsSourceGrouped-Eigenschaft auf true festgelegt ist. Die CollectionViewSource fungiert als Proxy der Sammlungsklasse, um Währungs- und Gruppierungsunterstützung zu aktivieren.

Hh780627.wedge(de-de,WIN.10).gifSo verwenden Sie eine gruppierte Datenquelle

  1. Legen Sie die ItemsSource-Eigenschaft der Liste oder des Rasters auf eine Instanz von CollectionViewSource fest.
  2. Legen Sie die CollectionViewSource.Source-Eigenschaft auf die gruppierte Datenquelle fest.
  3. Legen Sie die CollectionViewSource.IsSourceGrouped-Eigenschaft auf true fest.

Hier wird eine Sammlung von Activity-Elementen zur Liste hinzugefügt. Jedes Activity-Element weist eine Project-Eigenschaft auf, die ein mit der Activity verknüpftes Projekt angibt. Mit einer LINQ-Abfrage werden die Aktivitäten nach Projekt gruppiert. Die daraus hervorgehenden gruppierten Daten werden als CollectionViewSource.Source festgelegt. Die Definition der Activity-Klasse wird später im vollständigen Beispielcode gezeigt.


List<Activity> Activities = new List<Activity>();

Activities.Add(new Activity() 
    { Name = "Activity 1", Complete = true, 
        DueDate = startDate.AddDays(4), Project = "Project 1" });
Activities.Add(new Activity() 
    { Name = "Activity 2", Complete = true, 
        DueDate = startDate.AddDays(5), Project = "Project 1" });
Activities.Add(new Activity() 
    { Name = "Activity 3", Complete = false, 
        DueDate = startDate.AddDays(7), Project = "Project 1" });
Activities.Add(new Activity() 
    { Name = "Activity 4", Complete = false, 
        DueDate = startDate.AddDays(9), Project = "Project 1" });
Activities.Add(new Activity() 
    { Name = "Activity 5", Complete = false, 
        DueDate = startDate.AddDays(14), Project = "Project 1" });
Activities.Add(new Activity() 
    { Name = "Activity A", Complete = true, 
        DueDate = startDate.AddDays(2), Project = "Project 2" });
Activities.Add(new Activity() 
    { Name = "Activity B", Complete = false, 
        DueDate = startDate.AddDays(4), Project = "Project 2" });
Activities.Add(new Activity() 
    { Name = "Activity C", Complete = true, 
        DueDate = startDate.AddDays(5), Project = "Project 2" });
Activities.Add(new Activity() 
    { Name = "Activity D", Complete = false, 
        DueDate = startDate.AddDays(9), Project = "Project 2" });
Activities.Add(new Activity() 
    { Name = "Activity E", Complete = false, 
        DueDate = startDate.AddDays(18), Project = "Project 2" });

var result = from act in Activities group act by act.Project into grp orderby grp.Key select grp;
cvsActivities.Source = result;


Die CollectionViewSource wird in XAML als Ressource der Hauptseite deklariert. Die IsSourceGrouped-Eigenschaft wird auf true festgelegt. Die ItemsSource-Eigenschaft der ListView ist an die CollectionViewSource gebunden.


<CollectionViewSource x:Name="cvsActivities" IsSourceGrouped="True"/>


Sie können gruppierte Daten aus einer Sammlung anzeigen, in der jedes Element eine Liste von Unterelementen aufweist, die eine Gruppe bilden. In diesem Fall legen Sie die CollectionViewSource.ItemsPath-Eigenschaft so fest, dass die Eigenschaft des Elements angegeben wird, dass die Sammlung von untergeordneten Elementen enthält.

Hh780627.wedge(de-de,WIN.10).gifSo verwenden Sie eine Datenquelle, bei der jedes Element eine Sammlung von untergeordneten Elementen enthält

  1. Führen Sie die Schritte 1-3 weiter oben in diesem Thema aus.
  2. Legen Sie die CollectionViewSource.ItemsPath-Eigenschaft auf die Eigenschaft fest, die die Sammlung der untergeordneten Elemente enthält.

Hier wird eine Liste von Project-Elementen erstellt, die in einer GridView angezeigt werden sollen. Die Daten sind so eingerichtet, dass jedes Project-Element eine Activities-Eigenschaft aufweist, die einer Liste von Activity-Elementen entspricht. Die Liste der Projekte wird als CollectionViewSource.Source festgelegt. Die Definitionen der Project- und Activity-Klassen werden später im vollständigen Beispielcode gezeigt.


List<Project> Projects = new List<Project>();

Project newProject = new Project();
newProject.Name = "Project 1";
newProject.Activities.Add(new Activity() 
    { Name = "Activity 1", Complete = true, DueDate = startDate.AddDays(4) });
newProject.Activities.Add(new Activity() 
    { Name = "Activity 2", Complete = true, DueDate = startDate.AddDays(5) });
newProject.Activities.Add(new Activity() 
    { Name = "Activity 3", Complete = false, DueDate = startDate.AddDays(7) });
newProject.Activities.Add(new Activity() 
    { Name = "Activity 4", Complete = false, DueDate = startDate.AddDays(9) });
newProject.Activities.Add(new Activity() 
    { Name = "Activity 5", Complete = false, DueDate = startDate.AddDays(14) });
Projects.Add(newProject);

newProject = new Project();
newProject.Name = "Project 2";
newProject.Activities.Add(new Activity() 
    { Name = "Activity A", Complete = true, DueDate = startDate.AddDays(2) });
newProject.Activities.Add(new Activity() 
    { Name = "Activity B", Complete = false, DueDate = startDate.AddDays(3) });
newProject.Activities.Add(new Activity() 
    { Name = "Activity C", Complete = true, DueDate = startDate.AddDays(5) });
newProject.Activities.Add(new Activity() 
    { Name = "Activity D", Complete = false, DueDate = startDate.AddDays(9) });
newProject.Activities.Add(new Activity() 
    { Name = "Activity E", Complete = false, DueDate = startDate.AddDays(18) });
Projects.Add(newProject);

newProject = new Project();
newProject.Name = "Project 3";
Projects.Add(newProject);

cvsProjects.Source = Projects;


Die CollectionViewSource wird in XAML als Ressource der Hauptseite deklariert. Die IsSourceGrouped-Eigenschaft wird auf true und die ItemsPath-Eigenschaft auf die Project.Activities-Eigenschaft festgelegt, die die Sammlung von Activity-Elementen enthält. Die ItemsSource-Eigenschaft der GridView ist an die CollectionViewSource gebunden.


<CollectionViewSource x:Name="cvsProjects" IsSourceGrouped="True" ItemsPath="Activities"/>


Weitere Informationen zur Datenbindung und -gruppierung finden Sie unter Datenbindung mit XAML.

Schritt 2: Festlegen eines GroupStyle zum Angeben der Gruppenanzeige

Um die gruppierten Daten als Liste oder Raster anzuzeigen, definieren Sie einen GroupStyle, der eine Kopfzeilenvorlage für jede Gruppe angibt. Standardmäßig wird die Gruppenkopfzeile für leere Gruppen angezeigt. Um die Kopfzeile für leere Gruppen auszublenden, legen Sie die HidesIfEmpty-Eigenschaft auf true fest.

Hh780627.wedge(de-de,WIN.10).gifSo geben Sie an, wie Gruppen angezeigt werden

  1. Definieren Sie einen GroupStyle für die ListView oder GridView.
  2. Definieren Sie im GroupStyle eine HeaderTemplate, die das Aussehen der Gruppenkopfzeile angibt.
  3. Um die Kopfzeile für leere Gruppen auszublenden, legen Sie die GroupStyle.HidesIfEmpty-Eigenschaft auf true fest.

Hier verwenden Sie eine GridView, um die zuvor erstellte Projects-Liste anzuzeigen. Das Erscheinungsbild der einzelnen Elemente in jeder Gruppe wird durch die ItemTemplate definiert, genau wie für nicht gruppierte Daten. Das ItemsPanel gibt an, wie die Gruppen in der GridView angeordnet werden. Die Projects-Liste enthält ein Projekt mit einer leeren Activities-Sammlung. Sie legen die HidesIfEmpty-Eigenschaft auf true fest, um diese leere Gruppe auszublenden.


<GridView ItemsSource="{Binding Source={StaticResource cvsProjects}}" 
  Margin="0,120,0,0" MaxHeight="500" Grid.Column="1">
    <GridView.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="20">
                <TextBlock Text="{Binding Name}" FontWeight="Bold" 
                           Style="{StaticResource BaseTextBlockStyle}"/>
                <TextBlock Text="{Binding DueDate}" TextWrapping="NoWrap" 
                           Style="{StaticResource BodyTextBlockStyle}" />
                <CheckBox Content="Complete" IsChecked="{Binding Complete}" 
                          IsEnabled="False"/>
            </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid MaximumRowsOrColumns="3"/>
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>

    <GridView.GroupStyle>
        <GroupStyle HidesIfEmpty="True">
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <Grid Background="LightGray" Margin="0">
                        <TextBlock Text='{Binding Name}' 
                                   Foreground="Black" Margin="30"
                                   Style="{StaticResource HeaderTextBlockStyle}"/>
                    </Grid>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>

        </GroupStyle>
    </GridView.GroupStyle>
</GridView>


Schritt 3: Festlegen eines GroupStyle mit einer GroupStyleSelector

Um einen als Ressource definierten GroupStyle zu verwenden oder einen GroupStyle mithilfe von Bedingungslogik anzuwenden, nutzen Sie eine GroupStyleSelector.

Hh780627.wedge(de-de,WIN.10).gifVerwenden einer GroupStyleSelector

  1. Erstellen Sie eine Unterklasse der GroupStyleSelector-Klasse, und überschreiben Sie die SelectGroupStyleCore-Methode.

    Hier erstellen Sie eine Klasse namens ListGroupStyleSelector, die von GroupStyleSelector abgeleitet ist. Sie überschreiben die SelectGroupStyleCore-Methode, um eine GroupStyle-Ressource zurückzugeben, die den Schlüssel-listViewGroupStyle enthält. Diese Ressource wird in der App.xaml-Datei deklariert. Sie können hier Bedingungslogik anwenden, wenn Sie für die Rückgabe aus unterschiedlichen Gruppenstilen wählen müssen.

    
    public class ListGroupStyleSelector : GroupStyleSelector
    {
        protected override GroupStyle SelectGroupStyleCore(object group, uint level)
        {
            return (GroupStyle)App.Current.Resources["listViewGroupStyle"];
        }
    }
    
    
    
  2. In Ihrer XAML-Datei definieren Sie eine Instanz Ihrer Gruppenstil-Auswahlklasse.

    Diese Ressource wird im Resources-Abschnitt der Seite deklariert.

    
    <local:ListGroupStyleSelector x:Key="listGroupStyleSelector"/>
    
    
    
  3. Legen Sie die GroupStyleSelector-Eigenschaft Ihres Element-Steuerelements auf die Ressource aus dem vorigen Schritt fest.

    Hier erstellen Sie eine ListView, um die zuvor erstellte Activities-Liste anzuzeigen. Die ItemTemplate ist auf eine Ressource mit der Schlüssel-listViewItemTemplate und die GroupStyleSelector-Eigenschaft auf eine Ressource mit der Schlüssel-listGroupStyleSelector festgelegt. Diese Ressourcen werden später im vollständigen Beispielcode gezeigt.

    
    <ListView ItemsSource="{Binding Source={StaticResource cvsActivities}}"
      ItemTemplate="{StaticResource listViewItemTemplate}"
      GroupStyleSelector="{StaticResource listGroupStyleSelector}"
      Margin="120" Width="320"/>
    
    
    

Anmerkungen

So sehen die Listen- und Rasteransichten beim Ausführen der App aus.

Gruppierte Listenansicht

 

Gruppierte Rasteransicht

Weitere Codebeispiele zur Gruppierung und Anzeige von Daten finden Sie in den folgenden Beispielen:

Vollständiges Beispiel

Nachfolgend finden Sie den vollständigen Code zu den Beispielen in diesem Thema.

MainPage.xaml


<Page
    x:Class="ItemsControlGroupingSnippets.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ItemsControlGroupingSnippets"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <UserControl.Resources>
        <CollectionViewSource x:Name="cvsActivities" IsSourceGrouped="True"/>

        <CollectionViewSource x:Name="cvsProjects" IsSourceGrouped="True" ItemsPath="Activities"/>

        <local:ListGroupStyleSelector x:Key="listGroupStyleSelector"/>
    </UserControl.Resources>

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

        <ListView ItemsSource="{Binding Source={StaticResource cvsActivities}}"
          ItemTemplate="{StaticResource listViewItemTemplate}"
          GroupStyleSelector="{StaticResource listGroupStyleSelector}"
          Margin="120" Width="320"/>

        <GridView ItemsSource="{Binding Source={StaticResource cvsProjects}}" 
          Margin="0,120,0,0" MaxHeight="500" Grid.Column="1">
            <GridView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Margin="20">
                        <TextBlock Text="{Binding Name}" FontWeight="Bold" 
                                   Style="{StaticResource BaseTextBlockStyle}"/>
                        <TextBlock Text="{Binding DueDate}" TextWrapping="NoWrap" 
                                   Style="{StaticResource BodyTextBlockStyle}" />
                        <CheckBox Content="Complete" IsChecked="{Binding Complete}" 
                                  IsEnabled="False"/>
                    </StackPanel>
                </DataTemplate>
            </GridView.ItemTemplate>
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <ItemsWrapGrid MaximumRowsOrColumns="3"/>
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>

            <GridView.GroupStyle>
                <GroupStyle HidesIfEmpty="True">
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <Grid Background="LightGray" Margin="0">
                                <TextBlock Text='{Binding Name}' 
                                           Foreground="Black" Margin="30"
                                           Style="{StaticResource HeaderTextBlockStyle}"/>
                            </Grid>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>

                </GroupStyle>
            </GridView.GroupStyle>
        </GridView>
    </Grid>
</Page>


CodeBehind "MainPage.xaml"


using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace ItemsControlGroupingSnippets
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        DateTime startDate;
        public MainPage()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            DateTime.TryParse("1/1/2014", out startDate);

            PopulateProjects();
            PopulateActivities();
        }

        private void PopulateActivities()
        {
            List<Activity> Activities = new List<Activity>();

            Activities.Add(new Activity() 
                { Name = "Activity 1", Complete = true, 
                    DueDate = startDate.AddDays(4), Project = "Project 1" });
            Activities.Add(new Activity() 
                { Name = "Activity 2", Complete = true, 
                    DueDate = startDate.AddDays(5), Project = "Project 1" });
            Activities.Add(new Activity() 
                { Name = "Activity 3", Complete = false, 
                    DueDate = startDate.AddDays(7), Project = "Project 1" });
            Activities.Add(new Activity() 
                { Name = "Activity 4", Complete = false, 
                    DueDate = startDate.AddDays(9), Project = "Project 1" });
            Activities.Add(new Activity() 
                { Name = "Activity 5", Complete = false, 
                    DueDate = startDate.AddDays(14), Project = "Project 1" });
            Activities.Add(new Activity() 
                { Name = "Activity A", Complete = true, 
                    DueDate = startDate.AddDays(2), Project = "Project 2" });
            Activities.Add(new Activity() 
                { Name = "Activity B", Complete = false, 
                    DueDate = startDate.AddDays(4), Project = "Project 2" });
            Activities.Add(new Activity() 
                { Name = "Activity C", Complete = true, 
                    DueDate = startDate.AddDays(5), Project = "Project 2" });
            Activities.Add(new Activity() 
                { Name = "Activity D", Complete = false, 
                    DueDate = startDate.AddDays(9), Project = "Project 2" });
            Activities.Add(new Activity() 
                { Name = "Activity E", Complete = false, 
                    DueDate = startDate.AddDays(18), Project = "Project 2" });

            var result = from act in Activities group act by act.Project into grp orderby grp.Key select grp;
            cvsActivities.Source = result;
        }

        private void PopulateProjects()
        {
            List<Project> Projects = new List<Project>();

            Project newProject = new Project();
            newProject.Name = "Project 1";
            newProject.Activities.Add(new Activity() 
                { Name = "Activity 1", Complete = true, DueDate = startDate.AddDays(4) });
            newProject.Activities.Add(new Activity() 
                { Name = "Activity 2", Complete = true, DueDate = startDate.AddDays(5) });
            newProject.Activities.Add(new Activity() 
                { Name = "Activity 3", Complete = false, DueDate = startDate.AddDays(7) });
            newProject.Activities.Add(new Activity() 
                { Name = "Activity 4", Complete = false, DueDate = startDate.AddDays(9) });
            newProject.Activities.Add(new Activity() 
                { Name = "Activity 5", Complete = false, DueDate = startDate.AddDays(14) });
            Projects.Add(newProject);

            newProject = new Project();
            newProject.Name = "Project 2";
            newProject.Activities.Add(new Activity() 
                { Name = "Activity A", Complete = true, DueDate = startDate.AddDays(2) });
            newProject.Activities.Add(new Activity() 
                { Name = "Activity B", Complete = false, DueDate = startDate.AddDays(3) });
            newProject.Activities.Add(new Activity() 
                { Name = "Activity C", Complete = true, DueDate = startDate.AddDays(5) });
            newProject.Activities.Add(new Activity() 
                { Name = "Activity D", Complete = false, DueDate = startDate.AddDays(9) });
            newProject.Activities.Add(new Activity() 
                { Name = "Activity E", Complete = false, DueDate = startDate.AddDays(18) });
            Projects.Add(newProject);

            newProject = new Project();
            newProject.Name = "Project 3";
            Projects.Add(newProject);

            cvsProjects.Source = Projects;
        }

    }

    public class ListGroupStyleSelector : GroupStyleSelector
    {
        protected override GroupStyle SelectGroupStyleCore(object group, uint level)
        {
            return (GroupStyle)App.Current.Resources["listViewGroupStyle"];
        }
    }

    public class Project
    {
        public Project()
        {
            Activities = new ObservableCollection<Activity>();
        }

        public string Name { get; set; }
        public ObservableCollection<Activity> Activities { get; private set; }
    }

    public class Activity
    {
        public string Name { get; set; }
        public DateTime DueDate { get; set; }
        public bool Complete { get; set; }
        public string Project { get; set; }
    }
}


App.xaml


<Application
    x:Class="ItemsControlGroupingSnippets.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ItemsControlGroupingSnippets">

    <Application.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="listViewItemTemplate">
                <StackPanel Width="320" Margin="10">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}" FontWeight="Bold" Style="{StaticResource BaseTextBlockStyle}"
                       Margin="2,0,0,0"/>
                        <TextBlock Text="{Binding DueDate}" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap"
                       Margin="20,0,0,0"/>
                    </StackPanel>
                    <CheckBox Content="Complete" IsChecked="{Binding Complete}" IsEnabled="False"/>
                </StackPanel>
            </DataTemplate>

            <GroupStyle x:Key="listViewGroupStyle">
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <Grid Background="LightGray"  >
                            <TextBlock Text='{Binding Key}' Foreground="Black" Margin="10"
                           Style="{StaticResource SubheaderTextBlockStyle}" />
                        </Grid>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ResourceDictionary>
    </Application.Resources>
</Application>


Verwandte Themen

ListView
GridView
Hinzufügen von ListView- und GridView-Steuerelementen
Beispiel für XAML-GridView-Gruppierung und SemanticZoom

 

 

Anzeigen:
© 2015 Microsoft