Vue d'ensemble des modèles de données

 

Date de publication : juin 2016

Le Entity with relative path '../Token/TLA2%23tla_winclient_md.md' can not be found, for source topic '{"project_id":"3fedad16-eaf1-41a6-8f96-0c1949c68f32","entity_id":"0f4d9f8c-0230-4013-bd7b-e8e7fed01b4a","entity_type":"Article","locale":"fr-FR"}'. modèle de création de modèles de données vous offre une grande souplesse pour définir la présentation de vos données. Entity with relative path '../Token/TLA2%23tla_winclient_md.md' can not be found, for source topic '{"project_id":"3fedad16-eaf1-41a6-8f96-0c1949c68f32","entity_id":"0f4d9f8c-0230-4013-bd7b-e8e7fed01b4a","entity_type":"Article","locale":"fr-FR"}'.les contrôles ont des fonctionnalités intégrées pour prendre en charge la personnalisation de la présentation des données. Cette rubrique montre tout d’abord comment définir un DataTemplate et présente d’autres fonctionnalités de création de modèles de données, telles que la sélection des modèles basés sur la logique personnalisée et la prise en charge pour l’affichage des données hiérarchiques.

Entity with relative path '../Token/autoOutline_md.md' can not be found, for source topic '{"project_id":"3fedad16-eaf1-41a6-8f96-0c1949c68f32","entity_id":"0f4d9f8c-0230-4013-bd7b-e8e7fed01b4a","entity_type":"Article","locale":"fr-FR"}'.

Cette rubrique se concentre sur les fonctionnalités de création de modèles de données et n’est pas une présentation des concepts de liaison de données. Pour plus d’informations sur les concepts de liaison de données de base, consultez le vue d’ensemble de la liaison de données.

DataTemplate concerne la présentation des données et est une des nombreuses fonctionnalités fournies par le Entity with relative path '../Token/TLA2%23tla_winclient_md.md' can not be found, for source topic '{"project_id":"3fedad16-eaf1-41a6-8f96-0c1949c68f32","entity_id":"0f4d9f8c-0230-4013-bd7b-e8e7fed01b4a","entity_type":"Article","locale":"fr-FR"}'. styles et modèles. Pour obtenir une présentation de la Entity with relative path '../Token/TLA2%23tla_winclient_md.md' can not be found, for source topic '{"project_id":"3fedad16-eaf1-41a6-8f96-0c1949c68f32","entity_id":"0f4d9f8c-0230-4013-bd7b-e8e7fed01b4a","entity_type":"Article","locale":"fr-FR"}'. modèle, telles que l’utilisation d’un Style pour définir des propriétés sur les contrôles, consultez la styles et modèles rubrique.

En outre, il est important de comprendre Resources, qui permettent essentiellement les objets tels que Style et DataTemplate être réutilisables. Pour plus d’informations sur les ressources, consultez ressources XAML.

Entity with relative path '../Token/autoOutline_md.md' can not be found, for source topic '{"project_id":"3fedad16-eaf1-41a6-8f96-0c1949c68f32","entity_id":"0f4d9f8c-0230-4013-bd7b-e8e7fed01b4a","entity_type":"Article","locale":"fr-FR"}'.

Pour illustrer pourquoi DataTemplate est important, nous allons étudier un exemple de liaison de données. Dans cet exemple, nous avons un ListBox qui est lié à une liste de Task objets. Chaque Task objet a un TaskName (chaîne), un Description (chaîne), un Priority (int) et une propriété de type TaskType, qui est un Enum avec les valeurs Home et 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>

Sans un DataTemplate

Sans un DataTemplate, notre ListBox actuellement ressemble à ceci :

Capture d’écran exemple modèle données

Que se passe-t-il qui est sans instruction spécifique, le ListBox appelle par défaut ToString lorsque vous tentez d’afficher les objets dans la collection. Par conséquent, si le Task substitue l’objet le ToString (méthode), puis le ListBox affiche la représentation sous forme de chaîne de chaque objet source dans la collection sous-jacente.

