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”?

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.


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 ...


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)


Wolałbym sposób Xamly, ale nic nie
— przychodzi mi do głowy
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.