WPF: comment utiliser 2 convertisseurs en 1 reliure?

j'ai un contrôle que je veux afficher/masquer, en fonction de la valeur d'un booléen.

j'ai un convertisseur de basse tension négatif (switches true to false et vice versa) et j'ai besoin d'exécuter ce convertisseur en premier. J'ai un convertisseur de BooleanToVisibilityConverter et j'ai besoin d'exécuter ce convertisseur après le convertisseur de bool negated.

Comment puis-je résoudre ce problème? Je veux faire ça à XAML.

edit: c'est une possibilité solution.

ça ne semble pas marcher. Il convertit d'abord la valeur avec les convertisseurs séparés puis fait quelque chose avec les valeurs converties.

ce dont j'ai besoin est:

  • convertissez la valeur avec le premier convertisseur (ce qui donne la valeur convertie).
  • Converter convertedValue avec le deuxième convertisseur et c'est ce résultat dont j'ai besoin.
35
demandé sur Community 2009-10-20 16:46:57

9 réponses

C'est ce que j'ai fait:

public class CombiningConverter : IValueConverter
    {
        public IValueConverter Converter1 { get; set; }
        public IValueConverter Converter2 { get; set; }

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            object convertedValue = Converter1.Convert(value, targetType, parameter, culture);
            return Converter2.Convert(convertedValue, targetType, parameter, culture);
        }

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

        #endregion
    }

et je l'appelle comme ça:

<converters:CombiningConverter x:Key="negatedBoolToVisibilityConverter" Converter1="{StaticResource NegatedBooleanConverter}" Converter2="{StaticResource BoolToVisibilityConverter}" />

un MultiValueConverter pourrait aussi être possible je pense. Peut-être que je vais essayer plus tard.

52
répondu Natrium 2009-10-20 14:28:14

développement sur la grande réponse de Natrium...

XAML

<conv:ConverterChain x:Key="convBoolToInverseToVisibility">
    <conv:BoolToInverseConverter />
    <BooleanToVisibilityConverter />
</conv:ConverterChain>

Classe

/// <summary>Represents a chain of <see cref="IValueConverter"/>s to be executed in succession.</summary>
[ContentProperty("Converters")]
[ContentWrapper(typeof(ValueConverterCollection))]
public class ConverterChain : IValueConverter
{
    private readonly ValueConverterCollection _converters= new ValueConverterCollection();

    /// <summary>Gets the converters to execute.</summary>
    public ValueConverterCollection Converters
    {
        get { return _converters; }
    }

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Converters
            .Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Converters
            .Reverse()
            .Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
    }

    #endregion
}

/// <summary>Represents a collection of <see cref="IValueConverter"/>s.</summary>
public sealed class ValueConverterCollection : Collection<IValueConverter> { }
28
répondu Jake Berger 2016-05-19 18:46:22

ce que nous faisons dans notre projet est de faire un BooleanToVisibilityConverter régulier, dit convertisseur prend un paramètre (n'importe quoi, une chaîne, Un int, bool, n'importe quoi). Si le paramètre est défini, il inverse le résultat, si pas, il crache de l'ordinaire résultat.

public class BooleanToVisibilityConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool? isVisible = value as bool?;
        if (parameter != null && isVisible.HasValue)
            isVisible = !isVisible;
        if (isVisible.HasValue && isVisible.Value == true)
            return Visibility.Visible;
        else
            return Visibility.Collapsed;
    }

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

    #endregion
}
3
répondu Carlo 2009-10-20 14:21:56

dans ce cas, vous n'avez pas besoin d'une chaîne de convertisseur. Vous avez juste besoin d'un convertisseur configurable. Ceci est similaire à la réponse de Carlo ci-dessus, mais définit explicitement les valeurs true et false (ce qui signifie que vous pouvez utiliser les mêmes convertisseurs pour les conversions cachées, visibles ou effondrées).

[ValueConversion(typeof(bool), typeof(Visibility))]
public class BoolToVisibilityConverter : IValueConverter
{
    public Visibility TrueValue { get; set; }
    public Visibility FalseValue { get; set; }

    public BoolToVisibilityConverter()
    {
        // set defaults
        FalseValue = Visibility.Hidden;
        TrueValue = Visibility.Visible;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? TrueValue : FalseValue;
    }

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

puis dans XAML:

    <BoolToVisibilityConverter x:Key="BoolToVisibleConverter"
                               FalseValue="Hidden"
                               TrueValue="Visible" />
3
répondu metao 2015-02-04 08:43:18

pour répondre à nouveau à ma propre question: j'utilise cette solution depuis des années maintenant: http://www.codeproject.com/Articles/15061/Piping-Value-Converters-in-WPF

il fait un nouveau convertisseur de 2 convertisseurs existants, appelant le premier d'abord, puis le second etc etc

je suis assez satisfait de cette solution.

1
répondu Natrium 2016-08-24 05:54:21

je viens de créer ce que j'ai appelé Réversedbooleantovisibilityconverter pour faire essentiellement ce que ces deux-là feraient pour vous, mais en un seul pas.

0
répondu Alan Mendelevich 2009-10-20 13:43:16

pour résoudre ce problème spécifique, au lieu d'utiliser deux convertisseurs, vous pourriez écrire votre propre convertisseur BoolToVisibilityConverter qui utilise le ConverterParameter (comme un bool) pour déterminer si oui ou non de nier le booléen original.

0
répondu John Myczek 2009-10-20 13:47:31

personnellement, je voudrais juste faire 1 convertisseur simple qui fait la conversion complète. Sauf si vous avez désespérément besoin des convertisseurs (comme la négation) dans d'autres endroits, il sera plus facile de maintenir (imo) si la conversion est faite une fois, dans un endroit.

0
répondu Alastair Pitts 2009-10-20 13:48:19

je pense que vous pourriez vouloir utiliser un convertisseur multiple ici au lieu de deux convertisseurs séparés. Vous devriez être en mesure de réutiliser la logique de vos convertisseurs. Cochez cette discussion pour commencer.

0
répondu Scott Lawrence 2009-10-20 14:16:21