Recherche…


Paramètres

Paramètre Détails
valeur La valeur produite par la source de liaison.
valeurs Le tableau de valeurs, produit par la source de liaison.
targetType Le type de la propriété cible de liaison.
paramètre Le paramètre de convertisseur à utiliser.
Culture La culture à utiliser dans le convertisseur.

Remarques

Qu'est-ce que IValueConverter et IMultiValueConverterthey sont

IValueConverter et IMultiValueConverter - interfaces permettant d'appliquer une logique personnalisée à une liaison.

Qu'est-ce qu'ils sont utiles pour

  1. Vous avez une certaine valeur de type mais vous voulez afficher les valeurs nulles d'une manière et les nombres positifs d'une autre manière
  2. Vous avez une certaine valeur de type et souhaitez afficher l'élément dans un cas et le cacher dans un autre
  3. Vous avez une valeur numérique mais vous voulez le montrer en mots
  4. Vous avez une valeur numérique mais vous souhaitez afficher des images différentes pour les numéros différents

Ce sont quelques cas simples, mais il y en a beaucoup plus.

Pour des cas comme celui-ci, vous pouvez utiliser un convertisseur de valeur. Ces petites classes, qui implémentent l'interface IValueConverter ou IMultiValueConverter, agiront comme des intermédiaires et traduiront une valeur entre la source et la destination. Ainsi, dans toute situation où vous devez transformer une valeur avant qu’elle n’atteigne sa destination ou qu’elle ne soit à nouveau source, vous avez probablement besoin d’un convertisseur.

Build-In BooleanToVisibilityConverter [IValueConverter]

Convertisseur entre booléen et visibilité. Récupère la valeur bool en entrée et renvoie la valeur de Visibility .

Remarque: ce convertisseur existe déjà dans l'espace de noms System.Windows.Controls .

public sealed class BooleanToVisibilityConverter : IValueConverter
{
    /// <summary>
    /// Convert bool or Nullable bool to Visibility
    /// </summary>
    /// <param name="value">bool or Nullable bool</param>
    /// <param name="targetType">Visibility</param>
    /// <param name="parameter">null</param>
    /// <param name="culture">null</param>
    /// <returns>Visible or Collapsed</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool bValue = false;
        if (value is bool)
        {
            bValue = (bool)value;
        }
        else if (value is Nullable<bool>)
        {
            Nullable<bool> tmp = (Nullable<bool>)value;
            bValue = tmp.HasValue ? tmp.Value : false;
        }
        return (bValue) ? Visibility.Visible : Visibility.Collapsed;
    }

    /// <summary>
    /// Convert Visibility to boolean
    /// </summary>
    /// <param name="value"></param>
    /// <param name="targetType"></param>
    /// <param name="parameter"></param>
    /// <param name="culture"></param>
    /// <returns></returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Visibility)
        {
            return (Visibility)value == Visibility.Visible;
        }
        else
        {
            return false;
        }
    }
}

Utiliser le convertisseur

  1. Définir une ressource
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
  1. Utilisez-le dans la liaison
<Button Visibility="{Binding AllowEditing, 
                             Converter={StaticResource BooleanToVisibilityConverter}}"/>

Convertisseur avec propriété [IValueConverter]

Montrer comment créer un convertisseur simple avec un paramètre via une propriété, puis le transmettre dans une déclaration. Convertissez la valeur bool en Visibility . Autorise l'inversion de la valeur du résultat en définissant la propriété Inverted sur True .

public class BooleanToVisibilityConverter : IValueConverter
{
    public bool Inverted { get; set; }

    /// <summary>
    /// Convert bool or Nullable bool to Visibility
    /// </summary>
    /// <param name="value">bool or Nullable bool</param>
    /// <param name="targetType">Visibility</param>
    /// <param name="parameter">null</param>
    /// <param name="culture">null</param>
    /// <returns>Visible or Collapsed</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool bValue = false;
        if (value is bool)
        {
            bValue = (bool)value;
        }
        else if (value is Nullable<bool>)
        {
            Nullable<bool> tmp = (Nullable<bool>)value;
            bValue = tmp ?? false;
        }

