Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Thomas Lebrun

Tout sur WPF, LINQ, C# et .NET en général !

Actualités

[WPF] Comment et pourquoi créer sa propre "MarkupExtension" ?

Lorsque l'on manipule du XAML, il n'est pas rare de rencontrer des choses comme ceci:

{Binding ...}, {StaticResource ...}, and {RelativeSource ...}

Ces chaînes de caractères, encadrées des signes {}, forment ce que l'on appelle des MarkupExtensions.

Il peut arriver, lors de vos développements WPF, que les fonctionnalités offertes par le XAML ne soient pas suffisantes. Pour pallier à ce problème, la solution est d'écrire la fonctionnalité manquante dans le ode behind. Cela marche très bien mais comment faire si l'on ne veut pas écrire cette fonctionnalité dans le code mais faire le maximum de choses en XAML ? On écrit sa propre MarkupExtension ! Smile

Pour faire cela, il n'y a rien d'extraordainire: il vous suffit de créer une classe qui hérite de MarkupExtension et de surcharger la méthode ProvideValue:

public override object ProvideValue(IServiceProvider serviceProvider)

{

    return "Hello World";

}

Notez que les conventions WPF veulent que le nom de votre extension doit-être XXXExtension mais, dans le code, vous pouvez utitliser simplement XXX: c'est la même chose pour les attributs .NET par exemple (qui se nomme YYYAttribute mais que l'on utilise sous la forme YYY):

<TextBlock Text="{CustomExtension:CalculateSum}" HorizontalAlignment="Center" VerticalAlignment="Center" />

Si vous souhaitez utiliser des paramètres, rien de bien compliquer: il vous suffit de déclarer des propriétés dans votre classe:

public double FirstNumber { get; set; }

public double SecondNumber { get; set; }

 

public override object ProvideValue(IServiceProvider serviceProvider)

{

    if (FirstNumber == 0.0 && SecondNumber == 0.0)

    {

        return "No parameters specify";

    }

    else

    {

        return Convert.ToString(FirstNumber + SecondNumber);

    }

}

Et ensuite, de les utiliser dans votre code XAML:

<TextBlock Text="{CustomExtension:CalculateSum FirstNumber=5, SecondNumber=20}" HorizontalAlignment="Center" 

VerticalAlignment="Center" />

A l'exécution, vous remarquez que l'affichage affiche bien le résultat escompté:

 image

Vous avez sans doute remarquez que la méthode ProvideValue renvoit un object: cela sous-entend que vous pouvez lui faire renvoyer ce que vous voulez (chaîne de caractères, images, entier, etc...). Cependant, dans la majorité des cas, vous connaissez le type que vous souhaitez renvoyer: c'est pourquoi il est bon de le spécifier, sur la classe, l'attribut MarkupExtensionReturnType (qui prend en paramètre le type à renvoyer) qui est utilisé par le parseur XAML à la compilation pour s'assurer que vous assigner un type correct à la propriété sur laquelle l'extension est utilisée:

[MarkupExtensionReturnType(typeof(string))]

Au final, votre classe (le code de votre extension) ressemblera donc à ceci:

[MarkupExtensionReturnType(typeof(string))]

public class CalculateSumExtension : MarkupExtension

{

    public double FirstNumber { get; set; }

    public double SecondNumber { get; set; }

 

    public override object ProvideValue(IServiceProvider serviceProvider)

    {           

        if (FirstNumber == 0.0 && SecondNumber == 0.0)

        {

            return "No parameters specify";

        }

        else

        {

            return Convert.ToString(FirstNumber + SecondNumber);

        }

    }

}

Bon développement à tous !

 

A+

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Posted: mercredi 14 mai 2008 10:52 par Thomas LEBRUN
Classé sous : ,

Commentaires

PlaTyPuS a dit :

Intéressant! Je savais pas qu'on pouvait faire ca ;-). Merci.

Par contre, crois-tu que c'est + performant que d'utiliser un converter? (dans un cas comme celui que tu démontres...)

thx, ++

# mai 16, 2008 10:40

Thomas LEBRUN a dit :

Je n'ai pas testé les performances mais dans un cas comme celui-ci, il aurait été difficile d'implémenter un converter.

C'est surtout pour des besoins différents....

# mai 16, 2008 10:45
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Un outil pour réaliser des animations WPF basées sur des équations de Bézier par Perspective le il y a 1 heure et 10 minutes

- Sandcastle et CodePlex : le verdict par CoqBlog le il y a 2 heures et 2 minutes

- Webcasts sur le Parallel Framework disponibles par Matthieu MEZIL le il y a 5 heures et 29 minutes

- [Silverlight] - Comprendre et Débuter avec Silverlight par Danuz le il y a 10 heures et 14 minutes

- SharePoint : Nouvel article sur l'exportation et Importation de sites SharePoint par Blog Technique de Romelard Fabrice le il y a 21 heures et 55 minutes

- ImagineCup 2008 Final in Paris: Day 1 par Richard Clark le 07-03-2008, 22:48

- PowerShell : Comment utiliser un ENUM .NET dans un script PowerShell par Blog Technique de Romelard Fabrice le 07-03-2008, 18:09

- OU SONT LES VISITEURS DE MON SITE ? par Nix's Blog le 07-03-2008, 15:07

- PowerShell : Quelques outils de développement adaptés par Blog Technique de Romelard Fabrice le 07-03-2008, 14:50

- [DevWeb] "FireFox est lent quand je developpe en local ?" par The diary of EBArtSoft le 07-03-2008, 14:47