在 WPF 绑定中将值设置为 null

124
请看下面这行代码。
<TextBox Text="{Binding Price}"/>

以上的Price属性是一个Decimal?(可空的十进制数)。

我希望如果用户删除文本框的内容(即输入空字符串),它应该自动将数据源(绑定的目标)更新为null(在VB中为Nothing)。

有任何关于我如何在XAML中实现它的想法吗?

3个回答

239

我正在使用.NET 3.5 SP1,所以很简单:

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

这是由 Gregor 在评论中提供的缩写:

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

sys 是在 mscorlib 中导入 System 的 xml 命名空间:

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

希望这有所帮助。


14
TargetNullValue 实际上运作良好。它的作用是将给定的值与 null 建立等价关系。因此,在这种情况下,当绑定值为 null 时,它将显示为空字符串,而当目标值为空字符串时,它将将绑定值设置为 null。 - Bryan Anderson
4
目标空值(TargetNullValue)起作用了。当使用值转换器时,我得到了相同的结果。你也可以简化表达式:<TextBox Text="{Binding Price, TargetNullValue=''}"/>。 - Gregor Slavec
2
我感到困惑 - OP说:“..当Target是空字符串时,它应该自动将源更新为null。”,但是TargetNullValue会更新_Target_,而不是_Source_! - markmnl
1
你并不是唯一感到困惑的人——另一个答案中也有类似的困惑评论。提问者本人也稍微有些困惑,他说更新源,实际上是指 WPF 中的目标(源是 TextBox 上的 Text 属性)。TargetNullValue 指定了如果目标为空时要设置源的值。这个属性的反向操作是我们在这里要利用的,即当源被更新为此指定的值时,目标将被设置为 null。 - Nathan Phillips
@markmnl 我发了一个新的关于TargetNullValue的问题:https://dev59.com/OpXfa4cB1Zd3GeqPi7j- - Tim Pohlmann
显示剩余2条评论

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 为空时应使用哪个值。而在这里,Price 不是源,它是源的一个属性...


2
转换器是正确的方法,而且你不能在 XAML 中定义这些转换器。转换器允许你改变数据绑定中默认的“对象到对象”的转换行为,这正是你想要做的。 - Will Eddins
我的问题在于我已经在这里使用了一个转换器,它做了另一件事情。 我发布了一个答案,请看一下。 - Shimmy Weitzhandler
可能需要使用IsNullOrWhiteSpace()方法,以允许将空格字符" "视为null(这很可能是您想要的)。 - Simon_Weaver
+1 但是:价格是你的来源,但你是正确的,TargetNullValue 在这里不合适——当源为空时,TargetNullValue 设置目标,而我们想在目标是某个值(空字符串)时设置源(为空)——这正是你的转换器所做的。 - markmnl

5
您可以尝试使用值转换器(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);
    }
}

(可能需要一些调整)


我更喜欢Xamly的方式,但我想不出任何东西。 - Shimmy Weitzhandler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接