posté @ Wednesday, October 29, 2008 3:22 AM

Un des éléments les plus puissants du Binding en WPF n'a pas été implémenté dans Silverlight 2, au grand malheur de beaucoup de développeurs d'application RIA : la notion de TemplateSelector.

Pour rappel, sur le ContentControl de WPF, on trouve 3 DependencyProperties fondamentales pour le binding :

  • Content : Il s'agit de l'objet à afficher / éditer
  • ContentTemplate : Il s'agit du template à utiliser pour afficher / éditer l'objet
  • ContentTemplateSelector : Il s'agit d'une alternative utilisable à la propriété ContentTemplate, permettant de définir le template à utiliser At Runtime (en dérivant de DataTemplateSelector)

Par défaut, si l'on ne spécifie ni ContentTemplate ni ContentTemplateSelector, WPF utilise un DataTemplateSelector se basant sur le type du "Content" pour définir le DataTemplate à sélectionner (en cherchant des DataTemplate avec une propriété DataType qui match).

C'est très utile pour afficher des listes de données hétérogènes par exemple.

En Silverlight, nous n'avons pas ce mécanisme à notre disposition. Nous devons donc passer outre.

Une solution déjà éprouvée (et prouvée...) chez un de mes clients me semble élégante et ouvre même sur d'autres possibilités tout à fait utiles : Il s'agit d'un Converter capable de sélectionner une valeur dans un ResourceDictionnary en fonction de la valeur fournie par une expression de Binding. Jugez par vous même du résultat obtenu côté makup :

<UserControl.Resources>
    <sleData:ResourceSelector x:Key="myTemplateSelector">
        <ResourceDictionary>
            <DataTemplate x:Key="TypeA">
                <TextBlock Text="This is the template for Type A" Foreground="Blue" />
            </DataTemplate>
            <DataTemplate x:Key="TypeB">
                <TextBlock Text="This is the template for Type B" Foreground="Red" />
            </DataTemplate>
        </ResourceDictionary>
    </sleData:ResourceSelector>
    <DataTemplate x:Key="myItemTemplate">
        <ContentControl Content="{Binding}"
                ContentTemplate="{Binding Converter={StaticResource myTemplateSelector}}"/>
    </DataTemplate>
</UserControl.Resources>
<ItemsControl x:Name="dynTplItemsControl" ItemTemplate="{StaticResource myItemTemplate}"
ItemsSource="{Binding myHeterogeneCollection}" />

Dans les faits, le ResourceSelector a plusieurs modes de fonctionnement. En fonction du type de la valeur bindée, on va utiliser soit la valeur elle même (si il s'agit d'un string, int, long...), soit la propriété ResourceKey de la valeur (si elle implémente IProvideResourceKey), soit le type de cette valeur (en utilisant d'abord l'AssemblyQualifiedName, puis le FullName et enfin le Name de ce type pour localiser la ressource demandée).

Vous pouvez retrouver ce ResourceSelector (et pleins d'autres trucs super intéressants) dans le projet Silverlight Extensions disponible sur CodePlex. Le ResourceSelector se trouve dans le namespace SLExtensions.Data.

(Attention, le ResourceSelector n'est pas encore disponible dans la Release, et pour cause, il a été check-in il y'a quelques minutes... Il faut donc aller dans l'onglet "Source Code" du projet et télécharger la dernière version)

Mots clés Technorati : ,,,

Commentaires :

# re: [Silverlight] Une solution pour remplacer ITemplateSelector
Ecrit par pierlag le 10/31/2008 5:19 PM
ResourceSelector est dispo dans l'Alpha 2 sur codeplex
http://www.slextensions.net

Ecrire un commentaire :

Titre :*
Nom *
Email
Url
Commentaire : *  


Please add 8 and 1 and type the answer here: