Información general sobre plantillas de datosData Templating Overview

El modelo de plantillas de datos de WPF ofrece gran flexibilidad para definir la presentación de los datos.The WPF data templating model provides you with great flexibility to define the presentation of your data. Los controles WPF tienen funcionalidad integrada que admite la personalización de la presentación de los datos.WPF controls have built-in functionality to support the customization of data presentation. En este tema muestra primero cómo definir un DataTemplate y, a continuación, presenta otras características de plantillas de datos, como la selección de plantillas basadas en la lógica personalizada y la compatibilidad con la presentación de datos jerárquicos.This topic first demonstrates how to define a DataTemplate and then introduces other data templating features, such as the selection of templates based on custom logic and the support for the display of hierarchical data.

Requisitos previosPrerequisites

Este tema se centra en las características de creación de plantillas de datos y no es una introducción a los conceptos de enlace de datos.This topic focuses on data templating features and is not an introduction of data binding concepts. Para información sobre los conceptos básicos de enlace de datos, vea the Información general sobre el enlace de datos.For information about basic data binding concepts, see the Data Binding Overview.

DataTemplate trata la presentación de datos y es una de las muchas características proporcionadas por el modelo de estilos y plantillas WPF.DataTemplate is about the presentation of data and is one of the many features provided by the WPF styling and templating model. Para obtener una introducción del modelo aplicar estilos y plantillas WPF, por ejemplo, cómo usar un Style para establecer propiedades de controles, vea el aplicar estilos y plantillas tema.For an introduction of the WPF styling and templating model, such as how to use a Style to set properties on controls, see the Styling and Templating topic.

Además, es importante comprender Resources, que son esencialmente lo que permiten a los objetos como Style y DataTemplate para poder ser reutilizados.In addition, it is important to understand Resources, which are essentially what enable objects such as Style and DataTemplate to be reusable. Para más información sobre los recursos, vea Recursos XAML.For more information on resources, see XAML Resources.

Conceptos básicos de plantillas de datosData Templating Basics

Para demostrar por qué DataTemplate es importante, vamos a recorrer un ejemplo de enlace de datos.To demonstrate why DataTemplate is important, let's walk through a data binding example. En este ejemplo, tenemos un ListBox que está enlazado a una lista de Task objetos.In this example, we have a ListBox that is bound to a list of Task objects. Cada objeto Task tiene un TaskName (cadena), un Description (cadena), un Priority (int) y una propiedad de tipo TaskType, que es un Enum con valores Home y Work.Each Task object has a TaskName (string), a Description (string), a Priority (int), and a property of type TaskType, which is an Enum with values Home and Work.

<Window x:Class="SDKSample.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:SDKSample"
  Title="Introduction to Data Templating Sample">
  <Window.Resources>
    <local:Tasks x:Key="myTodoList"/>

</Window.Resources>
  <StackPanel>
    <TextBlock Name="blah" FontSize="20" Text="My Task List:"/>
    <ListBox Width="400" Margin="10"
             ItemsSource="{Binding Source={StaticResource myTodoList}}"/>
  </StackPanel>
</Window>

Sin un DataTemplateWithout a DataTemplate

Sin un DataTemplate, nuestro ListBox actualmente tiene este aspecto:Without a DataTemplate, our ListBox currently looks like this:

Captura de pantalla de ejemplo de creación de plantillas de datosData templating sample screenshot

Lo que sucede es que, sin ninguna instrucción concreta, el ListBox mediante llamadas predeterminada ToString al intentar mostrar los objetos de la colección.What's happening is that without any specific instructions, the ListBox by default calls ToString when trying to display the objects in the collection. Por lo tanto, si la Task objeto invalidaciones el ToString método, el ListBox muestra la representación de cadena de cada objeto de origen en la colección subyacente.Therefore, if the Task object overrides the ToString method, then the ListBox displays the string representation of each source object in the underlying collection.

Por ejemplo, si la clase Task invalida el método ToString de esta manera, donde name es el campo para la propiedad TaskName:For example, if the Task class overrides the ToString method this way, where name is the field for the TaskName property:

