Установите значение null в привязке WPF

116

пожалуйста, взгляните на следующую строку

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

Указанное выше свойство Price является Decimal?(десятичным, допускающим значение NULL).

Я хочу, чтобы, если пользователь удаляет содержимое текстового поля (т.е. вводит пустую строку, он должен автоматически обновлять источник с помощью нуля (ничего в VB).

Есть идеи, как я могу сделать это «Xamly»?

Шимми Вайцхандлер
источник

Ответы:

226

Я использую .NET 3.5 SP1, поэтому это очень просто:

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

Что означает (спасибо Грегору за ваш комментарий):

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

sysэто импортированное пространство имен xml для Systemin mscorlib:

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

Надеюсь, это помогло.

Шимми Вайцхандлер
источник
13
На самом деле TargetNullValue работает нормально. Он устанавливает эквивалентность между заданным значением и нулевым значением. Таким образом, в этом случае, когда привязанное значение равно нулю, оно будет отображать пустую строку, а когда целевым значением является пустая строка, оно установит связанное значение на null.
Брайан Андерсон
4
TargetNullValue работает. Я получил такие же результаты при использовании преобразователя значений. Вы также можете упростить выражение: <TextBox Text = "{Binding Price, TargetNullValue = ''}" />
Грегор Славец
2
Я сбит с толку - OP говорит: «... он должен автоматически обновлять источник с нулевым значением [когда Target является пустой строкой].», Но TargetNullValue обновляет Target , а не Source !
markmnl
1
Не только вы запутались - к другому ответу тоже есть запутанные комментарии. OP также немного сбит с толку, когда он говорит, что обновите источник, он на самом деле означает, что Target в WPF говорит (источником является свойство Text в TextBox). TargetNullValue говорит, какое значение установить для источника, когда Target имеет значение null. Обратное, чем мы здесь пользуемся, заключается в том, что когда источник обновляется до этого заданного значения, для цели устанавливается значение null.
Натан Филлипс,
@markmnl Хотя TargetNullValue действительно предназначен для пересматриваемых Targetи не Source, это решение до сих пор трюк для какой - то причине (я не мог вполне понять, почему).
Тим Полманн,
12

Этот преобразователь значений должен помочь:

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

Объявите экземпляр этого конвертера в ресурсах:

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

И используйте его в своей привязке:

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

Обратите внимание, что TargetNullValueэто здесь неуместно: оно используется для определения того, какое значение следует использовать, когда sourceпривязка имеет значение null. Здесь Priceне источник, это свойство источника ...

Томас Левеск
источник
2
Конвертер - это правильный способ сделать это, и вы не можете определить эти конвертеры в XAML. Конвертеры позволяют вам изменить поведение преобразования «объект в объект» по умолчанию в привязке данных, что вы и хотите сделать.
Уилл Эддинс
В моем случае проблема в том, что я уже использую здесь конвертер, который выполняет другое действие. Я отправил ответ, пожалуйста, посмотрите.
Шимми Вайцхандлер
может захотеть использовать IsNullOrWhiteSpace (), чтобы позволить "" считаться нулевым (скорее всего, что вы хотите)
Simon_Weaver
+1 Однако: цена здесь ваш источник, но вы правы TargetNullValue здесь не подходит - TargetNullValue устанавливает цель, когда источник равен нулю - тогда как мы хотим установить источник (равным нулю), когда целью является определенное значение (пустое строка) - что и делает ваш конвертер.
markmnl
5

Вы можете попробовать использовать ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

Здесь на затылке что-то вроде:

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

(Хотя может потребоваться некоторая настройка)

TimothyP
источник
Я бы предпочел способ Xamly, но я ничего не могу придумать
Шимми Вейцхандлер