Par exemple, si le Task substitue le ToString méthode de cette façon, où name correspond au champ de la TaskName propriété :

      public override string ToString()
      {
          return name.ToString();
      }

Le ListBox ressemble à ceci :

Capture d’écran exemple modèle données

Toutefois, ceci est restrictif et rigide. En outre, si vous liez à XML les données, vous ne pourriez pas substituer ToString.

Définition d’un DataTemplate Simple

La solution consiste à définir un DataTemplate. Une méthode qui consiste à définir le ItemTemplate propriété de la ListBox à un DataTemplate. Vous spécifiez dans votre DataTemplate devient la structure visuelle de l’objet de données. Les éléments suivants DataTemplate est relativement simple. Nous offrons des instructions, chaque élément apparaît sous forme de trois TextBlock éléments au sein d’un StackPanel. Chaque TextBlock élément soit lié à une propriété de la Task classe.

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

Les données sous-jacentes pour les exemples de cette rubrique sont une collection de CLR objets. Si vous liez à XML les données, les concepts fondamentaux sont identiques, mais il existe une légère différence syntaxique. Par exemple, au lieu d’avoir Path=TaskName, vous devez définir XPath à @TaskName (si TaskName est un attribut de votre XML nœud).

Maintenant notre ListBox ressemble à ceci :

Capture d’écran exemple modèle données

Création d’une ressource DataTemplate

Dans l’exemple ci-dessus, nous avons défini la DataTemplate inline. Il est plus courant de définir dans la section de ressources afin d’en faire un objet réutilisable, comme dans l’exemple suivant :

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

Vous pouvez désormais utiliser myTaskTemplate en tant que ressource, comme dans l’exemple suivant :

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

Étant donné que myTaskTemplate est une ressource, vous pouvez maintenant l’utiliser sur d’autres contrôles qui ont une propriété qui accepte un DataTemplate type. Comme indiqué ci-dessus, pour ItemsControl objets, tels que les ListBox, il s’agit du ItemTemplate propriété. Pour ContentControl des objets, il est la ContentTemplate propriété.

La propriété type de données

Le DataTemplate classe a un type de données propriété est très similaire à la TargetType propriété de la Style classe. Par conséquent, au lieu de spécifier un x:Key pour la DataTemplate dans l’exemple ci-dessus, vous pouvez procédez comme suit :

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

Cela DataTemplate est appliqué automatiquement à tous les Task objets. Notez que dans ce cas la x:Key est définie implicitement. Par conséquent, si vous affectez DataTemplate un x:Key valeur, vous substituez implicite x:Key et DataTemplate n’est pas appliqué automatiquement.

Si vous liez un ContentControl à une collection de Task des objets, le ContentControl n’utilise pas ces DataTemplate automatiquement. C’est parce que la liaison sur un ContentControl nécessite davantage d’informations pour déterminer si vous souhaitez lier à une collection complète ou avec des objets. Si votre ContentControl effectue le suivi de la sélection d’un ItemsControl , vous pouvez définir le type le chemin d’accès propriété du ContentControl liaison à «/» pour indiquer que vous êtes intéressé par l’élément actuel. Pour obtenir un exemple, consultez lier à une Collection et des informations sur la sélection. Dans le cas contraire, vous devez spécifier le DataTemplate explicitement en définissant le ContentTemplate propriété.

Le type de données propriété est particulièrement utile lorsque vous avez un CompositeCollection de différents types d’objets de données. Pour obtenir un exemple, consultez implémenter une classe CompositeCollection.

Actuellement, les données s’affiche avec les informations nécessaires, mais il est sans aucun doute améliorée. Nous allons améliorer la présentation en ajoutant un bordure, un grilleet certains TextBlock éléments qui décrivent les données affichées.


    <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 capture d’écran suivante montre les ListBox avec cette modification DataTemplate:

Capture d’écran exemple modèle données

Nous pouvons définir HorizontalContentAlignment à Stretch sur la ListBox pour vous assurer que la largeur des éléments occupe tout l’espace disponible :

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

Avec le HorizontalContentAlignment propriété Stretch, le ListBox se présente comme suit :

