Dans cet article je vais vous présenter le fonctionnement des DataTemplate en WPF. Pour cela nous allons avoir besoin d’une petite application WPF de base. Voila l’arborescence du projet :

Nous pouvons voir que notre application est composée d’une MainWindow dans laquelle on trouve :

<Window x:Class="DataTemplateTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:View="clr-namespace:DataTemplateTest.View"
        Title="MainWindow" Height="350" Width="525">
        <View:MainView />
</Window>

Dans le code behind de cette vu nous instancions le view model :

public partial class MainWindow: Window
{
	public MainWindow()
	{
		DataContext = new MainViewModel();
		InitializeComponent();
	}
}

La MainView est composée simplement d’une ListView bindé sur la proprité Elements du ViewModel :

<UserControl x:Class="DataTemplateTest.View.MainView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:Model="clr-namespace:DataTemplateTest.Model" >
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type Model:Square}">
            <Rectangle Width="30" Height="30" Fill="LightGreen" Margin="5" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type Model:Circle}">
            <Border Width="30" Height="30" Background="LightBlue" CornerRadius="15" Margin="5" />
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ListView ItemsSource="{Binding Elements}" />
    </Grid>
</UserControl>

Dans le MainViewModel, on peuple simplement notre liste de Square :

public class MainViewModel
{
	public List Elements { get; set; }

	public MainViewModel()
	{
		Elements = new List();
		Elements.Add(new Square());
		Elements.Add(new Square());
		Elements.Add(new Square());
	}
}

Les classes Square et Circle sont des classes vide.

Maintenant que nous avons notre projet de base nous allons pouvoir commencer.

Sans DataTemplate

Dans un premier temps, exécutons simplement l’application sans définir de DataTemplate :

sans datatemplate

Nous pouvons voir que notre liste de trois éléments est bien affichée, mais que chaque élément n’est pas designé. Le Framework écrit simplement dans un TextBlock le résultat de l’appel à ToString sur les objets Square. Ce qui nous donne le nom complet de la classe.

DataTemplate simple

Nous allons créer notre premier DataTemplate pour les objets de type Square. Voila la vue MainView mise à jour :

<UserControl x:Class="DataTemplateTest.View.MainView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:Model="clr-namespace:DataTemplateTest.Model" >
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type Model:Square}">
            <Rectangle Width="30" Height="30" Fill="LightGreen" Margin="5" />
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ListView ItemsSource="{Binding Elements}" />
    </Grid>
</UserControl>

Et voila le résultat :

datatemplate simple

Nous pouvons bien voir que notre DataTemplate a été appliqué sur chaque élément de la liste.

Maintenant que ce passe t-il si nous avons des éléments de type Circle dans notre liste. Pour cela modifions le MainViewModel :

public class MainViewModel
{
	public List Elements { get; set; }

	public MainViewModel()
	{
		Elements = new List();
		Elements.Add(new Square());
		Elements.Add(new Square());
		Elements.Add(new Circle());
		Elements.Add(new Square());
		Elements.Add(new Circle());
	}
}

Voila le résultat :

résultat

Le comportement est tout à fait normal, en effet les objets de type Square sont bien templétés avec le DataTemplate précédent, les autres retrouvent l’affichage par défaut avec le ToString.

Modifions notre MainView pour avoir un second DataTemplate :

<UserControl x:Class="DataTemplateTest.View.MainView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:Model="clr-namespace:DataTemplateTest.Model" >
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type Model:Square}">
            <Rectangle Width="30" Height="30" Fill="LightGreen" Margin="5" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type Model:Circle}">
            <Border Width="30" Height="30" Background="LightBlue" CornerRadius="15" Margin="5" />
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ListView ItemsSource="{Binding Elements}" />
    </Grid>
</UserControl>

Voila la résultat :

résultat

Maintenant nous avons une liste d’objet composée de Square ou de Circle. Lors de l’affichage de ses éléments, le Framework choisit automatiquement le DataTemplate qui correspond à son type. La suite dans un prochain article ! 😉

Les DataTemplate WPF – Partie 2

Ne ratez plus aucunes actualités avec la newsletter mensuelle de SoftFluent