Setzen Sie den Wert in der WPF-Bindung auf null

116

Bitte schauen Sie sich die folgende Zeile an

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

Diese Price-Eigenschaft von oben ist eine Decimal?(nullbare Dezimalstelle).

Ich möchte, dass, wenn der Benutzer den Inhalt des Textfelds löscht (dh eine leere Zeichenfolge eingibt, die Quelle automatisch mit null aktualisiert wird (Nothing in VB).

Irgendwelche Ideen, wie ich es 'Xamly' machen kann?

Shimmy Weitzhandler
quelle

Antworten:

226

Ich verwende .NET 3.5 SP1, daher ist es sehr einfach:

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

Wofür steht (danke Gregor für deinen Kommentar):

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

sysist der importierte XML-Namespace für Systemin mscorlib:

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

Hoffe das hat geholfen.

Shimmy Weitzhandler
quelle
13
Eigentlich funktioniert TargetNullValue einwandfrei. Es wird eine Äquivalenz zwischen dem angegebenen Wert und null festgelegt. Wenn in diesem Fall der gebundene Wert null ist, wird eine leere Zeichenfolge angezeigt, und wenn der Wert des Ziels die leere Zeichenfolge ist, wird der gebundene Wert auf null gesetzt.
Bryan Anderson
4
Der TargetNullValue funktioniert. Ich habe die gleichen Ergebnisse bei der Verwendung des Wertekonverters erhalten. Sie können den Ausdruck auch vereinfachen: <TextBox Text = "{Binding Price, TargetNullValue = ''}" />
Gregor Slavec
2
Ich bin verwirrt - das OP sagt: "..es sollte die Quelle automatisch mit null aktualisieren [wenn Target eine leere Zeichenfolge ist].", Aber TargetNullValue aktualisiert das Ziel , nicht die Quelle !
Markmnl
1
Du bist nicht der einzige, der verwirrt ist - es gibt auch verwirrte Kommentare zu der anderen Antwort. Das OP ist auch etwas verwirrt, wenn er sagt, dass die Quelle aktualisiert werden soll, meint er tatsächlich, dass das Ziel in WPF spricht (die Quelle ist die Text-Eigenschaft in der TextBox). TargetNullValue gibt an, auf welchen Wert die Quelle gesetzt werden soll, wenn das Ziel null ist. Das Gegenteil davon, was wir hier ausnutzen, ist, dass das Ziel auf Null gesetzt wird, wenn die Quelle auf diesen angegebenen Wert aktualisiert wird.
Nathan Phillips
@markmnl Während TargetNullValue tatsächlich dazu gedacht ist, das Targetund nicht das zu aktualisieren Source, macht diese Lösung aus irgendeinem Grund immer noch den Trick (ich konnte nicht genau herausfinden, warum).
Tim Pohlmann
12

Dieser Wertekonverter sollte den Trick machen:

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);
    }
}

Deklarieren Sie eine Instanz dieses Konverters in den Ressourcen:

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

Und verwenden Sie es in Ihrer Bindung:

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

Beachten Sie, dass dies TargetNullValuehier nicht angemessen ist: Hiermit wird definiert, welcher Wert verwendet werden soll, wenn sourcedie Bindung null ist. Hier Priceist nicht die Quelle, es ist eine Eigenschaft der Quelle ...

Thomas Levesque
quelle
2
Ein Konverter ist der richtige Weg, und Sie können diese Konverter nicht in XAML definieren. Mit Konvertern können Sie das Standardkonvertierungsverhalten von "Objekt zu Objekt" bei der Datenbindung ändern. Dies möchten Sie tun.
Will Eddins
Das Problem in meinem Fall ist, dass ich hier bereits einen Konvereter verwende, der eine andere Sache macht. Ich habe eine Antwort gepostet, bitte schauen Sie.
Shimmy Weitzhandler
Vielleicht möchten Sie IsNullOrWhiteSpace () verwenden, damit "" als null gezählt werden kann (höchstwahrscheinlich was Sie wollen)
Simon_Weaver
+1 Allerdings: Der Preis ist hier Ihre Quelle, aber Sie sind korrekt. TargetNullValue ist hier nicht geeignet. TargetNullValue setzt das Ziel, wenn die Quelle null ist. Wir möchten die Quelle (auf null) setzen, wenn das Ziel ein bestimmter Wert (leer) ist string) - was Ihr Konverter tut.
Markmnl
5

Sie können versuchen, einen ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx zu verwenden

Von meinem Hinterkopf hier so etwas wie:

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);
    }
}

(Möglicherweise müssen einige Anpassungen vorgenommen werden.)

TimothyP
quelle
Ich würde einen Xamly-Weg bevorzugen, aber mir
fällt