Capture d’écran exemple modèle données

Utiliser DataTrigger pour appliquer des valeurs de propriété

La présentation actuelle n’indique pas si un Task est une tâche de base ou une tâche d’office. N’oubliez pas que la Task objet a un TaskType propriété de type TaskType, qui est une énumération avec les valeurs Home et Work.

Dans l’exemple suivant, la DataTrigger définit les BorderBrush de l’élément nommé border à Yellow si le TaskType propriété est 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>

Notre application se présente maintenant comme suit. Les tâches privées apparaissent avec une bordure jaune et tâches professionnelles s’affichent avec une bordure cyan :

Capture d’écran exemple modèle données

Dans cet exemple la DataTrigger utilise un Set pour définir une valeur de propriété. Les classes de déclencheur comportent également les EnterActions et ExitActions propriétés qui vous permettent de démarrer un jeu d’actions telles que des animations. En outre, il existe également un MultiDataTrigger classe qui vous permet d’appliquer les modifications en fonction de plusieurs valeurs de propriété liée aux données.

Une autre façon d’obtenir le même effet consiste à lier le BorderBrush propriété du TaskType propriété et utiliser un convertisseur de valeur pour retourner la couleur selon la TaskType valeur. Création de l’effet ci-dessus à l’aide d’un convertisseur est légèrement plus efficace en termes de performances. En outre, la création de votre propre convertisseur offre plus de souplesse, car vous fournissez votre propre logique. Au final, la technique que vous choisissez dépend de votre scénario et vos préférences. Pour plus d’informations sur la façon d’écrire un convertisseur, consultez IValueConverter.

Ce qui appartient à un DataTemplate ?

Dans l’exemple précédent, nous avons placé le déclencheur dans le DataTemplate à l’aide de la DataTemplate. Déclencheurs propriété. Le Setter déclencheur définit la valeur d’une propriété d’un élément (la bordure élément) qui figure dans le DataTemplate. Toutefois, si les propriétés qui votre Setters concerne ne sont pas des propriétés d’éléments qui se trouvent dans le courant DataTemplate, il peut être préférable de définir les propriétés à l’aide un Style pour la ListBoxItem (classe) (si le contrôle lié est un ListBox). Par exemple, si vous souhaitez que votre déclencheur pour animer la opacité valeur de l’élément lorsque la souris pointe sur un élément, vous définissez des déclencheurs dans un ListBoxItem style. Pour obtenir un exemple, consultez la Introduction aux styles et modèles exemple.

En règle générale, n’oubliez pas que la DataTemplate est appliqué à chaque généré ListBoxItem (pour plus d’informations sur comment et où elle est réellement appliquée, consultez le ItemTemplate page.). Votre DataTemplate s’inquiète du fait seulement la présentation et l’apparence des objets de données. Dans la plupart des cas, tous les autres aspects de présentation, par exemple un élément ressemble à lorsqu’il est sélectionné ou la ListBox disposition des éléments, n’appartiennent pas dans la définition d’un DataTemplate. Pour obtenir un exemple, consultez la styles et modèles d’un ItemsControl section.

Dans la propriété DataType section, nous avons abordé que vous pouvez définir des modèles de données différents pour différents objets de données. C’est particulièrement utile lorsque vous avez un CompositeCollection de types différents ou des regroupements avec des éléments de types différents. Dans le Utiliser DataTrigger pour appliquer des valeurs de propriété section, nous avons montré que si vous avez une collection du même type d’objets de données vous pouvez créer un DataTemplate , puis utiliser des déclencheurs pour appliquer des modifications basées sur les valeurs de propriété de chaque objet de données. Toutefois appliquer des valeurs de propriété ou démarrer des animations déclencheurs permettent, mais elles ne vous donne la possibilité de reconstruire la structure de vos objets de données. Certains scénarios pouvant vous obliger à créer une autre DataTemplate pour les données les objets qui sont du même type, mais comportant des propriétés différentes.

