• Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Mis à jour le 29/04/2014

Le toolkit Windows Phone

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Bien que déjà bien fournis, les contrôles Windows Phone ne font pas tout. Nous avons déjà vu des bibliothèques tierces, comme le MVVM Light toolkit qui permet de faire en sorte que son application respecte plus facilement le patron de conception MVVM. Nous avons également utilisé une bibliothèque qui permet d’utiliser le binding avec la barre d’application.

Il existe d’autres bibliothèques bien pratiques contenant des contrôles évolués qui vont nous permettre d’enrichir nos applications et d’offrir avec le moindre effort une expérience utilisateur des plus sympathiques.

En plus, il y en a qui sont gratuites, alors pourquoi s'en priver ?

Présentation et installation du toolkit Windows Phone

La bibliothèque la plus connue est sans nul doute le Toolkit pour Windows Phone. Il s’agit d’un projet très suivi qui contient beaucoup de contrôles pour Windows Phone. Historiquement, ce toolkit proposait déjà toute une gamme de contrôles supplémentaires pour Silverlight. Depuis la sortie de Silverlight pour Windows Phone 7.X, c’est tout naturellement qu’une bibliothèque parallèle, dédiée à Windows Phone, a vu le jour. Et aujourd’hui, avec l’arrivée de Windows Phone 8, il en existe une version pour lui.

Comme beaucoup de bibliothèques, elle est open-source, utilisable dans beaucoup de situations mais pas toujours exempte de bug. Il y a tout une communauté qui travaille sur ces projets et qui continue régulièrement à l’améliorer. Cette bibliothèque est téléchargeable sur http://phone.codeplex.com/. À l’heure où j’écris ces lignes, nous pouvons télécharger la version de novembre 2012. Vous pouvez télécharger les binaires sur le site ou encore une fois utiliser NuGet qui facilite la récupération de bibliothèques tierces (voir la figure suivante).

Utilisation de NuGet pour télécharger le Windows Phone Toolkit
Utilisation de NuGet pour télécharger le Windows Phone Toolkit

NuGet nous a donc ajouté la référence à l’assembly Microsoft.Phone.Controls.Toolkit.dll.
Je ne vais pas vous présenter tous les contrôles tellement il y en a. Je vous encourage à télécharger les sources ainsi que l’application exemple et de la tester pour voir ce qu’elle renferme. Mais voyons-en quand même quelques uns :) .

PerformanceProgressBar

Je souhaitais vous parler de la barre de progression PerformanceProgressBar car c’est un très bon exemple de la puissance du toolkit. La barre de progression qui était originellement présente avec le SDK pour Windows Phone 7.X posait des problèmes de performances. Celle du toolkit profite de toutes les optimisations possibles et gère également beaucoup mieux les threads. Nous parlerons des Threads dans un prochain chapitre.
Toujours est-il que pour Windows Phone 7, c’était cette barre de progression qui était recommandée un peu partout sur le net et par Microsoft (pour la petite histoire, c’est un développeur de Microsoft qui a créé cette nouvelle barre de progression).
Elle a depuis été intégrée dans le SDK de Windows Phone 8 afin de tirer parti de ces améliorations. Je vais vous montrer ici comment s’en servir dans une application pour Windows Phone 7 et après je rebasculerai sur Windows Phone 8.
Créez donc une application qui cible le SDK 7.1. Ensuite, pour utiliser la barre, rien de plus simple, il vous suffit d’importer l’espace de nom du toolkit :

xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

et de la déclarer où vous souhaitez qu’elle s’affiche :

<toolkit:PerformanceProgressBar IsIndeterminate="True" />

La barre de progression n’en est en fait pas vraiment une, du moins pas dans le sens où on les connait : en l'occurrence, elle n’affiche pas un pourcentage de progression sur une tâche dont on connait la durée totale. Il s’agit plutôt d’une petite animation qui montre qu’il se passe un chargement, sans que l’on sache vraiment où nous en sommes.
Vous pouvez voir son fonctionnement dans le designer de Visual Studio, la barre s’anime et affiche des points, comme indiqué sur la figure suivante.

