web-dev-qa-db-fra.com

WPF: Affiche une valeur booléenne sous la forme "Oui"/"Non"

J'ai une valeur bool que je dois afficher comme "Oui" ou "Non" dans un TextBlock. J'essaye de faire ceci avec un StringFormat, mais mon StringFormat est ignoré et le TextBlock affiche "True" ou "False".

<TextBlock Text="{Binding Path=MyBoolValue, StringFormat='{}{0:Yes;;No}'}" />

Ma syntaxe est-elle erronée ou ce type de StringFormat n'est-il pas pris en charge?

Je sais que je peux utiliser un ValueConverter pour accomplir cela, mais la solution StringFormat semble plus élégante (si elle a fonctionné).

41
John Myczek

Votre solution avec StringFormat ne peut pas fonctionner, car ce n'est pas une chaîne de format valide.

J'ai écrit une extension de balisage qui ferait ce que vous voulez. Vous pouvez l'utiliser comme ça:

<TextBlock Text="{my:SwitchBinding MyBoolValue, Yes, No}" />

Voici le code de l'extension de balisage:

public class SwitchBindingExtension : Binding
{
    public SwitchBindingExtension()
    {
        Initialize();
    }

    public SwitchBindingExtension(string path)
        : base(path)
    {
        Initialize();
    }

    public SwitchBindingExtension(string path, object valueIfTrue, object valueIfFalse)
        : base(path)
    {
        Initialize();
        this.ValueIfTrue = valueIfTrue;
        this.ValueIfFalse = valueIfFalse;
    }

    private void Initialize()
    {
        this.ValueIfTrue = Binding.DoNothing;
        this.ValueIfFalse = Binding.DoNothing;
        this.Converter = new SwitchConverter(this);
    }

    [ConstructorArgument("valueIfTrue")]
    public object ValueIfTrue { get; set; }

    [ConstructorArgument("valueIfFalse")]
    public object ValueIfFalse { get; set; }

    private class SwitchConverter : IValueConverter
    {
        public SwitchConverter(SwitchBindingExtension switchExtension)
        {
            _switch = switchExtension;
        }

        private SwitchBindingExtension _switch;

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                bool b = System.Convert.ToBoolean(value);
                return b ? _switch.ValueIfTrue : _switch.ValueIfFalse;
            }
            catch
            {
                return DependencyProperty.UnsetValue;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return Binding.DoNothing;
        }

        #endregion
    }

}
43
Thomas Levesque

Vous pouvez également utiliser ce convertisseur de grande valeur

Ensuite, vous déclarez en XAML quelque chose comme ceci:

<local:BoolToStringConverter x:Key="BooleanToStringConverter" FalseValue="No" TrueValue="Yes" />

Et vous pouvez l'utiliser comme ceci:

<TextBlock Text="{Binding Path=MyBoolValue, Converter={StaticResource BooleanToStringConverter}}" />
57
alf

Sans convertisseur 

            <TextBlock.Style>
                <Style TargetType="{x:Type TextBlock}">
                    <Setter Property="Text" Value="OFF" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding MyBoolValue}" Value="True">
                            <Setter Property="Text" Value="ON" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
29
Cedre

Il y a aussi une autre très bonne option. Cochez cette case: Alex141 CalcBinding

Dans mon DataGrid, je n'ai que:

<DataGridTextColumn Header="Mobile?" Binding="{conv:Binding (IsMobile?\'Yes\':\'No\')}" />

Pour l’utiliser, il suffit d’ajouter CalcBinding via GitHub, puis dans la déclaration UserControl/Windows, vous ajoutez

<Windows XXXXX xmlns:conv="clr-namespace:CalcBinding;Assembly=CalcBinding"/>
3
Simon

Ceci est une solution utilisant une Converter et la ConverterParameter qui vous permet de définir facilement différents strings pour différents Bindings:

public class BoolToStringConverter : IValueConverter
{
    public char Separator { get; set; } = ';';

    public object Convert(object value, Type targetType, object parameter,
                          CultureInfo culture)
    {
        var strings = ((string)parameter).Split(Separator);
        var trueString = strings[0];
        var falseString = strings[1];

        var boolValue = (bool)value;
        if (boolValue == true)
        {
            return trueString;
        }
        else
        {
            return falseString;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter,
                              CultureInfo culture)
    {
        var strings = ((string)parameter).Split(Separator);
        var trueString = strings[0];
        var falseString = strings[1];

        var stringValue = (string)value;
        if (stringValue == trueString)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

Définissez le convertisseur comme ceci:

<local:BoolToStringConverter x:Key="BoolToStringConverter" />

Et utilisez-le comme ceci:

<TextBlock Text="{Binding MyBoolValue, Converter={StaticResource BoolToStringConverter},
                                       ConverterParameter='Yes;No'}" />

Si vous avez besoin d'un séparateur différent de ; (par exemple .), définissez le convertisseur comme suit:

<local:BoolToStringConverter x:Key="BoolToStringConverter" Separator="." />
2
Tim Pohlmann

Ceci est une autre alternative au convertisseur simplifié avec des valeurs Oui/Non "codées en dur"

[ValueConversion(typeof (bool), typeof (bool))]
public class YesNoBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var boolValue = value is bool && (bool) value;

        return boolValue ? "Yes" : "No";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value != null && value.ToString() == "Yes";
    }
}

Utilisation de XAML

<DataGridTextColumn Header="Is Listed?" Binding="{Binding Path=IsListed, Mode=TwoWay, Converter={StaticResource YesNoBoolConverter}}" Width="110" IsReadOnly="True" TextElement.FontSize="12" />
1
Kwex

Ce qui suit a fonctionné pour moi dans une colonne datagridtext: J'ai ajouté une autre propriété à ma classe qui renvoyait une chaîne en fonction de la valeur de MyBool . Notez que dans mon cas, la grille de données était liée à un objet CollectionViewSource of MyClass.

C #:

public class MyClass        
{     
    public bool MyBool {get; set;}   

    public string BoolString    
    {    
        get { return MyBool == true ? "Yes" : "No"; }    
    }    
}           

XAML:

<DataGridTextColumn Header="Status" Binding="{Binding BoolString}">
0
MGDsoft