由于空值而无法评估绑定时使用默认值

Posted

技术标签:

【中文标题】由于空值而无法评估绑定时使用默认值【英文标题】:Use a default value when binding cannot be evaluated because of a null value 【发布时间】:2011-05-14 15:28:34 【问题描述】:

当由于 属性中的 null 值而无法评估 绑定 时,有没有办法分配 特殊值路径 ?

例如,如果我在类 Customer 中有一个属性 Name 和这样的绑定:

Binding CurrentCustomer.Name

CurrentCustomer 为空时,我希望绑定生成字符串“---”。

“TargetNullValue”和“FallbackValue”似乎不能解决问题。

提前感谢您的帮助。

编辑

事实上,我正在尝试做的是用 新的源值 代替不可用的 true。 真实场景如下:

bool 值用于确定控件的可见性,但当无法获得此值时,我想将其替换为“false”。

这是一个完美模仿我的真实用例的插图:

MainPage.xaml.cs:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace TestSilverlightBindingDefaultValue

    public class BoolToVisibilityConverter : IValueConverter
    
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        
            return (bool)value ? Visibility.Visible : Visibility.Collapsed;
        

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        
            throw new NotImplementedException();
        

        #endregion
    

    public class Customer
    
        public bool HasACar
        
            get;
            set;
        
    

    public partial class MainPage : UserControl
    
        public static readonly DependencyProperty CurrentCustomerProperty =
            DependencyProperty.Register("CurrentCustomer", typeof(Customer), typeof(MainPage), null);

        public Customer CurrentCustomer
        
            get  return this.GetValue(CurrentCustomerProperty) as Customer; 
            set  this.SetValue(CurrentCustomerProperty, value); 
        

        public MainPage()
        
            InitializeComponent();

            this.CurrentCustomer = null;

            this.DataContext = this;
        
    

MainPage.xaml:

<UserControl x:Class="TestSilverlightBindingDefaultValue.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:TestSilverlightBindingDefaultValue"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
    <local:BoolToVisibilityConverter x:Key="boolToVisibilityConverter" />
</UserControl.Resources>
    <StackPanel x:Name="LayoutRoot" Background="White">
    <TextBlock Text="You have a car"  Visibility="Binding CurrentCustomer.HasACar,Converter=StaticResource boolToVisibilityConverter" />
</StackPanel>

FallbackValue 不是解决方案,因为它只会更改生成的值而不是源值。

Abe Heidebrecht 已经通过 PriorityBindingWPF 提供了完美的解决方案,但它在 Silverlight 中不存在。

最终编辑Abe Heidebrecht的第二种解决方案,即包裹在另一个元素中,效果很好。

【问题讨论】:

【参考方案1】:

你可以使用PriorityBinding:

<TextBlock>
    <TextBlock.Text>
        <PriorityBinding>
            <Binding Path="CurrentCustomer.Name" />
            <Binding Source="---" />
        </PriorityBinding>
    </TextBlock.Text>
</TextBlock>

好的,对于 Silverlight,将元素包装在包装器(如边框)​​中可能更容易。然后,您有一个 IValueConverter 将 null 转换为 Visibility.Collapsed,并将其他任何内容转换为 Visibility.Visible

public class NullToVisibilityConverter : IValueConverter

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        return value != null ? Visibility.Visible : Visibility.Collapsed;
    

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        throw new NotImplementedException();
    

然后像这样使用它:

<Border Visibility="Binding CurrentCustomer, Converter=StaticResource NullToVisibilityConverter">
    <TextBlock Text="You have a car"  Visibility="Binding CurrentCustomer.HasACar,Converter=StaticResource boolToVisibilityConverter" />
</Border>

【讨论】:

我不知道你能做到这一点......我一直使用 DataTrigger 检查值是否等于x:Null。谢谢! 谢谢,这将是有效的解决方案...如果我没有使用似乎不支持 PriorityBinding 的 Silverlight 4。 我已经更新了答案以反映如何在 Silverlight 中做到这一点。 再次感谢您的大力帮助,但是...Silverlight 4 似乎也不支持 DataTrigger!对绑定和样式的支持还没有完全实现,这很烦人。如果没有人有其他干净的解决方案,我会将您的答案标记为已接受。 哈哈,我是个白痴。我更新了它,这样它就可以工作了。每次需要这种功能时都必须这样做是很烦人的。【参考方案2】:

嘿 TargetNullValue 和 FallbackValue 有效。可能是您使用的 .NET 版本错误。 它需要 .NET Framework 3.5 SP1。TargetNullValue 和 FallbackValue 是 Binding 类的新增内容

【讨论】:

谢谢,你说得对,但我的真实情况更复杂;我将更新我最初的问题以使其清楚。【参考方案3】:

如果您使用 .NET framework 3.5 或更高版本,您可以使用 targetnullValue 在此示例中,如果您创建了名为 BackgroundProperty 的依赖属性,则可以在绑定声明中使用 targetNullvalue。 在这种情况下,我从 ResourcesDictionary 传递颜色。

  <Style x:Key="LabelAxisNameStyle" TargetType="x:Type Label">
            <Setter Property="Background">
                <Setter.Value>
                    <Binding Path="BackgroundProperty" TargetNullValue="StaticResource LabelTitleBrush"/>
                </Setter.Value>
            </Setter>
        </Style>            

【讨论】:

以上是关于由于空值而无法评估绑定时使用默认值的主要内容,如果未能解决你的问题,请参考以下文章

WPF——TargetNullValue(如何在绑定空值显示默认字符)

如何设置TextBox空字符串的默认值而不是null

设计时 XAML 的默认值

用 phpunit 模拟 symfony 安全,返回空值而不是布尔值(不使用预言)

在grails中解析JSON时如何获取真正的空值而不是JSONObject.NULL值

当未设置可选字段时,大象鸟库生成字段的默认值而不是 null