Animation de la barre dans le designer
Animation de la barre dans le designer

La barre est visible dans un état où la progression est indéterminée. C’est pour cela que la propriété s’appelle IsIndeterminate et permet d’indiquer si elle est visible ou non. Passez la à False pour la voir se masquer.
En général, ce que vous ferez, c’est dans un premier temps mettre la propriété à vrai, démarrer quelque chose de long de manière asynchrone, par exemple un téléchargement, et une fois terminé vous passerez la propriété à faux. Nous pouvons simuler ce fonctionnement avec un DispatcherTimer, il s’agit d’une classe qui va nous permettre d’appeler une méthode à une fréquence déterminée. Nous en reparlerons plus tard, mais par exemple ici, mon Timer va me permettre de masquer ma barre de progression au bout de 7 secondes :

public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
{
    private DispatcherTimer timer;

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private bool chargementEnCours;
    public bool ChargementEnCours
    {
        get { return chargementEnCours; }
        set
        {
            chargementEnCours = value;
            NotifyPropertyChanged("ChargementEnCours");
        }
    }

    public MainPage()
    {
        InitializeComponent();
        DataContext = this;

        ChargementEnCours = true;
        timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(7) };
        timer.Tick += timer_Tick;
        timer.Start();
    }

    private void timer_Tick(object sender, EventArgs e)
    {
        ChargementEnCours = false;
        timer.Stop();
    }
}

N’oubliez pas d’inclure l’espace de noms suivant pour pouvoir utiliser le DispatcherTimer :

using System.Windows.Threading;

Et dans le XAML, nous aurons le binding suivant :

<toolkit:PerformanceProgressBar IsIndeterminate="{Binding ChargementEnCours}" />

Remarquez qu’il est possible de changer facilement la couleur des points grâce à la propriété Foreground.
À noter que son utilisation est globalement la même avec le SDK pour Windows Phone 8, on utilisera cependant le contrôle ProgressBar directement. Sachant que pour reproduire exactement le même fonctionnement, il faudra masquer la barre de progression une fois son statut indéterminé activé :

<ProgressBar IsIndeterminate="{Binding ChargementEnCours}" Visibility="{Binding ChargementEnCours,Converter={StaticResource VisibilityConverter}}" />

Usez et abusez de cette barre dès qu'il faut avertir l'utilisateur que quelque chose de potentiellement long se passe.

ListPicker

Le contrôle ListPicker est une espèce de ListBox simplifiée. Il est l’équivalent d’un contrôle connu mais qui manquait dans les contrôles Windows Phone, la ComboBox.
Ce ListPicker permet de choisir un élément parmi une liste d’éléments relativement restreinte. Puissant grâce à son système de modèle, il permet de présenter l’information de manière évoluée. Voyons à présent comment il fonctionne.

La manière la plus simple de l’utiliser est de le lier à une liste de chaines de caractères :

<toolkit:ListPicker ItemsSource="{Binding Langues}" />

Avec dans le code-behind :

public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private bool NotifyPropertyChanged<T>(ref T variable, T valeur, [CallerMemberName] string nomPropriete = null)
    {
        if (object.Equals(variable, valeur)) return false;

        variable = valeur;
        NotifyPropertyChanged(nomPropriete);
        return true;
    }

    private List<string> langues;
    public List<string> Langues
    {
        get { return langues; }
        set { NotifyPropertyChanged(ref langues, value); }
    }

    public MainPage()
    {
        InitializeComponent();
        DataContext = this;

        Langues = new List<string> { "Français", "English", "Deutsch", "Español" };
    }
}

Nous obtenons la figure suivante.

Le ListPicker plié
Le ListPicker plié

Et lorsque nous cliquons dessus, il se déplie pour nous permettre de sélectionner un élément, comme vous pouvez le voir à la figure suivante.

Le ListPicker déplié nous permet de sélectionner un élément
Le ListPicker déplié nous permet de sélectionner un élément