public override string ToString()
{
    return name.ToString();
}
Public Overrides Function ToString() As String
    Return _name.ToString()
End Function

El ListBox el siguiente aspecto:Then the ListBox looks like the following:

Captura de pantalla de ejemplo de creación de plantillas de datosData templating sample screenshot

Pero eso resulta limitante e inflexible.However, that is limiting and inflexible. Además, si enlaza a datos XMLXML, no podrá invalidar ToString.Also, if you are binding to XMLXML data, you wouldn't be able to override ToString.

Definir un DataTemplate simpleDefining a Simple DataTemplate

La solución consiste en definir un DataTemplate.The solution is to define a DataTemplate. Una manera de hacerlo es establecer el ItemTemplate propiedad de la ListBox a un DataTemplate.One way to do that is to set the ItemTemplate property of the ListBox to a DataTemplate. Lo que especifique en su DataTemplate se convierte en la estructura visual de su objeto de datos.What you specify in your DataTemplate becomes the visual structure of your data object. La siguiente DataTemplate es bastante sencillo.The following DataTemplate is fairly simple. Le estamos ofreciendo instrucciones que cada elemento aparezca como tres TextBlock elementos dentro de un StackPanel.We are giving instructions that each item appears as three TextBlock elements within a StackPanel. Cada TextBlock elemento está enlazado a una propiedad de la Task clase.Each TextBlock element is bound to a property of the Task class.

<ListBox Width="400" Margin="10"
         ItemsSource="{Binding Source={StaticResource myTodoList}}">
   <ListBox.ItemTemplate>
     <DataTemplate>
       <StackPanel>
         <TextBlock Text="{Binding Path=TaskName}" />
         <TextBlock Text="{Binding Path=Description}"/>
         <TextBlock Text="{Binding Path=Priority}"/>
       </StackPanel>
     </DataTemplate>
   </ListBox.ItemTemplate>
 </ListBox>

Los datos subyacentes de los ejemplos de este tema son una colección de objetos CLRCLR.The underlying data for the examples in this topic is a collection of CLRCLR objects. Si enlaza a datos XMLXML, los conceptos fundamentales son los mismos, pero existe una ligera diferencia sintáctica.If you are binding to XMLXML data, the fundamental concepts are the same, but there is a slight syntactic difference. Por ejemplo, en lugar de tener Path=TaskName, establecería XPath a @TaskName (si TaskName es un atributo de su XMLXML nodo).For example, instead of having Path=TaskName, you would set XPath to @TaskName (if TaskName is an attribute of your XMLXML node).

Ahora nuestra ListBox el siguiente aspecto:Now our ListBox looks like the following:

Captura de pantalla de ejemplo de creación de plantillas de datosData templating sample screenshot

Crear el DataTemplate como recursoCreating the DataTemplate as a Resource

En el ejemplo anterior, hemos definido la DataTemplate en línea.In the above example, we defined the DataTemplate inline. Es más frecuente definirlo en la sección de recursos para que pueda ser un objeto reutilizable, como en el ejemplo siguiente:It is more common to define it in the resources section so it can be a reusable object, as in the following example:

<Window.Resources>
<DataTemplate x:Key="myTaskTemplate">
  <StackPanel>
    <TextBlock Text="{Binding Path=TaskName}" />
    <TextBlock Text="{Binding Path=Description}"/>
    <TextBlock Text="{Binding Path=Priority}"/>
  </StackPanel>
</DataTemplate>
</Window.Resources>

Ahora puede usar myTaskTemplate como recurso, como en el ejemplo siguiente:Now you can use myTaskTemplate as a resource, as in the following example:

<ListBox Width="400" Margin="10"
         ItemsSource="{Binding Source={StaticResource myTodoList}}"
         ItemTemplate="{StaticResource myTaskTemplate}"/>

