web-dev-qa-db-fra.com

Définissez la valeur sur null dans la liaison WPF

veuillez consulter la ligne suivante

<TextBox Text="{Binding Price}"/>

Cette propriété Price ci-dessus est un Decimal? (Décimal nul).

Je veux que si l'utilisateur supprime le contenu de la zone de texte (c'est-à-dire qu'il entre une chaîne vide, il devrait automatiquement mettre à jour la source avec null (Rien dans VB).

Des idées sur la façon dont je peux le faire "Xamly"?

113
Shimmy

J'utilise .NET 3.5 SP1, c'est donc très simple:

<TextBox Text="{Binding Price, TargetNullValue=''}"/>

Ce qui signifie (merci Gregor pour votre commentaire):

<TextBox Text="{Binding Price, TargetNullValue={x:Static sys:String.Empty}}"/>

sys est l'espace de noms xml importé pour System dans mscorlib:

xmlns:sys="clr-namespace:System;Assembly=mscorlib"

J'espère que cela a aidé.

220
Shimmy

Ce convertisseur de valeur devrait faire l'affaire:

public class StringToNullableDecimalConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
        CultureInfo culture)
    {
        decimal? d = (decimal?)value;
        if (d.HasValue)
            return d.Value.ToString(culture);
        else
            return String.Empty;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        string s = (string)value;
        if (String.IsNullOrEmpty(s))
            return null;
        else
            return (decimal?)decimal.Parse(s, culture);
    }
}

Déclarez une instance de ce convertisseur dans les ressources:

<Window.Resources>
    <local:StringToNullableDecimalConverter x:Key="nullDecimalConv"/>
</Window.Resources>

Et utilisez-le dans votre reliure:

<TextBox Text="{Binding Price, Converter={StaticResource nullDecimalConv}}"/>

Notez que TargetNullValue n'est pas approprié ici: il est utilisé pour définir la valeur à utiliser lorsque le source de la liaison est nul. Ici Price n'est pas la source, c'est une propriété de la source ...

11
Thomas Levesque

Vous pouvez essayer d'utiliser un ValueConverter (IValueConverter) http://msdn.Microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

De l'arrière de ma tête ici, quelque chose comme:

public class DoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return (double)value;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
    var doubleValue = Convert.ToDouble(value);

    return (doubleValue == 0 ? null : doubleValue);
    }
}

(Peut-être besoin de quelques ajustements cependant)

5
TimothyP