        if (Inverted)
            bValue = !bValue;
        return (bValue) ? Visibility.Visible : Visibility.Collapsed;
    }

    /// <summary>
    /// Convert Visibility to boolean
    /// </summary>
    /// <param name="value"></param>
    /// <param name="targetType"></param>
    /// <param name="parameter"></param>
    /// <param name="culture"></param>
    /// <returns>True or False</returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Visibility)
        {
            return ((Visibility) value == Visibility.Visible) && !Inverted;
        }

        return false;
    }
}

Utiliser le convertisseur

  1. Définir un espace de noms

xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"

  1. Définir une ressource
<converters:BooleanToVisibilityConverter x:Key="BoolToVisibilityInvertedConverter"
                                         Inverted="False"/>
  1. Utilisez-le dans la liaison
<Button Visibility="{Binding AllowEditing, Converter={StaticResource BoolToVisibilityConverter}}"/>

Simple add converter [IMultiValueConverter]

Montrer comment créer un simple convertisseur IMultiValueConverter et utiliser MultiBinding dans xaml. Obtient la somme de toutes les valeurs transmises par le tableau de values .

public class AddConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        decimal sum = 0M;

        foreach (string value in values)
        {
            decimal parseResult;
            if (decimal.TryParse(value, out parseResult))
            {
                sum += parseResult;
            }
        }

        return sum.ToString(culture);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Utiliser le convertisseur

  1. Définir un espace de noms
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
  1. Définir une ressource
<converters:AddConverter x:Key="AddConverter"/>
  1. Utilisez-le dans la liaison
<StackPanel Orientation="Vertical">
    <TextBox x:Name="TextBox" />
    <TextBox x:Name="TextBox1" />
    <TextBlock >
        <TextBlock.Text>
            <MultiBinding Converter="{StaticResource AddConverter}">
                <Binding Path="Text" ElementName="TextBox"/>
                <Binding Path="Text" ElementName="TextBox1"/>
            </MultiBinding>
         </TextBlock.Text>
    </TextBlock>
</StackPanel>

Convertisseurs d'utilisation avec ConverterParameter

Montrer comment créer un convertisseur simple et utiliser ConverterParameter pour passer le paramètre au convertisseur. Multipliez la valeur par le coefficient passé dans ConverterParameter.

public class MultiplyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return 0;

        if (parameter == null)
            parameter = 1;

        double number;
        double coefficient;

        if (double.TryParse(value.ToString(), out number) && double.TryParse(parameter.ToString(), out coefficient))
        {
            return number * coefficient;
        }

        return 0;
    }

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

Utiliser le convertisseur

  1. Définir un espace de noms
xmlns:converters="clr-namespace:MyProject.Converters;assembly=MyProject"
  1. Définir une ressource
<converters:MultiplyConverter x:Key="MultiplyConverter"/>
  1. Utilisez-le dans la liaison
<StackPanel Orientation="Vertical">
    <TextBox x:Name="TextBox" />
    <TextBlock Text="{Binding Path=Text, 
                              ElementName=TextBox, 
                              Converter={StaticResource MultiplyConverter},
                              ConverterParameter=10}"/>
</StackPanel>

Grouper plusieurs convertisseurs [IValueConverter]

Ce convertisseur enchaînera plusieurs convertisseurs.

public class ValueConverterGroup : List<IValueConverter>, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
    }

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

Dans cet exemple, le résultat booléen de EnumToBooleanConverter est utilisé comme entrée dans BooleanToVisibilityConverter .

<local:ValueConverterGroup x:Key="EnumToVisibilityConverter">
    <local:EnumToBooleanConverter/>
    <local:BooleanToVisibilityConverter/>
</local:ValueConverterGroup>

Le bouton ne sera visible que lorsque la propriété CurrentMode est définie sur Ready .

<Button Content="Ok" Visibility="{Binding Path=CurrentMode, Converter={StaticResource EnumToVisibilityConverter}, ConverterParameter={x:Static local:Mode.Ready}"/>

