nRoute – RelayConverters – Création de Converters locaux à une vue

2 minutes read

Lorsque l’on développe des applications Silverlight ou WPF il arrive que l’on ait besoin de créer des converters qui n’auront d’utilité que dans une vue particulière. On doit alors créer une classe et donc généralement un fichier supplémentaire qui n’aura aucune utilité pour le reste de l’application ce qui, sur de gros projets, peux rapidement devenir assez volumineux.

Suite à l’article précédent concernant les RelayCommands, on va voir comment nRoute propose de résoudre le problème ci-dessus en utilisant les RelayConverters.

Les RelayConverters suivent le même principe que les RelayCommands avec une déclaration d’un relay en ressource et une initialisation grâce à un behavior. Mais assez parlé, place au code.

On va utiliser une version légèrement modifié des ViewModels de l’article sur le RelayCommands.

public class Book
{
    public long ID { get; set; }
    public string Author { get; set; }
    public string Title { get; set; }
    public int Likes { get; set; }
}
public class MainPageViewModel : ViewModelBase
{
    private readonly IEnumerable<Book> _books;

    public MainPageViewModel()
    {
        var authors = new[] {
            "Terry Pratchett",
            "Molière",
            "Shakespeare",
            "Frank Herbert",
            "Isaac Asimov"
        };

        var list = new List<Book>();
        for (int i = 0; i < 10; ++i)
            list.Add(new Book
            {
                ID = i,
                Author = authors[i % authors.Length],
                Title = "Title " + i,
                Likes = i * i * 10
            });

        _books = list;
    }

    public IEnumerable<Book> Books
    {
        get { return _books; }
    }
}

On veux afficher dans la vue principale la liste des livres d’une manière un peu différente en fonctions du nombre de Likes sur le livre.

Si on a plus de 100 Likes on va dire que beaucoup de gens aiment ce livre, en dessous de 100 on dira que peu de gens l’aiment et à 0 on précisera que ce livre n’est aimé par personne.

Les converters permettent de faire celà, cependant créer une classe juste pour ça ne représente aucun intérêt particulier aussi on va utiliser un RelayConverter. Voici comment on va déclarer notre Xaml :

<UserControl x:Class="nRoute_RelayConverters.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:n="http://nRoute/schemas/2010/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.Resources>
        <n:ValueConverterRelay x:Name="BookValueConverterRelay" />
    </UserControl.Resources>

    <i:Interaction.Behaviors>
        <n:BridgeViewModelBehavior />
        <n:BridgeValueConverterBehavior ValueConverterRelay="{StaticResource BookValueConverterRelay}" />
    </i:Interaction.Behaviors>

    <StackPanel x:Name="LayoutRoot" Background="White">
        <ItemsControl ItemsSource="{Binding Books}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
                        <TextBlock Text="{Binding Converter={StaticResource BookValueConverterRelay}}" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</UserControl>

Comme on peux le constater, la façon de procéder ici est quasi identique qu’avec les RelayCommand. A la différence près que pour l’instant on a juste déclaré un converter et pas la fonction de conversion en elle même. Pour celà direction le code-behind de la vue.

On va premièrement rajouter un using :

using nRoute.Components;

Ce using permet d’accèder aux méthodes d’extensions de nRoute, l’une d’entre elle, SetRelayConverter, permet de définir la fonction de conversion du RelayConverter et voici comment celà s’utilise :

[MapView(typeof(ViewModels.MainPageViewModel))]
public partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();

        this.SetRelayConverter<Book, string>("BookValueConverterRelay", BookValueConverterIn);
    }

    private static string BookValueConverterIn(Book book)
    {
        if (book.Likes > 100)
            return string.Format("A lot of people likes {0} by {1} !", book.Title, book.Author);
        else if (book.Likes > 1)
            return string.Format("Not a lot of people likes {0} by {1}.", book.Title, book.Author);
        return string.Format("No one likes {0} by {1}...", book.Title, book.Author);
    }
}

SetRelayConverter est une fonction générique prenant paramètre de type les types d’entrée et de retour du converter et en paramètre le nom du RelayConverter défini dans la vue suivi de la méthode de conversion à utilisée.

Verdict, un peu de code-behind pour un traitement purement visuel et une classe économisée et oui on fait toujours du MVVM.

Comme d’habitude, les sources de l’articles sont disponibles sur mon skydrive.

Updated:

Leave a Comment