164 votes

Comment inverser le BooleanToVisibilityConverter ?

J'utilise un BooleanToVisibilityConverter dans WPF pour lier la propriété Visibility d'un contrôle à un booléen. Cela fonctionne bien, mais j'aimerais que l'un des contrôles soit masqué si le booléen est vrai, et affiché s'il est faux.

Est-ce possible ?

Merci, Andy

0 votes

Note : à partir de la version bêta 4, silverlight n'inclut pas BooleanToVisibility - vous devrez donc l'implémenter vous-même.

0 votes

Ajout d'une suggestion vocale de l'utilisateur pour obtenir le support de l'inversion. visualstudio.uservoice.com/forums/121579-visual-studio-2015/

0 votes

Je ne peux pas croire qu'ils n'aient pas implémenté des paramètres de convertisseur pour faire de telles choses.

273voto

Atif Aziz Points 16967

Au lieu d'inverser, vous pouvez atteindre le même objectif en utilisant un générique IValueConverter qui peut convertir une valeur booléenne en configurable les valeurs cibles pour le vrai et le faux. Vous trouverez ci-dessous l'une de ces implémentations :

public class BooleanConverter<T> : IValueConverter
{
    public BooleanConverter(T trueValue, T falseValue)
    {
        True = trueValue;
        False = falseValue;
    }

    public T True { get; set; }
    public T False { get; set; }

    public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is bool && ((bool) value) ? True : False;
    }

    public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value is T && EqualityComparer<T>.Default.Equals((T) value, True);
    }
}

Ensuite, sous-classez-la où T es Visibility :

public sealed class BooleanToVisibilityConverter : BooleanConverter<Visibility>
{
    public BooleanToVisibilityConverter() : 
        base(Visibility.Visible, Visibility.Collapsed) {}
}

Enfin, voici comment vous pourriez utiliser BooleanToVisibilityConverter ci-dessus dans XAML et le configurer pour, par exemple, utiliser Collapsed pour le vrai et Visible pour de faux :

<Application.Resources>
    <app:BooleanToVisibilityConverter 
        x:Key="BooleanToVisibilityConverter" 
        True="Collapsed" 
        False="Visible" />
</Application.Resources>

Cette inversion est utile lorsque vous voulez vous lier à une propriété booléenne nommée IsHidden comme opposé IsVisible .

0 votes

J'ai peut-être raté quelque chose, mais n'avez-vous pas simplement besoin d'une propriété niée ? stackoverflow.com/questions/534575/

11 votes

@OscarRyz : Avec des interfaces utilisateur plus complexes, cela commence à ajouter beaucoup d'encombrement vraiment ennuyeux aux modèles de vue, sans parler d'une autre propriété que vous devez théoriquement tester en unité afin de maintenir la couverture du code. Les modèles de vue ne devraient pas avoir à obtenir que proche des détails de l'implémentation de la vue, sinon vous pourriez tout aussi bien avoir juste Visibility dans votre modèle de vue.

0 votes

C'est si simple, mais très utile. Merci @AtifAziz.

52voto

Michael Hohlios Points 373

La meilleure solution pour l'instant est d'écrire son propre code. Voici un exemple d'un convertisseur qui peut faire les deux sens Normal et Inversé. Si vous avez des problèmes avec ceci, demandez-nous.

[ValueConversion(typeof(bool), typeof(Visibility))]
public class InvertableBooleanToVisibilityConverter : IValueConverter
{
    enum Parameters
    {
        Normal, Inverted
    }

    public object Convert(object value, Type targetType,
                          object parameter, CultureInfo culture)
    {
        var boolValue = (bool)value;
        var direction = (Parameters)Enum.Parse(typeof(Parameters), (string)parameter);

        if(direction == Parameters.Inverted)
            return !boolValue? Visibility.Visible : Visibility.Collapsed;

        return boolValue? Visibility.Visible : Visibility.Collapsed;
    }

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

<UserControl.Resources>
  <Converters:InvertableBooleanToVisibilityConverter x:Key="_Converter"/>
</UserControl.Resources>

<Button Visibility="{Binding IsRunning, Converter={StaticResource _Converter}, ConverterParameter=Inverted}">Start</Button>

2 votes

Je me demande juste une chose. Le code xaml "Binding IsRunning", où se trouve le code source ou la valeur de l'objet "IsRunning" ?

0 votes

IsRunning est une propriété de mon modèle de vue. Le contexte de ce code est long, mais en résumé, j'avais besoin que certaines choses soient cachées lorsque j'exécutais un calcul et que d'autres ne le soient pas. J'ai créé ce convertisseur pour éviter d'avoir plusieurs propriétés sur mon viewmodel.

2 votes

Vous pouvez en faire un remplacement direct de l'application normale de l'UE. BooleanToVisibilityConverter en vérifiant que le paramètre n'est pas nul : Parameter direction = Parameter.Normal; if (parameter != null) direction = (Parameter)Enum.Parse(typeof(Parameter), (string)parameter);

48voto

Simon Points 11945
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

public sealed class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var flag = false;
        if (value is bool)
        {
            flag = (bool)value;
        }
        else if (value is bool?)
        {
            var nullable = (bool?)value;
            flag = nullable.GetValueOrDefault();
        }
        if (parameter != null)
        {
            if (bool.Parse((string)parameter))
            {
                flag = !flag;
            }
        }
        if (flag)
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Collapsed;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));
        if (parameter != null)
        {
            if ((bool)parameter)
            {
                back = !back;
            }
        }
        return back;
    }
}

et ensuite passer un true ou un false comme ConverterParameter.

       <Grid.Visibility>
                <Binding Path="IsYesNoButtonSetVisible" Converter="{StaticResource booleanToVisibilityConverter}" ConverterParameter="true"/>
        </Grid.Visibility>

4 votes

Au else if (value is bool?) ReSharper me dit "Expression is always false". De plus, le if (flag) peut être réécrite de manière plus concise comme suit return flag ? Visibility.Visible : Visibility.Collapsed; .

1 votes

J'ai peut-être raté quelque chose, mais n'avez-vous pas simplement besoin d'une propriété niée ? stackoverflow.com/questions/534575/

1 votes

var nullable = (bool?)value; flag = nullable.GetValueOrDefault(); peut être rendu beaucoup plus court et simple : flag = (bool?)value ?? false;

21voto

Steve Mitcham Points 1248

Il suffit de mettre en œuvre votre propre implémentation de IValueConverter. Un exemple d'implémentation se trouve à

http://msdn.microsoft.com/en-us/library/system.Windows.data.ivalueconverter.aspx

Dans votre méthode Convert, faites en sorte qu'elle renvoie les valeurs que vous souhaitez au lieu des valeurs par défaut.

20voto

Cameron MacFarland Points 27240

Il y a aussi le Convertisseurs WPF sur Codeplex. Dans leur documentation, ils disent que vous pouvez utiliser leur MapConverter pour convertir l'énumération de visibilité en bool.

<Label>
    <Label.Visible>
        <Binding Path="IsVisible">
            <Binding.Converter>
                <con:MapConverter>
                    <con:Mapping From="True" To="{x:Static Visibility.Visible}"/>
                    <con:Mapping From="False" To="{x:Static Visibility.Hidden}"/>
                </con:MapConverter>
            </Binding.Converter>
        </Binding>
    </Label.Visible>
</Label>

1 votes

Les convertisseurs WPF comprennent désormais un convertisseur BooleanToVisibilityConverter qui peut être inversé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X