Compartir a través de


Enlace datos jerárquicos y cree una vista maestro/detalle con WinUI

Obtenga información sobre cómo crear una vista de maestro/detalles de varios niveles de datos jerárquicos en WinUI mediante el enlace de controles de elementos a instancias de CollectionViewSource. En este artículo se explica cómo usar la extensión de marcado {x:Bind} para mejorar el rendimiento y la extensión de marcado {Binding} cuando se necesita flexibilidad.

Una estructura común para las aplicaciones winUI es navegar a diferentes páginas de detalles cuando un usuario realiza una selección en una lista maestra. Esta estructura es útil cuando desea proporcionar una representación visual enriquecida de cada elemento en cada nivel de una jerarquía. Otra opción es mostrar varios niveles de datos en una sola página. Esta estructura es útil cuando desea mostrar algunas listas sencillas que permiten al usuario explorar en profundidad rápidamente un elemento de interés. En este artículo se describe cómo implementar esta interacción. Las instancias de CollectionViewSource realizan un seguimiento de la selección actual en cada nivel jerárquico.

Crea una vista de una jerarquía de equipos deportivos organizada en listas para ligas, divisiones y equipos, e incluye una vista de detalles del equipo. Cuando seleccionas un elemento de cualquier lista, las vistas siguientes se actualizan automáticamente.

Captura de pantalla de una vista principal/detallada de una jerarquía deportiva. La vista incluye ligas, divisiones y equipos.

Sugerencia

Consulta también la Muestra de maestro y detalles para UWP.

Prerrequisitos

En este artículo se da por supuesto que sabe cómo crear una aplicación WinUI básica. Para obtener instrucciones sobre cómo crear la primera aplicación winUI, consulte Creación de una aplicación WinUI.

Creación del proyecto

Cree un nuevo proyecto de aplicación en blanco, empaquetado (WinUI 3 en escritorio). Asígnale el nombre "MasterDetailsBinding".

Crear el modelo de datos

Agregue una nueva clase al proyecto, asígnele el nombre de ViewModel.cs y agréguele este código. Esta clase es tu clase fuente de enlace.

using System.Collections.Generic;
using System.Linq;

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()
        {
            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
                   };
        }
    }
}

Crear la vista

Después, expón la clase de origen de enlace desde la clase que representa la página de marcado. Agregue una propiedad de tipo LeagueList a MainWindow.

namespace MasterDetailsBinding
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ViewModel = new LeagueList();
        }
        public LeagueList ViewModel { get; set; }
    }
}

Por último, reemplace el contenido del archivo MainWindow.xaml por el marcado siguiente. Este marcado declara tres instancias collectionViewSource y las enlaza en una cadena. A continuación, los controles subsiguientes se pueden enlazar al elemento CollectionViewSource apropiado, según su nivel en la jerarquía.

<Window
    x:Class="MasterDetailsBinding.MainWindow"
    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">

    <Grid>
        <Grid.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>
        </Grid.Resources>

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

Al enlazar directamente a CollectionViewSource, usted está indicando que desea enlazar al elemento actual en configuraciones de enlace donde no se puede encontrar la ruta en la propia colección. No es necesario especificar la propiedad CurrentItem como la ruta de acceso para el enlace, aunque puede agregarla si hay ambigüedad. Por ejemplo, contentControl que representa la vista de equipo tiene su propiedad Content enlazada a .TeamsCollectionViewSource No obstante, los controles del elemento DataTemplate se enlazan a las propiedades de la clase Team, porque el elemento CollectionViewSource facilita de forma automática el equipo seleccionado actualmente de la lista de equipos cuando es necesario.

Vea también