Dado que myTaskTemplate es un recurso, ahora se puede utilizar en otros controles que tienen una propiedad que toma un DataTemplate tipo.Because myTaskTemplate is a resource, you can now use it on other controls that have a property that takes a DataTemplate type. Como se muestra anteriormente, para ItemsControl objetos, como el ListBox, es el ItemTemplate propiedad.As shown above, for ItemsControl objects, such as the ListBox, it is the ItemTemplate property. Para ContentControl objetos, es el ContentTemplate propiedad.For ContentControl objects, it is the ContentTemplate property.

La propiedad DataTypeThe DataType Property

El DataTemplate clase tiene un DataType propiedad que es muy similar a la TargetType propiedad de la Style clase.The DataTemplate class has a DataType property that is very similar to the TargetType property of the Style class. Por lo tanto, en lugar de especificar un x:Key para el DataTemplate en el ejemplo anterior, puede hacer lo siguiente:Therefore, instead of specifying an x:Key for the DataTemplate in the above example, you can do the following:

<DataTemplate DataType="{x:Type local:Task}">
  <StackPanel>
    <TextBlock Text="{Binding Path=TaskName}" />
    <TextBlock Text="{Binding Path=Description}"/>
    <TextBlock Text="{Binding Path=Priority}"/>
  </StackPanel>
</DataTemplate>

Esto DataTemplate se aplica automáticamente a todos los Task objetos.This DataTemplate gets applied automatically to all Task objects. Tenga en cuenta que en este caso el x:Key se establece implícitamente.Note that in this case the x:Key is set implicitly. Por lo tanto, si se asigna esta DataTemplate una x:Key valor, se va a reemplazar implícito x:Key y DataTemplate no se aplicaría automáticamente.Therefore, if you assign this DataTemplate an x:Key value, you are overriding the implicit x:Key and the DataTemplate would not be applied automatically.

Si va a enlazar un ContentControl a una colección de Task objetos, el ContentControl no utiliza el anterior DataTemplate automáticamente.If you are binding a ContentControl to a collection of Task objects, the ContentControl does not use the above DataTemplate automatically. Esto es porque el enlace en un ContentControl necesita más información para distinguir si desea enlazar a una colección completa o los objetos individuales.This is because the binding on a ContentControl needs more information to distinguish whether you want to bind to an entire collection or the individual objects. Si su ContentControl seguimiento de la selección de un ItemsControl tipo, puede establecer el Path propiedad de la ContentControl enlazar a "/" para indicar que estás interesado en el elemento actual.If your ContentControl is tracking the selection of an ItemsControl type, you can set the Path property of the ContentControl binding to "/" to indicate that you are interested in the current item. Para obtener un ejemplo, vea Bind to a Collection and Display Information Based on Selection (Cómo: Enlazar a una colección y mostrar información basada en la selección).For an example, see Bind to a Collection and Display Information Based on Selection. En caso contrario, deberá especificar el DataTemplate explícitamente estableciendo la ContentTemplate propiedad.Otherwise, you need to specify the DataTemplate explicitly by setting the ContentTemplate property.

El DataType propiedad resulta especialmente útil cuando tenga un CompositeCollection de diferentes tipos de objetos de datos.The DataType property is particularly useful when you have a CompositeCollection of different types of data objects. Para obtener un ejemplo, vea Implement a CompositeCollection (Cómo: Implementar una CompositeCollection).For an example, see Implement a CompositeCollection.

Agregar más elementos al DataTemplateAdding More to the DataTemplate

Actualmente los datos aparecen con la información necesaria, pero sin duda hay margen de mejora.Currently the data appears with the necessary information, but there's definitely room for improvement. Vamos a mejorar la presentación agregando un Border, un Gridy algunos TextBlock elementos que describen los datos que se va a mostrar.Let's improve on the presentation by adding a Border, a Grid, and some TextBlock elements that describe the data that is being displayed.


<DataTemplate x:Key="myTaskTemplate">
  <Border Name="border" BorderBrush="Aqua" BorderThickness="1"
          Padding="5" Margin="5">
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <TextBlock Grid.Row="0" Grid.Column="0" Text="Task Name:"/>
      <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=TaskName}" />
      <TextBlock Grid.Row="1" Grid.Column="0" Text="Description:"/>
      <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/>
      <TextBlock Grid.Row="2" Grid.Column="0" Text="Priority:"/>
      <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>
    </Grid>
  </Border>
</DataTemplate>

La siguiente captura de pantalla muestra la ListBox con esto se puede modificar DataTemplate:The following screenshot shows the ListBox with this modified DataTemplate:

Captura de pantalla de ejemplo de creación de plantillas de datosData templating sample screenshot

Podemos establecer HorizontalContentAlignment a Stretch en el ListBox para asegurarse de que el ancho de los elementos ocupe todo el espacio:We can set HorizontalContentAlignment to Stretch on the ListBox to make sure the width of the items takes up the entire space:

<ListBox Width="400" Margin="10"
     ItemsSource="{Binding Source={StaticResource myTodoList}}"
     ItemTemplate="{StaticResource myTaskTemplate}" 
     HorizontalContentAlignment="Stretch"/>

Con el HorizontalContentAlignment propiedad establecida en Stretch, el ListBox ahora tiene este aspecto:With the HorizontalContentAlignment property set to Stretch, the ListBox now looks like this:

Captura de pantalla de ejemplo de creación de plantillas de datosData templating sample screenshot

Usar DataTriggers para aplicar valores de propiedadUse DataTriggers to Apply Property Values

La presentación actual no nos indica si una Task es una tarea doméstica o una tarea de oficina.The current presentation does not tell us whether a Task is a home task or an office task. Recuerde que el objeto Task tiene una propiedad TaskType de tipo TaskType, que es una enumeración con valores Home y Work.Remember that the Task object has a TaskType property of type TaskType, which is an enumeration with values Home and Work.

En el ejemplo siguiente, la DataTrigger establece la BorderBrush del elemento denominado border a Yellow si el TaskType propiedad es TaskType.Home.In the following example, the DataTrigger sets the BorderBrush of the element named border to Yellow if the TaskType property is TaskType.Home.

<DataTemplate x:Key="myTaskTemplate">
<DataTemplate.Triggers>
  <DataTrigger Binding="{Binding Path=TaskType}">
    <DataTrigger.Value>
      <local:TaskType>Home</local:TaskType>
    </DataTrigger.Value>
    <Setter TargetName="border" Property="BorderBrush" Value="Yellow"/>
  </DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>

Nuestra aplicación tiene ahora el aspecto siguiente.Our application now looks like the following. Las tareas domésticas aparecen con un borde amarillo y las tareas de oficina, con un borde aguamarina:Home tasks appear with a yellow border and office tasks appear with an aqua border:

Captura de pantalla de ejemplo de creación de plantillas de datosData templating sample screenshot

En este ejemplo el DataTrigger usa un Setter para establecer un valor de propiedad.In this example the DataTrigger uses a Setter to set a property value. Las clases de desencadenador tienen también la EnterActions y ExitActions propiedades que le permiten iniciar un conjunto de acciones, como animaciones.The trigger classes also have the EnterActions and ExitActions properties that allow you to start a set of actions such as animations. Además, también hay un MultiDataTrigger clase que le permite aplicar los cambios en función de varios valores de propiedad enlazada a datos.In addition, there is also a MultiDataTrigger class that allows you to apply changes based on multiple data-bound property values.

Una manera alternativa de conseguir el mismo efecto es enlazar el BorderBrush propiedad a la TaskType propiedad y use un convertidor de valores para devolver el color según el TaskType valor.An alternative way to achieve the same effect is to bind the BorderBrush property to the TaskType property and use a value converter to return the color based on the TaskType value. La creación del efecto anterior mediante un convertidor es ligeramente más eficiente en términos de rendimiento.Creating the above effect using a converter is slightly more efficient in terms of performance. Además, la creación de su propio convertidor le brinda mayor flexibilidad porque usted proporciona su propia lógica.Additionally, creating your own converter gives you more flexibility because you are supplying your own logic. En última instancia, la técnica que elija depende de su escenario y de sus preferencias.Ultimately, which technique you choose depends on your scenario and your preference. Para obtener información sobre cómo escribir un convertidor de tipos, vea IValueConverter.For information about how to write a converter, see IValueConverter.

Lo que corresponde a un DataTemplateWhat Belongs in a DataTemplate?

En el ejemplo anterior, situamos el desencadenador dentro de la DataTemplate mediante el DataTemplate.TriggersIn the previous example, we placed the trigger within the DataTemplate using the DataTemplate.Triggers propiedad.property. El Setter del desencadenador establece el valor de una propiedad de un elemento (el Border elemento) que está dentro de la DataTemplate.The Setter of the trigger sets the value of a property of an element (the Border element) that is within the DataTemplate. Sin embargo, si las propiedades que su Setters les preocupa no son propiedades de elementos que están dentro del actual DataTemplate, puede ser más adecuado establecer las propiedades mediante un Style que es para el ListBoxItem clase (si el control que se va a enlazar es un ListBox).However, if the properties that your Setters are concerned with are not properties of elements that are within the current DataTemplate, it may be more suitable to set the properties using a Style that is for the ListBoxItem class (if the control you are binding is a ListBox). Por ejemplo, si desea que su Trigger para animar la Opacity valor del elemento cuando un mouse apunta a un elemento, defina desencadenadores en una ListBoxItem estilo.For example, if you want your Trigger to animate the Opacity value of the item when a mouse points to an item, you define triggers within a ListBoxItem style. Para obtener un ejemplo, vea Introducción a la aplicación de estilos y plantillas de ejemplo.For an example, see the Introduction to Styling and Templating Sample.

En general, tenga en cuenta que el DataTemplate se aplica a cada uno de los generados ListBoxItem (para obtener más información acerca de cómo y dónde se aplica realmente, vea la ItemTemplate página.).In general, keep in mind that the DataTemplate is being applied to each of the generated ListBoxItem (for more information about how and where it is actually applied, see the ItemTemplate page.). Su DataTemplate se refiere a solo la presentación y la apariencia de los objetos de datos.Your DataTemplate is concerned with only the presentation and appearance of the data objects. En la mayoría de los casos, es similar a todos los demás aspectos de presentación, como un elemento cuando se selecciona o cómo la ListBox establece los elementos, no pertenecen a la definición de un DataTemplate.In most cases, all other aspects of presentation, such as what an item looks like when it is selected or how the ListBox lays out the items, do not belong in the definition of a DataTemplate. Para obtener un ejemplo, vea la sección Aplicar estilos y plantillas con un ItemsControl.For an example, see the Styling and Templating an ItemsControl section.

Elegir un DataTemplate en función de las propiedades del objeto de datosChoosing a DataTemplate Based on Properties of the Data Object

En la sección La propiedad DataType, explicamos que se pueden definir distintas plantillas de datos para objetos de datos diferentes.In The DataType Property section, we discussed that you can define different data templates for different data objects. Esto resulta especialmente útil cuando tenga un CompositeCollection de diferentes tipos o colecciones con elementos de diferentes tipos.That is especially useful when you have a CompositeCollection of different types or collections with items of different types. En el usar DataTriggers para aplicar valores de propiedad sección, hemos mostrado que si tiene una colección del mismo tipo de objetos de datos puede crear un DataTemplate y, a continuación, utilizar desencadenadores para aplicar cambios basados en los valores de propiedad cada objeto de datos.In the Use DataTriggers to Apply Property Values section, we have shown that if you have a collection of the same type of data objects you can create a DataTemplate and then use triggers to apply changes based on the property values of each data object. Aunque los desencadenadores le permiten aplicar valores de propiedad o iniciar animaciones, no le ofrecen la flexibilidad de reconstruir la estructura de los objetos de datos.However, triggers allow you to apply property values or start animations but they don't give you the flexibility to reconstruct the structure of your data objects. Algunos escenarios pueden requerir que crear otra DataTemplate para datos de objetos que son del mismo tipo pero tienen propiedades diferentes.Some scenarios may require you to create a different DataTemplate for data objects that are of the same type but have different properties.

