Windows 8 – Appliquer un template en fonction des items d’une liste
J’ai commencé à travailler sur Windows 8 autour d’une application utilisant des List/Grid/Gridview, en C#/XAML, et pour lesquelles je souhaitais personnaliser l’affichage de certains éléments identifiable. Par exemple, appliquer un style différent au dernier élément de la liste…
Pour l’exemple, nous allons créer une nouvelle application Windows Metro style de type Grid App (XAML) que j’ai nommé ici TemplateSelector :
Si on exécute l’application, voilà ce que l’on obtient :
Nous avons donc ici une liste d’éléments basés sur la Datasource exemple fournit par le template de projet. On voit ici que chaque élément utilise le même template : Standard250x250ItemTemplate.
<DataTemplate x:Key="Standard250x250ItemTemplate">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
Imaginons que l’on souhaite que l’élément 3 de notre premier groupe possède un cadre bleu, c’est à dire, appliquer un style différent que Standard250x250ItemTemplate utilisé.
Pour cela il existe une classe DataTemplateSelector : http://msdn.microsoft.com/fr-fr/library/system.windows.controls.datatemplateselector.aspx
Pour l’implémenter c’est simple, il suffit de créer une classe qui hérite de DataTemplateSelector et de surcharger la méthode SelectTemplateCore.
Ajoutons une classe à notre projet, que j’ai nommé ici MyTemplateSelector :
Voici le code de ma classe MyTemplateSelector :
public class MyTemplateSelector : DataTemplateSelector
{
protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore
(object item, Windows.UI.Xaml.DependencyObject container)
{
if (item is SampleDataItem)
{
SampleDataItem sample = item as SampleDataItem;
if (sample.UniqueId == "Group-1-Item-3")
return Application.Current.Resources["Special250x250ItemTemplate"] as DataTemplate;
else
return Application.Current.Resources["Standard250x250ItemTemplate"] as DataTemplate;
}
return base.SelectTemplateCore(item, container);
}
}
Ici, en fonction de l’Identifiant de l’item en cours, j’applique soit le template Standard250x250ItemTemplate, soit le template Special250x250ItemTemplate dans le cas ou l’Identifiant est "Group-1-Item-3" dans mon exemple et en me basant sur la Datasource du template de projet.
Il faut penser à créer le template Special250x250ItemTemplate, dans le fichier StandardStyles.xaml par exemple :
<DataTemplate x:Key="Special250x250ItemTemplate">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border BorderBrush="Blue" BorderThickness="12" Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
Il ne reste plus qu’à dire à notre GridView d’utiliser notre classe MyTemplateSelector. Pour cela, il suffit d’ajouter, dans le code XAML de la page, la ressource :
<common:MyTemplateSelector x:Key="TemplateSelector" />
Puis au niveau du GridView de spécifier la propriété ItemTemplateSelector :
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.Row="1"
Margin="0,-3,0,0"
Padding="116,0,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplateSelector="{StaticResource ResourceKey=TemplateSelector}"
SelectionMode="None"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
Attention, il faut également supprimer la propriété ItemTemplate du GridView sinon, il ne passera pas par notre classe MyTemplateSelector.
Remarque, on peut aussi appliquer ces valeurs au niveau du code behind C# :
this.itemGridView.ItemTemplate = null; this.itemGridView.ItemTemplateSelector = new MyTemplateSelector();
Si on exécute désormais notre application, voici ce que l’on obtient :
Nous savons désormais comment personnaliser nos éléments dans une liste. Les possibilités sont assez nombreuses. Dans mon cas, j’ai utilisé ce principe pour ajouter un élément en fin de ma liste qui me permet de faire de la pagination.
Par défaut ma liste charge 40 éléments, le dernier élément est un + qui lorsque l’on clique dessus, charge les 40 éléments suivants :
Rock’n'Roll.





Article sympa mais j’ai une question:
Est-ce que le rendu final est fait par un moteur WEB ou autre? Suggères-tu utiliser XAML au lieu de HTML/CSS/JavaScript pour le développement d’application Windows 8 style metro, et si oui, pourquoi?
Salut Ilyas,
En réalité Microsoft à mis en place un nouveau runtime WinRT :
Le Windows RunTime associe le code fonctionnel de celui réservé à l’affichage et la présentation. Par exemple, un développeur peut utiliser le C# puis l’associer au XAML. De même, il peut se tourner vers le JavaScript associé aux HTML5 et CSS. Derrière WinRT utilise soit l’interpreteur XAML, soit le moteur de rendu IE10.
Je n’est pas réellement de préférence quand au choix C#/XAML ou HTML5/JS. Je ne me suis pas encore penché assez sur HTML5/JS pour avoir des points de comparaisons, notamment est-ce que l’un est plus performant que l’autre… Je dirai que ça dépend avant tout de ton background en développement. Microsoft à surtout, selon moi, mis à disposition HTML5/JS pour attirer plus de monde et surtout les développeurs WEB à développer des applications pour Windows 8.
A+
merci pour la réponse