Pour la sélection, ce contrôle fonctionne comme la ListBox. Nous pouvons présélectionner un élément et être informés de quel élément est sélectionné. Donnons un nom à notre ListPicker et abonnons-nous à l’événement SelectionChanged :

<toolkit:ListPicker ItemsSource="{Binding Langues}" x:Name="Liste" SelectionChanged="Liste_SelectionChanged" />

Et dans le code-behind :

public MainPage()
{
    InitializeComponent();
    DataContext = this;

    Langues = new List<string> { "Français", "English", "Deutsch", "Español" };
    Liste.SelectedIndex = 2;
}

private void Liste_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (Liste.SelectedItem != null)
    {
        MessageBox.Show(Liste.SelectedItem.ToString());
    }
}

Nous obtenons la figure suivante.

Sélection d'un élement du ListPicker
Sélection d'un élement du ListPicker

Dans cet exemple, lorsqu’on clique dans le ListPicker, la liste se déroule pour nous montrer tous les éléments de la liste. Il existe un autre mode de sélection : le mode plein écran. Il suffit de changer dans le XAML :

<toolkit:ListPicker ItemsSource="{Binding Langues}" Header="Langue :" FullModeHeader="Choisir une langue :" ExpansionMode="FullScreenOnly" />

Remarquons la propriété ExpansionMode qui permet de forcer la sélection dans un mode plein écran. Nous pouvons également donner un titre à notre ListPicker grâce à la propriété Header, titre qui peut être différent si nous sommes en mode plein écran (voir la figure suivante).

Sélection en mode plein écran
Sélection en mode plein écran

Comme je l’ai déjà dit, il est possible de fournir un modèle pour chaque élément et ceci grâce aux propriétés ItemTemplate et FullModeItemTemplate. Par exemple, changeons le type de notre liste d’éléments :

private List<Element> langues;
public List<Element> Langues
{
    get { return langues; }
    set { NotifyPropertyChanged(ref langues, value); }
}

Avec la classe Element suivante :

public class Element
{
    public string Langue { get; set; }
    public string Code { get; set; }
    public Uri Url { get; set; }
}

Que nous alimentons ainsi :

Langues = new List<Element> 
{
    new Element { Code = "FR", Langue = "Français", Url = new Uri("/Assets/Images/france.png", UriKind.Relative)},
    new Element { Code = "US", Langue = "English", Url = new Uri("/Assets/Images/usa.png", UriKind.Relative)},
    new Element { Code = "DE", Langue = "Deutsch", Url = new Uri("/Assets/Images/allemagne.png", UriKind.Relative)},
    new Element { Code = "ES", Langue = "Español", Url = new Uri("/Assets/Images/espagne.png", UriKind.Relative)},
};

sachant que les images correspondant aux drapeaux de chaque langue sont inclues dans le répertoire Images, sous le répertoire Assets, dans notre solution (en ayant changé l’action de génération à « Contenu »).
Je peux alors modifier le XAML pour avoir :

<toolkit:ListPicker ItemsSource="{Binding Langues}" Header="Langue :" FullModeHeader="Choisir une langue :" ExpansionMode="FullScreenOnly">
    <toolkit:ListPicker.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Border BorderThickness="2" BorderBrush="Beige" Background="Azure">
                    <TextBlock Text="{Binding Code}" Foreground="Blue" />
                </Border>
                <TextBlock Margin="20 0 0 0" Text="{Binding Langue}" />
            </StackPanel>
        </DataTemplate>
    </toolkit:ListPicker.ItemTemplate>
    <toolkit:ListPicker.FullModeItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Margin="20 0 0 0" Text="{Binding Langue}" Style="{StaticResource PhoneTextTitle1Style}" />
                <Image Source="{Binding Url}" />
            </StackPanel>
        </DataTemplate>
    </toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>

Ce qui donnera la page présentée dans la figure suivante.

Utilisation des templates du ListPicker
Utilisation des templates du ListPicker

Ainsi que dans le mode de sélection plein écran (voir la figure suivante).