Por ejemplo, puede que cuando un objeto Task tenga un valor Priority de 1 quiera darle un aspecto completamente distinto para que actúe como alerta para usted mismo.For example, when a Task object has a Priority value of 1, you may want to give it a completely different look to serve as an alert for yourself. En ese caso, crea un DataTemplate para la presentación de alta prioridad Task objetos.In that case, you create a DataTemplate for the display of the high-priority Task objects. Vamos a agregar la siguiente DataTemplate a la sección de recursos:Let's add the following DataTemplate to the resources section:

<DataTemplate x:Key="importantTaskTemplate">
  <DataTemplate.Resources>
    <Style TargetType="TextBlock">
      <Setter Property="FontSize" Value="20"/>
    </Style>
  </DataTemplate.Resources>
  <Border Name="border" BorderBrush="Red" BorderThickness="1"
          Padding="5" Margin="5">
    <DockPanel HorizontalAlignment="Center">
      <TextBlock Text="{Binding Path=Description}" />
      <TextBlock>!</TextBlock>
    </DockPanel>
  </Border>
</DataTemplate>

Tenga en cuenta este ejemplo se utiliza el DataTemplate.ResourcesNotice this example uses the DataTemplate.Resources propiedad.property. Los recursos definidos en esa sección son compartidos por los elementos dentro de la DataTemplate.Resources defined in that section are shared by the elements within the DataTemplate.

Para proporcionar lógica para elegir qué DataTemplate utilizar según la Priority valor del objeto de datos, cree una subclase de DataTemplateSelector e invalidar la SelectTemplate método.To supply logic to choose which DataTemplate to use based on the Priority value of the data object, create a subclass of DataTemplateSelector and override the SelectTemplate method. En el ejemplo siguiente, la SelectTemplate método proporciona la lógica para devolver la plantilla adecuada en función del valor de la Priority propiedad.In the following example, the SelectTemplate method provides logic to return the appropriate template based on the value of the Priority property. La plantilla que se devuelve se encuentra en los recursos de la envoltura Window elemento.The template to return is found in the resources of the enveloping Window element.

using System.Windows;
using System.Windows.Controls;

namespace SDKSample
{
    public class TaskListDataTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate
            SelectTemplate(object item, DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;

            if (element != null && item != null && item is Task)
            {
                Task taskitem = item as Task;

                if (taskitem.Priority == 1)
                    return
                        element.FindResource("importantTaskTemplate") as DataTemplate;
                else
                    return
                        element.FindResource("myTaskTemplate") as DataTemplate;
            }

            return null;
        }
    }
}

Namespace SDKSample
    Public Class TaskListDataTemplateSelector
        Inherits DataTemplateSelector
        Public Overrides Function SelectTemplate(ByVal item As Object, ByVal container As DependencyObject) As DataTemplate

            Dim element As FrameworkElement
            element = TryCast(container, FrameworkElement)

            If element IsNot Nothing AndAlso item IsNot Nothing AndAlso TypeOf item Is Task Then

                Dim taskitem As Task = TryCast(item, Task)

                If taskitem.Priority = 1 Then
                    Return TryCast(element.FindResource("importantTaskTemplate"), DataTemplate)
                Else
                    Return TryCast(element.FindResource("myTaskTemplate"), DataTemplate)
                End If
            End If

            Return Nothing
        End Function
    End Class
End Namespace

Podemos declarar el TaskListDataTemplateSelector como recurso:We can then declare the TaskListDataTemplateSelector as a resource:

<Window.Resources>
<local:TaskListDataTemplateSelector x:Key="myDataTemplateSelector"/>
</Window.Resources>

Para usar el recurso del selector de plantillas, asígnelo a la ItemTemplateSelector propiedad de la ListBox.To use the template selector resource, assign it to the ItemTemplateSelector property of the ListBox. El ListBox llamadas la SelectTemplate método de la TaskListDataTemplateSelector para cada uno de los elementos de la colección subyacente.The ListBox calls the SelectTemplate method of the TaskListDataTemplateSelector for each of the items in the underlying collection. La llamada pasa el objeto de datos como parámetro del elemento.The call passes the data object as the item parameter. El DataTemplate devuelta por el método, a continuación, se aplica al objeto de datos.The DataTemplate that is returned by the method is then applied to that data object.

<ListBox Width="400" Margin="10"
         ItemsSource="{Binding Source={StaticResource myTodoList}}"
         ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
         HorizontalContentAlignment="Stretch"/>

Con el selector de plantillas en su lugar, el ListBox aparece ahora como sigue:With the template selector in place, the ListBox now appears as follows:

Captura de pantalla de ejemplo de creación de plantillas de datosData templating sample screenshot

Con esto concluye la explicación de este ejemplo.This concludes our discussion of this example. Para obtener el ejemplo completo, vea Introducción a la aplicación de plantillas de ejemplo.For the complete sample, see Introduction to Data Templating Sample.

Aplicar estilos y plantillas con un ItemsControlStyling and Templating an ItemsControl

Aunque el ItemsControl no es el único tipo de control que puede usar un DataTemplate con, es un escenario muy común para enlazar un ItemsControl a una colección.Even though the ItemsControl is not the only control type that you can use a DataTemplate with, it is a very common scenario to bind an ItemsControl to a collection. En el lo que corresponde a un DataTemplate sección analizamos que la definición de su DataTemplate solo debe tener en cuenta la presentación de datos.In the What Belongs in a DataTemplate section we discussed that the definition of your DataTemplate should only be concerned with the presentation of data. Para saber cuándo no es adecuado usar un DataTemplate es importante comprender las distintas propiedades de estilo y plantilla proporcionadas por el ItemsControl.In order to know when it is not suitable to use a DataTemplate it is important to understand the different style and template properties provided by the ItemsControl. El ejemplo siguiente se ha diseñado para ilustrar la función de cada una de dichas propiedades.The following example is designed to illustrate the function of each of these properties. El ItemsControl en este ejemplo se enlaza a la misma Tasks colección del ejemplo anterior.The ItemsControl in this example is bound to the same Tasks collection as in the previous example. A efectos de demostración, los estilos y las plantillas de este ejemplo se declaran todas como inline.For demonstration purposes, the styles and templates in this example are all declared inline.

<ItemsControl Margin="10"
              ItemsSource="{Binding Source={StaticResource myTodoList}}">
  <!--The ItemsControl has no default visual appearance.
      Use the Template property to specify a ControlTemplate to define
      the appearance of an ItemsControl. The ItemsPresenter uses the specified
      ItemsPanelTemplate (see below) to layout the items. If an
      ItemsPanelTemplate is not specified, the default is used. (For ItemsControl,
      the default is an ItemsPanelTemplate that specifies a StackPanel.-->
  <ItemsControl.Template>
    <ControlTemplate TargetType="ItemsControl">
      <Border BorderBrush="Aqua" BorderThickness="1" CornerRadius="15">
        <ItemsPresenter/>
      </Border>
    </ControlTemplate>
  </ItemsControl.Template>
  <!--Use the ItemsPanel property to specify an ItemsPanelTemplate
      that defines the panel that is used to hold the generated items.
      In other words, use this property if you want to affect
      how the items are laid out.-->
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <WrapPanel />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <!--Use the ItemTemplate to set a DataTemplate to define
      the visualization of the data objects. This DataTemplate
      specifies that each data object appears with the Proriity
      and TaskName on top of a silver ellipse.-->
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <DataTemplate.Resources>
        <Style TargetType="TextBlock">
          <Setter Property="FontSize" Value="18"/>
          <Setter Property="HorizontalAlignment" Value="Center"/>
        </Style>
      </DataTemplate.Resources>
      <Grid>
        <Ellipse Fill="Silver"/>
        <StackPanel>
          <TextBlock Margin="3,3,3,0"
                     Text="{Binding Path=Priority}"/>
          <TextBlock Margin="3,0,3,7"
                     Text="{Binding Path=TaskName}"/>
        </StackPanel>
      </Grid>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
  <!--Use the ItemContainerStyle property to specify the appearance
      of the element that contains the data. This ItemContainerStyle
      gives each item container a margin and a width. There is also
      a trigger that sets a tooltip that shows the description of
      the data object when the mouse hovers over the item container.-->
  <ItemsControl.ItemContainerStyle>
    <Style>
      <Setter Property="Control.Width" Value="100"/>
      <Setter Property="Control.Margin" Value="5"/>
      <Style.Triggers>
        <Trigger Property="Control.IsMouseOver" Value="True">
          <Setter Property="Control.ToolTip"
                  Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                          Path=Content.Description}"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </ItemsControl.ItemContainerStyle>
