Un TemplateSelector est, comme son nom l'indique, un objet qui va vous permettre de chosir automatiquement entre plusieurs templates pour chaque item d'un itemControl (ItemControl, ListBox, ...).
Imaginons un cas simple :
Nous avons une liste de livre en vente. J'aimerais utiliser un template pour les livres traitant d'informatique et un autre pour tout les autres.
Voici tout d'abord notre class Livre :
public class Livre
{
private string titre;
...get/set...
private string sujet;
...get/set...
private double prix;
...get/set...
}
Créer un TemplateSelector
Ensuite crée une class dérivant de TempateSelector :
public class MyTemplateSelector : DataTemplateSelector
{
private DataTemplate templateLivreInfo;
...get/set... private DataTemplate templateLivreNotInfo;
...get/set...
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if(((Livre)item).Sujet == "Informatique")
return templateLivreInfo;
else
return templateLivreNotInfo;
}
}
Utiliser ce TemplateSelector dans le Xaml
Dans le Xaml il va tout d'abord vous falloir définir les deux templates, en tant que ressources :
<Window.Resources>
<DataTemplate x:Key="TemplateLivreInfo">
<Border BorderThickness="7" BorderBrush="Blue">
<StackPanel>
<Label Content="{Binding Path=Titre}"/>
<Label Content="{Binding Path=Sujet}"/>
<Label Content="{Binding Path=Prix}"/>
</StackPanel>
</Border>
</DataTemplate>
<DataTemplate x:Key="TemplateLivreNotInfo">
<Border BorderThickness="1" BorderBrush="Silver">
<StackPanel>
<Label Content="{Binding Path=Titre}"/>
<Label Content="{Binding Path=Sujet}"/>
<Label Content="{Binding Path=Description}"/>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>
Il s'agit bien sûr ici d'un cas d'école, dans une utilisation "normale" d'un TemplateSelector les multiples Templates seraient fort différent les uns des autres
Il suffit ensuite de signaler à notre ListBox d'utiliser myTemplateSelector :
<ListBox Name="ListBox1">
<ListBox.ItemTemplateSelector>
<MyApp:MyTemplateSelector
TemplateLivreInfo="{StaticResource TemplateLivreInfo}"
TemplateLivreNotInfo="{StaticResource TemplateLivreNotInfo}"/>
</ListBox.ItemTemplateSelector>
</ListBox>
Si nous peuplons notre ListBox, voici le résultat :
ListBox1.Items.Add(new Livre() { Titre = "WPF Pro", Sujet = "Informatique", Prix = 40 });
ListBox1.Items.Add(new Livre() { Titre = "Dune tome 14", Sujet = "SF", Prix = 7 });
ListBox1.Items.Add(new Livre() { Titre = "SimonBoigelot.com", Sujet = "Informatique", Prix = 12000 });
ListBox1.Items.Add(new Livre() { Titre = "La nuit des temps", Sujet = "SF", Prix = 7 });
Aller plus loin : Un TemplateSelector basé sur le type d'objets
Les TemplateSelector nous permette d'aller plus loin, et de choisir un template en fonction du type d'objet que représente notre item.
Si dans le cas vu ci-dessus nous avions dans notre ListBox non seulement des class Livre, mais aussi des class Voiture, il suffirait de changer le code de myTemplateSelector en celui-ci :
if (item is Livre)
return templateLivre;
if (item is Voiture)
return templateVoiture;