Utilisation de MarkupExtension avec des convertisseurs pour ignorer la déclaration de recource

Habituellement, pour utiliser le convertisseur, nous devons le définir comme ressource de la manière suivante:

<converters:SomeConverter x:Key="SomeConverter"/>

Il est possible d'ignorer cette étape en définissant un convertisseur comme MarkupExtension et en implémentant la méthode ProvideValue . L'exemple suivant convertit une valeur en son négatif:

namespace MyProject.Converters
{
public class Converter_Negative : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return this.ReturnNegative(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return this.ReturnNegative(value);
    }

    private object ReturnNegative(object value)
    {
        object result = null;
        var @switch = new Dictionary<Type, Action> {
            { typeof(bool), () => result=!(bool)value },
            { typeof(byte), () => result=-1*(byte)value },
            { typeof(short), () => result=-1*(short)value },
            { typeof(int), () => result=-1*(int)value },
            { typeof(long), () => result=-1*(long)value },
            { typeof(float), () => result=-1f*(float)value },
            { typeof(double), () => result=-1d*(double)value },
            { typeof(decimal), () => result=-1m*(decimal)value }
        };

        @switch[value.GetType()]();
        if (result == null) throw new NotImplementedException();
        return result;
    }

    public Converter_Negative()
        : base()
    {
    }

    private static Converter_Negative _converter = null;

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (_converter == null) _converter = new Converter_Negative();
        return _converter;
    }
}
}

En utilisant le convertisseur:

  1. Définir un espace de noms

    xmlns: converters = "espace de noms clr: MyProject.Converters; assembly = MyProject"

  2. Exemple d'utilisation de ce convertisseur en liaison

    <RichTextBox IsReadOnly="{Binding Path=IsChecked, ElementName=toggleIsEnabled, Converter={converters:Converter_Negative}}"/>
    

Utilisez IMultiValueConverter pour transmettre plusieurs paramètres à une commande

Il est possible de transmettre plusieurs valeurs liées en tant que CommandParameter aide de MultiBinding avec un IMultiValueConverter très simple:

namespace MyProject.Converters
{
    public class Converter_MultipleCommandParameters : MarkupExtension, IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return values.ToArray();
        }
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        private static Converter_MultipleCommandParameters _converter = null;

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null) _converter = new Converter_MultipleCommandParameters();
            return _converter;
        }

        public Converter_MultipleCommandParameters()
            : base()
        {
        }
    }
}

En utilisant le convertisseur:

  1. Exemple d'implémentation - méthode appelée lorsque SomeCommand est exécuté ( note: DelegateCommand est une implémentation de ICommand non fournie dans cet exemple ):

     private ICommand _SomeCommand;
     public ICommand SomeCommand
     {
         get { return _SomeCommand ?? (_SomeCommand = new DelegateCommand(a => OnSomeCommand(a))); }
     }
    
     private void OnSomeCommand(object item)
     {
         object[] parameters = item as object[];
    
         MessageBox.Show(
             string.Format("Execute command: {0}\nParameter 1: {1}\nParamter 2: {2}\nParamter 3: {3}",
             "SomeCommand", parameters[0], parameters[1], parameters[2]));
     }
    
  2. Définir un espace de noms

xmlns: converters = "espace de noms clr: MyProject.Converters; assembly = MyProject"

  1. Exemple d'utilisation de ce convertisseur en liaison

    <Button Width="150" Height="23" Content="Execute some command" Name="btnTestSomeCommand"
         Command="{Binding Path=SomeCommand}" >
         <Button.CommandParameter>
             <MultiBinding Converter="{converters:Converter_MultipleCommandParameters}">
                 <Binding RelativeSource="{RelativeSource Self}" Path="IsFocused"/>
                 <Binding RelativeSource="{RelativeSource Self}" Path="Name"/>
                 <Binding RelativeSource="{RelativeSource Self}" Path="ActualWidth"/>
             </MultiBinding>
         </Button.CommandParameter>
     </Button>
    


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow