Ustaw wartość na null w powiązaniu WPF

116

proszę spojrzeć na następujący wiersz

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

Ta właściwość Price z góry to Decimal? (liczba dziesiętna dopuszczalna wartość null).

Chcę, aby jeśli użytkownik usuwał zawartość pola tekstowego (tj. Wprowadził pusty ciąg, powinien automatycznie zaktualizować źródło o null (Nothing w VB).

Jakieś pomysły, jak mogę to zrobić „Xamly”?

Shimmy Weitzhandler
źródło

Odpowiedzi:

226

Używam .NET 3.5 SP1, więc jest to bardzo proste:

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

Co oznacza (dzięki Gregorowi za komentarz):

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

systo zaimportowana przestrzeń nazw xml dla Systemin mscorlib:

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

Mam nadzieję, że to pomogło.

Shimmy Weitzhandler
źródło
13
Właściwie TargetNullValue działa dobrze. To, co robi, ustawia równoważność między podaną wartością a null. Więc w tym przypadku, gdy wartość powiązana jest równa null, wyświetli pusty ciąg, a gdy wartością docelową jest pusty ciąg, ustawia wartość powiązaną na null.
Bryan Anderson
4
TargetNullValue działa. Otrzymałem te same wyniki, używając konwertera wartości. Możesz również uprościć wyrażenie: <TextBox Text = "{Binding Price, TargetNullValue = ''}" />
Gregor Slavec
2
Jestem zdezorientowany - OP mówi: „.. powinno automatycznie aktualizować źródło o wartości null [gdy Target jest pustym ciągiem].”, Ale TargetNullValue aktualizuje element Target , a nie Source !
markmnl
1
Nie jesteś jedyną zdezorientowaną osobą - są też niejasne komentarze do drugiej odpowiedzi. OP również jest nieco zdezorientowany, kiedy mówi zaktualizuj źródło, w rzeczywistości ma na myśli element docelowy w mowie WPF (źródłem jest właściwość Text w TextBox). TargetNullValue mówi, jaką wartość ustawić Source, gdy Target ma wartość null. Odwrotność tego, z czego tutaj korzystamy, polega na tym, że gdy źródło zostanie zaktualizowane do tej określonej wartości, cel zostanie ustawiony na null.
Nathan Phillips,
@markmnl Chociaż TargetNullValue rzeczywiście ma na celu aktualizację, Targeta nie Source, to rozwiązanie z jakiegoś powodu nadal działa (nie mogłem do końca zrozumieć, dlaczego).
Tim Pohlmann
12

Ten konwerter wartości powinien załatwić sprawę:

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

Zadeklaruj wystąpienie tego konwertera w zasobach:

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

I użyj go w swojej oprawie:

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

Zauważ, że TargetNullValuenie jest to właściwe w tym miejscu: służy do definiowania, która wartość powinna być używana, gdy sourcepowiązanie ma wartość null. Tutaj Pricenie ma źródła, to własność źródła ...

Thomas Levesque
źródło
2
Konwerter to właściwy sposób na zrobienie tego i nie można zdefiniować tych konwerterów w języku XAML. Konwertery umożliwiają zmianę domyślnego zachowania konwersji „obiekt na obiekt” w powiązaniu danych, co jest tym, co chcesz zrobić.
Will Eddins
Problem w moim przypadku polega na tym, że używam tu już konwertera, który robi coś innego. Wysłałem odpowiedź, proszę spojrzeć.
Shimmy Weitzhandler
możesz chcieć użyć IsNullOrWhiteSpace (), aby umożliwić liczenie „” jako null (najprawdopodobniej tak, jak chcesz)
Simon_Weaver
+1 Jednak: Cena jest tutaj twoim źródłem, ale masz rację TargetNullValue nie jest tutaj odpowiednia - TargetNullValue ustawia cel, gdy źródło jest null - podczas gdy chcemy ustawić źródło (na null), gdy cel ma określoną wartość (pusty string) - co robi twój konwerter.
markmnl
5

Możesz spróbować użyć ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

Z tyłu głowy coś takiego:

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

(Może potrzebować trochę poprawek)

Timothy P.
źródło
Wolałbym sposób Xamly, ale nic nie
przychodzi mi do głowy