Le template plein écran
Le template plein écran

Ce ListPicker est définitivement bien pratique lorsqu’il s’agit de permettre de choisir entre plusieurs éléments, dans une liste relativement courte. De plus, ses différents modes de sélection offrent une touche supplémentaire à vos applications.

WrapPanel

Au même titre que le StackPanel, le WrapPanel du toolkit est un conteneur de contrôles qui a une fonctionnalité intéressante. Il est capable de passer automatiquement à la ligne ou à la colonne suivante si les contrôles présents à l’intérieur dépassent du conteneur.
Prenons par exemple le XAML suivant et réutilisons les images de l’exemple précédent :

<StackPanel Orientation="Horizontal">
    <Image Source="/Assets/Images/france.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/usa.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/allemagne.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/espagne.png" Width="150" Height="150" Margin="10" />
</StackPanel>

Vous pouvez voir le résultat à la figure suivante.

L'écran n'est pas assez large pour voir les 4 images avec un StackPanel
L'écran n'est pas assez large pour voir les 4 images avec un StackPanel

Oh diantre, c’est plutôt embêtant, on ne voit que 3 images sur les 4 promises… ! Eh oui, il n’y a pas assez de place sur l’écran et la troisième image dépasse du conteneur.
Changeons maintenant juste le conteneur et remplaçons-le par un WrapPanel :

<toolkit:WrapPanel>
    <Image Source="/Assets/Images/france.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/usa.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/allemagne.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/espagne.png" Width="150" Height="150" Margin="10" />
</toolkit:WrapPanel>

Nous aurons la figure suivante.

Le WrapPanel passe automatiquement à la ligne s'il n'y a pas assez de place
Le WrapPanel passe automatiquement à la ligne s'il n'y a pas assez de place

Et ô miracle, toutes les images sont désormais présentes.
Vous avez compris que c’est le WrapPanel qui a fait automatiquement passer les images à la ligne afin qu’elles apparaissent à l’écran. Son but : faire en sorte que tout tienne à l’écran !

Cela fonctionne également en orientation verticale :

<toolkit:WrapPanel Orientation="Vertical">
    <Image Source="/Assets/Images/france.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/usa.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/allemagne.png" Width="150" Height="150" Margin="10" />
    <Image Source="/Assets/Images/espagne.png" Width="150" Height="150" Margin="10" />
</toolkit:WrapPanel>

Ce qui donnera la figure suivante.

Le WrapPanel en orientation verticale
Le WrapPanel en orientation verticale

Le WrapPanel est très pratique combiné avec une ListBox ou même un ListPicker. Dans l’exemple fourni avec le toolkit, on peut le voir utilisé à l’intérieur d’un Pivot.
N’hésitez pas à vous servir de ce conteneur dès que vous aurez besoin d’afficher une liste d’éléments dont vous ne maitrisez pas forcément le nombre.

Et je ne sais pas si vous vous souvenez, mais je vous ai fait une capture d’écran précédemment lorsque je parlais des différentes résolutions des Windows Phone où j’avais ajouté plein de boutons les uns à la suite des autres. Ils étaient dans un WrapPanel et s’alignaient alors automatiquement, les uns à la suite des autres.

LongListSelector

Avant de s’arrêter sur l'exploration des contrôles de ce toolkit, regardons encore le contrôle LongListSelector. Bien que j’aie choisi de présenter ce contrôle dans le chapitre sur le toolkit Windows Phone, le LongListSelector existe dans le SDK de Windows Phone 8. Eh oui, c’est comme pour le ProgressBar, voici un contrôle qui n’existait pas avec le SDK pour Windows Phone 7, qui a été créé et approuvé par la communauté, et qui trouve naturellement sa place dans le SDK pour Windows Phone 8.
Il permet d’améliorer encore la ListBox, notamment quand celle-ci contient énormément de valeurs. Grâce à lui, nous pouvons regrouper des valeurs afin que chacune soit plus facilement accessible. Ce type de contrôle est utilisé par exemple avec les contacts dans notre téléphone, lorsque nous commençons à en avoir beaucoup.

La figure suivante montre le résultat que nous allons obtenir à la fin de ce chapitre, les prénoms sont regroupés suivant leur première lettre.

Les prénoms sont regroupés avec le LongListSelector
Les prénoms sont regroupés avec le LongListSelector

Et lors d’un clic sur un groupe, nous obtenons la liste des groupes où nous pouvons sélectionner un élément pour l’atteindre plus rapidement (voir la figure suivante).

La liste des groupes du LongListSelector
La liste des groupes du LongListSelector

Pour démontrer ce fonctionnement, prenons par exemple la liste des 50 prénoms féminins de bébé les plus donnés en 2012 :

List<string> liste = new List<string> { "Emma", "Manon", "Chloé", "Camille", "Léa", "Lola", "Louise", "Zoé", "Jade", "Clara", "Lena", "Eva", "Anaïs", "Clémence", "Lilou", "Inès", "Juliette", "Maëlys", "Lucie", "Alice", "Sarah", "Romane", "Jeanne", "Margaux", "Mathilde", "Elise", "Léonie", "Louna", "Lisa", "Ambre", "Anna", "Justine", "Lily", "Pauline", "Laura", "Charlotte", "Rose", "Julia", "Noemie", "Eloïse", "Lou", "Alicia", "Eléna", "Margot", "Elsa", "Louane", "Elisa", "Nina", "Marie", "Agathe" };

Le principe est de faire une liste de liste groupée d’éléments grâce à l’opérateur Linq join :

IEnumerable<List<string>> prenoms = from prenom in liste
                group prenom by prenom[0].ToString() into p
                orderby p.Key
                select new List<string>(p);

ListePrenoms = prenoms.ToList();

Ici, j’ai choisi de regrouper les prénoms en fonction de leur première lettre, mais on pourrait très bien imaginer une liste de villes regroupées en fonction de leur pays d’appartenance… ou quoi que ce soit d’autre... Pour utiliser le binding avec ce LongListSelector, nous devons avoir la propriété suivante :

private List<List<string>> listePrenoms;
public List<List<string>> ListePrenoms
{
    get { return listePrenoms; }
    set { NotifyPropertyChanged(ref listePrenoms, value); }
}

Coté XAML c’est un peu plus compliqué. Nous avons premièrement besoin de lier la propriété ItemsSource du LongListSelector à notre propriété ListePrenoms :

<phone:LongListSelector ItemsSource="{Binding ListePrenoms}">
</phone:LongListSelector>

Il faut maintenant indiquer plusieurs choses, premièrement que le contrôle est en mode liste, qu’il accepte de grouper les éléments et qu’il a la possibilité d’obtenir la liste des groupes. Cela se fait grâce à ces propriétés :

<phone:LongListSelector ItemsSource="{Binding ListePrenoms}" LayoutMode="List" IsGroupingEnabled="True" JumpListStyle="{StaticResource LongListSelectorJumpListStyle}">
</phone:LongListSelector>

Notez la présence du style LongListSelectorJumpListStyle qui est à définir.

Ensuite, il y a plusieurs modèles à créer. Premièrement le modèle des éléments, c’est-à-dire des prénoms. Il s’agit du modèle ItemTemplate. Ici, un simple TextBlock suffit :

<phone:LongListSelector ItemsSource="{Binding ListePrenoms}">
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" FontSize="26"  Margin="12,-12,12,6"/>
        </DataTemplate>
    </phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>

Ensuite, nous rajoutons un modèle pour les groupes visibles dans la liste. Il s’agit du modèle GroupHeaderTemplate. Ici nous devons afficher la première lettre du groupe, entourée dans un rectangle dont le bord correspond à la couleur d’accentuation :

<phone:LongListSelector ItemsSource="{Binding ListePrenoms}">
    …
    <phone:LongListSelector.GroupHeaderTemplate>
        <DataTemplate>
            <Border BorderBrush="{Binding Converter={StaticResource BackgroundConverter}}" BorderThickness="2" Width="60" Margin="10" HorizontalAlignment="Left">
                <TextBlock Text="{Binding Converter={StaticResource ListConverter}}" FontSize="40" Foreground="{Binding Converter={StaticResource BackgroundConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </DataTemplate>
    </phone:LongListSelector.GroupHeaderTemplate>
</phone:LongListSelector>

Remarquez qu’étant donné que la liaison se fait sur la List<string>, j’utilise un converter pour n’afficher que la première lettre. Ce converter est défini classiquement en ressource :

<converter:ListConverter x:Key="ListConverter" />

Avec l’import d’espace de nom adéquat :

xmlns:converter="clr-namespace:DemoToolkit"

Le converter quant à lui est très simple, il prend simplement la première lettre du premier élément de la liste :

public class ListConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        List<string> liste = (List<string>)value;
        if (liste == null || liste.Count == 0)
            return string.Empty;
        return liste[0][0];
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Notez l’utilisation du converter BackgroundConverter qui permet d’obtenir la couleur d’accentuation. Ce converter est défini dans les ressources et est un converter système. Déclarons-le ainsi que son petit frère, le ForegroundConverter, qui permet d’avoir la couleur du thème :

<phone:JumpListItemBackgroundConverter x:Key="BackgroundConverter"/>
<phone:JumpListItemForegroundConverter x:Key="ForegroundConverter"/>

Enfin, il reste le style de la liste des groupes, qui apparaît lorsqu’on clique sur un groupe. Il s’agit du style LongListSelectorJumpListStyle que nous avons précédemment vu, qui est également à mettre en ressources :

<Style x:Key="LongListSelectorJumpListStyle" TargetType="phone:LongListSelector">
    <Setter Property="GridCellSize"  Value="113,113"/>
    <Setter Property="LayoutMode" Value="Grid" />
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <Border Background="{Binding Converter={StaticResource BackgroundConverter}}"
                                Width="113" Height="113" Margin="6" >
                    <TextBlock Text="{Binding Converter={StaticResource ListConverter}}"
                                        FontFamily="{StaticResource PhoneFontFamilySemiBold}"
                                        FontSize="48" Padding="6"
                                        Foreground="{Binding Converter={StaticResource ForegroundConverter}}"
                                        VerticalAlignment="Center"/>
                </Border>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

Ici, le principe est le même, on utilise le converter pour afficher la première lettre. Elle sera dans un cadre au fond du thème d’accentuation.
Ce qui nous donne le code XAML complet suivant :

<phone:LongListSelector ItemsSource="{Binding ListePrenoms}" LayoutMode="List" IsGroupingEnabled="True" JumpListStyle="{StaticResource LongListSelectorJumpListStyle}">
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" FontSize="26" Margin="12,-12,12,6"/>
        </DataTemplate>
    </phone:LongListSelector.ItemTemplate>
    <phone:LongListSelector.GroupHeaderTemplate>
        <DataTemplate>
            <Border BorderBrush="{Binding Converter={StaticResource BackgroundConverter}}" BorderThickness="2" Width="60" Margin="10" HorizontalAlignment="Left">
                <TextBlock Text="{Binding Converter={StaticResource ListConverter}}" FontSize="40" Foreground="{Binding Converter={StaticResource BackgroundConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </DataTemplate>
    </phone:LongListSelector.GroupHeaderTemplate>
</phone:LongListSelector>

C’est vrai, je le reconnais, il fait un peu peur ! :p Nous allons le simplifier en mettant nos DataTemplate en ressource. Il suffit de les déclarer ainsi :

<phone:PhoneApplicationPage.Resources>
    …

    <DataTemplate x:Key="ModeleElement">
        <TextBlock Text="{Binding}" FontSize="26" Margin="12,-12,12,6"/>
    </DataTemplate>
    <DataTemplate x:Key="ModeleGroupe">
        <Border BorderBrush="{Binding Converter={StaticResource BackgroundConverter}}" BorderThickness="2" Width="60" Margin="10" HorizontalAlignment="Left">
            <TextBlock Text="{Binding Converter={StaticResource ListConverter}}" FontSize="40" Foreground="{Binding Converter={StaticResource BackgroundConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Border>
    </DataTemplate>

    …
</phone:PhoneApplicationPage.Resources>

N’oubliez pas qu’il faut impérativement une clé à un élément présent dans les ressources. Nous pourrons alors simplifier l’écriture du contrôle ainsi :

<phone:LongListSelector ItemsSource="{Binding ListePrenoms}" LayoutMode="List" IsGroupingEnabled="True" JumpListStyle="{StaticResource LongListSelectorJumpListStyle}" ItemTemplate="{StaticResource ModeleElement}" GroupHeaderTemplate="{StaticResource ModeleGroupe}" />

Ce qui est beaucoup plus court et qui permet également de potentiellement réutiliser les modèles…
Je n’ai pas décrit toutes les possibilités de ce contrôle. Sachez qu’il est possible de définir un modèle pour réaliser un entête de liste et un pied de liste. Elle peut également se consulter « à plat », en utilisant la propriété :

IsFlatList="True"

Ce contrôle est plutôt pratique. J’ai choisi d’utiliser un converter pour afficher le titre d’un groupe en utilisant la première lettre des prénoms. Ce qui se fait aussi c’est de construire un objet directement liable possédant une propriété Titre et une liste d’éléments, en général quelque chose comme ça :

public class Group<T> : List<T>
{
    public Group(string nom, IEnumerable<T> elements)
        : base(elements)
    {
        this.Titre = nom;
    }
 
    public string Titre { get;  set;  }
}

Avantages & limites du toolkit

Bon, je m’arrête là pour cette petite présentation limitée du toolkit. Nous aurons l’occasion de revoir des choses du toolkit de temps en temps dans la suite du cours.
Il rajoute des fonctionnalités très intéressantes qui manquaient aux développeurs souhaitant réaliser des applications d’envergure avec Windows Phone. Il ne s’agit bien sûr pas de contrôles officiels, mais ils sont largement reconnus par la communauté. Ce toolkit, notamment dans sa version XAML, sert parfois également de bac à sable pour les développeurs Microsoft afin de fournir des contrôles sans qu’ils ne fassent partie intégrante de la bibliothèque de contrôles officielle.

Il y a tout une communauté active et dynamique qui pousse afin que ces contrôles aient le moins de bug possible, cependant nous ne sommes pas à l’abri d’un comportement indésirable…

Les autres toolkits

Le toolkit pour Windows Phone n’est pas la seule bibliothèque de contrôles du marché. Il en existe d’autres.
Citons par l’exemple la bibliothèque Coding4Fun http://coding4fun.codeplex.com/ qui est gratuite et qui fournit des contrôles plutôt sympathiques. Notons par exemple un contrôle qui permet de sélectionner une date ou une heure (voir la figure suivante).

Le choix d'une durée grâce au toolkit Coding4Fun
Le choix d'une durée grâce au toolkit Coding4Fun

D’autres sont payants et développés par des sociétés tierces, citons par exemple les contrôles de la société Telerik ou encore de Syncfusion. Ils fournissent des contrôles qui nous simplifient la tâche et qui permettent de gagner du temps dans nos développements. N’hésitez pas à y jeter un coup d’œil, c’est souvent plus intéressant d’acheter un contrôle déjà tout fait que de passer du temps (beaucoup de temps !) à le réaliser.

  • Le toolkit pour Windows Phone est une bibliothèque de contrôles fournie gratuitement qui permet d’enrichir vos applications avec des contrôles très pratiques.

  • Il y a beaucoup de bibliothèques qui existent et qui proposent des contrôles complets, s’adaptant à beaucoup de situation. Certaines sont gratuites, d’autres payantes. N’hésitez pas à les consulter, il y a souvent de bonnes surprises.

Exemple de certificat de réussite
Exemple de certificat de réussite