Par exemple, lorsque un Task objet a un Priority valeur 1, vous souhaiterez peut-être lui donner un aspect pour servir une alerte par vous-même. Dans ce cas, vous créez un DataTemplate pour l’affichage de la haute priorité Task objets. Nous allons ajouter les éléments suivants DataTemplate à la section de ressources :

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

Notez que cet exemple utilise le DataTemplate. Ressources propriété. Les ressources définies dans cette section sont partagées par les éléments dans le DataTemplate.

Pour fournir une logique permettant de choisir le DataTemplate à utiliser en fonction de la Priority valeur de l’objet de données, créez une sous-classe de DataTemplateSelector et remplacez le SelectTemplate (méthode). Dans l’exemple suivant, la SelectTemplate méthode fournit une logique pour retourner le modèle approprié en fonction de la valeur de la Priority propriété. Le modèle à retourner est recherché dans les ressources de l’enveloppe fenêtre élément.

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

Vous pouvez ensuite déclarer le TaskListDataTemplateSelector en tant que ressource :

  <Window.Resources>

    <local:TaskListDataTemplateSelector x:Key="myDataTemplateSelector"/>

</Window.Resources>

Pour utiliser la ressource de sélecteur de modèle, assignez-la à la ItemTemplateSelector propriétés de la ListBox. Le ListBox appelle la SelectTemplate procédé de la TaskListDataTemplateSelector pour chacun des éléments dans la collection sous-jacente. L’appel passe l’objet de données en tant que paramètre de l’élément. Le DataTemplate qui est retourné par la méthode est ensuite appliquée à cet objet de données.

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

Le sélecteur de modèle en place, les ListBox se présente comme suit :

Capture d’écran exemple modèle données

Ceci conclut notre discussion de cet exemple. Pour l’exemple complet, consultez la page Introduction aux modèles de données exemple.

Bien que le ItemsControl n’est pas le seul type de contrôle que vous pouvez utiliser un DataTemplate , il est très fréquent de lier un ItemsControl à une collection. Dans le ce qui appartient à un DataTemplate section que nous avons abordé que la définition de votre DataTemplate ne doit être concernées par la présentation des données. Pour savoir quand il n’est pas recommandé d’utiliser un DataTemplate qu’il est important de comprendre les différentes propriétés de style et de modèle fournies par le ItemsControl. L’exemple suivant est conçu pour illustrer la fonction de chacune de ces propriétés. Le ItemsControl dans cet exemple est lié à la même Tasks collection comme dans l’exemple précédent. Démonstration à des fins, les styles et les modèles dans cet exemple sont tous déclarés 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>

Voici une capture d’écran de l’exemple lorsqu’il est restitué :

Capture d’écran exemple de ItemsControl

Notez que, au lieu d’utiliser la ItemTemplate, vous pouvez utiliser la ItemTemplateSelector. Reportez-vous à la section précédente pour obtenir un exemple. De même, au lieu d’utiliser la ItemContainerStyle, vous avez la possibilité d’utiliser le ItemContainerStyleSelector.

Deux autres propriétés de style de la ItemsControl qui ne sont pas affichés ici sont GroupStyle et GroupStyleSelector.

Jusqu'à présent, nous avons vu seulement comment lier et afficher une collection unique. Parfois, vous avez une collection qui contient d’autres collections. Le HierarchicalDataTemplate classe est conçue pour être utilisée avec contrôles HeaderedItemsControl types pour afficher ces données. Dans l’exemple suivant, ListLeagueList est une liste de League objets. Chaque League objet a un Name et une collection de Division objets. Chaque Division a un Name et une collection de Team objets et chaque Team objet a un 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>

L’exemple montre que l’utilisation de HierarchicalDataTemplate, vous pouvez facilement afficher des données de liste qui contiennent d’autres listes. Voici une capture d’écran de l’exemple.

Capture d’écran : exemple de HierarchicalDataTemplate

Liaison de données
Rechercher des éléments générés par DataTemplate
Styles et modèles
Vue d’ensemble de la liaison de données
Vue d’ensemble des modèles et des Styles d’en-tête de colonne GridView

Afficher: