Un Content ON/OFF pour ToggleSwitch et CheckBox

Le ToggleSwitch est véritablement un superbe contrôle.
Enfin, au niveau design.
Car malheureusement, la personne qui l’a crée déteste manifestement le XAML.

Pour preuve, lorsque j’utilise ce contrôle dans mes applications pour créer des pages de paramétrage par exemple, je dois toujours passer par du code pour changer le label affichées à l’écran (texte « Off » sur l’image).

ToggleSwitch

C’est rageant vous ne trouvez pas ?

Changer le label par le code

Normalement pour changer le label, on affecte une chaine de caractère à la propriété Content du ToggleSwitch.
Pour que cela s’effectue lors des actions de switch on s’abonne aux événements Checked / Unchecked.
Selon l’événement on changera la propriété Content par la chaîne de caractères qui correspond à une valeur vrai ou Fausse.

NDLR : Dans cette exemple on considère que l’on désire changer des chaines de caractères mais l’on pourrait tout à fait mettre un objet quelconque dans Content (Control, Texte, Valeur,…)

Ce qu’il nous faudrait, et on se demande pourquoi cela na pas été géré ainsi depuis le début, ce sont deux propriétés « Content » supplémentaires qui correspondraient aux valeurs Vrai et Fausse.

Changer le label par le XAML

Pour rajouter ces deux propriétés, que l’on nommera « ContentOn » et « ContentOff » au contrôle ToggleSwitch, je vous propose de créer un Behavior (c’est à dire une extension des capacités d’un contrôle) à l’aide d’un assembly fournit par Blend.

NDLR : On aurait put réalisé un behavior d’une autre façon mais cette méthode me semble la plus simple et la plus extensible.

Vous pouvez référencer facilement cet assembly (System.Windows.Interactivity) dans votre app car elle est proposée comme extension dans le « Reference Manager » (accessible par le menu Project -> Add Reference).

Interactivity

On va pouvoir ajouter une classe « ToggleSwitchBehavior » qui héritera de « Behavior »

public class ToggleSwitchBehavior : System.Windows.Interactivity.Behavior<ToggleSwitch>
{
  ...
}

Celle-ci à la particularité de pouvoir se greffer au contrôle auquel elle se rattache (ici ToggleSwitch) de cette manière :

<Controls:ToggleSwitch IsChecked="{Binding IsSoundSynchronized, Mode=TwoWay}">
    <i:Interaction.Behaviors>
        <SamuelBlanchardControls:ToggleSwitchBehavior></SamuelBlanchardControls:ToggleSwitchBehavior>
    </i:Interaction.Behaviors>
</Controls:ToggleSwitch>  

On verra plus tard à quoi correspondent les namespaces i et SamuelBlanchardControls

On va ensuite déclarer nos deux propriétés « ContentOn » et « ContentOff » en tant que « Propderty Dependency » (snippet propdp). On aurait pu utiliser des propriétés classiques « get; set; » mais les propdp nous donnent la possibilité de rendre nos propriétés bindable, ce qui est un atout précieux en XAML.

        /// <summary>
        /// Postion On
        /// </summary>

        public string ContentOn
        {
            get { return (string)GetValue(ContentOnProperty); }
            set { SetValue(ContentOnProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ContentOn.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ContentOnProperty =
            DependencyProperty.Register("ContentOn", typeof(string), typeof(ToggleSwitchBehavior), new PropertyMetadata(null));

        /// <summary>
        /// Position Off
        /// </summary>

        public string ContentOff
        {
            get { return (string)GetValue(ContentOffProperty); }
            set { SetValue(ContentOffProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ContentOff.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ContentOffProperty =
            DependencyProperty.Register("ContentOff", typeof(string), typeof(ToggleSwitchBehavior), new PropertyMetadata(null));

On peut désormais attacher notre fonctionnalité de changement de Content à notre Behavior.
Pour se faire on surchage la méthode « OnAttached » de notre Behavior.

        protected override void OnAttached()
        {
            // this.AssociatedObject = ToggleSwitch
            this.AssociatedObject.Checked += AssociatedObject_Checked;
            this.AssociatedObject.Unchecked += AssociatedObject_Unchecked;

            // valuer par défaut
            this.AssociatedObject.Content = this.AssociatedObject.IsChecked == true ? this.ContentOn : this.ContentOff;

            base.OnAttached();
        }

Comme on le voit dans le code l’objet AssociatedObject correspond au control ToggleSwitch et l’on s’abonne donc aux events Checked et Unchecked.
On fixe également une valeur par défaut à notre Content qui correspond à la propriété ContentOn ou ContentOff selon la valeur de la propriété IsChecked de ToggleSwitch.

Les méthodes « AssociatedObject_Checked » et « AssociatedObject_Unchecked »
seront chargées quant à elles d’affecter à Content respectivement les valeurs ContentOn et ContentOff.

        void AssociatedObject_Unchecked(object sender, RoutedEventArgs e)
        {
            this.AssociatedObject.Content = this.ContentOff;
        }

        void AssociatedObject_Checked(object sender, RoutedEventArgs e)
        {
            this.AssociatedObject.Content = this.ContentOn;
        }

voila c’est terminé pour le code !

Intégration dans XAML

Pour pouvoir utiliser ce magnifique Behavior il suffit d’intégrer les deux namespaces suivants en entête de votre page

    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:SamuelBlanchardControls="clr-namespace:SamuelBlanchard.Controls"

puis de rajouter à votre ToggleSwitch :

<Controls:ToggleSwitch IsChecked="{Binding IsSoundSynchronized, Mode=TwoWay}">
    <i:Interaction.Behaviors>
        <SamuelBlanchardControls:ToggleSwitchBehavior ContentOff="Normal" ContentOn="Best"/>
    </i:Interaction.Behaviors>
</Controls:ToggleSwitch>

A l’exécution le Content sera automatiquement fixé aux valeurs de ContentOff et ContentOn mais malheureusement cela ne sera pas le cas en mode Design.

ToggleSwitchNormal

Vous trouverez le code du Behavior en cliquant sur ce lien.

PS : J’ai rajouter également un ToggleButtonBehavior qui vous permet de faire la même chose pour les CheckBoxs par exemple. En effet les CheckBoxs ne gèrent par non plus cette fonctionnalité. Cela me fait penser que le créateur des CheckBox n’aime pas non plus le XAML ou est le même créateur que celui du ToggleSwitch 😉

One Response to Un Content ON/OFF pour ToggleSwitch et CheckBox

  1.  

    Bonjour,
    Le post n’est pas mal. Mais au cas ou des personnes ne vois pas la date du poste il faudrait l’editer et préciser qu’aujourd’hui les valeur « OnContent= »On » » et « OffContent= »Off » » font très bien le travail.
    En tout cas sur WindowsStoreApp.

leave your comment