</ItemsControl>

La siguiente captura de pantalla muestra el ejemplo cuando se representa:The following is a screenshot of the example when it is rendered:

Captura de pantalla de ejemplo ItemsControlItemsControl example screenshot

Tenga en cuenta que en lugar de usar el ItemTemplate, puede usar el ItemTemplateSelector.Note that instead of using the ItemTemplate, you can use the ItemTemplateSelector. Consulte la sección anterior para obtener un ejemplo.Refer to the previous section for an example. De forma similar, en lugar de usar el ItemContainerStyle, tiene la opción para usar el ItemContainerStyleSelector.Similarly, instead of using the ItemContainerStyle, you have the option to use the ItemContainerStyleSelector.

Dos otras propiedades relacionadas con el estilo de la ItemsControl que no se muestran aquí son GroupStyle y GroupStyleSelector.Two other style-related properties of the ItemsControl that are not shown here are GroupStyle and GroupStyleSelector.

Compatibilidad con datos jerárquicosSupport for Hierarchical Data

Hasta ahora solo hemos examinado cómo enlazar a una sola colección y mostrarla.So far we have only looked at how to bind to and display a single collection. A veces se tiene una colección que contiene otras colecciones.Sometimes you have a collection that contains other collections. El HierarchicalDataTemplate clase está diseñada para usarse con HeaderedItemsControl tipos para mostrar esos datos.The HierarchicalDataTemplate class is designed to be used with HeaderedItemsControl types to display such data. En el ejemplo siguiente, ListLeagueList es una lista de objetos League.In the following example, ListLeagueList is a list of League objects. Cada objeto League tiene un Name y una colección de objetos Division.Each League object has a Name and a collection of Division objects. Cada Division tiene un Name y una colección de objetos Team y cada objeto Team tiene un Name.Each Division has a Name and a collection of Team objects, and each Team object has a Name.

<Window x:Class="SDKSample.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="HierarchicalDataTemplate Sample"
  xmlns:src="clr-namespace:SDKSample">
  <DockPanel>
    <DockPanel.Resources>
      <src:ListLeagueList x:Key="MyList"/>

      <HierarchicalDataTemplate DataType    = "{x:Type src:League}"
                                ItemsSource = "{Binding Path=Divisions}">
        <TextBlock Text="{Binding Path=Name}"/>
      </HierarchicalDataTemplate>

      <HierarchicalDataTemplate DataType    = "{x:Type src:Division}"
                                ItemsSource = "{Binding Path=Teams}">
        <TextBlock Text="{Binding Path=Name}"/>
      </HierarchicalDataTemplate>

      <DataTemplate DataType="{x:Type src:Team}">
        <TextBlock Text="{Binding Path=Name}"/>
      </DataTemplate>
    </DockPanel.Resources>

    <Menu Name="menu1" DockPanel.Dock="Top" Margin="10,10,10,10">
        <MenuItem Header="My Soccer Leagues"
                  ItemsSource="{Binding Source={StaticResource MyList}}" />
    </Menu>

    <TreeView>
      <TreeViewItem ItemsSource="{Binding Source={StaticResource MyList}}" Header="My Soccer Leagues" />
    </TreeView>

  </DockPanel>
</Window>

En el ejemplo se muestra que, con el uso de HierarchicalDataTemplate, puede mostrar fácilmente datos de la lista que contiene otras listas.The example shows that with the use of HierarchicalDataTemplate, you can easily display list data that contains other lists. La siguiente captura de pantalla muestra el ejemplo.The following is a screenshot of the example.

HierarchicalDataTemplate sample screenshotHierarchicalDataTemplate sample screenshot

Vea tambiénSee also