当绑定值为空时,使用默认值。

16

有没有一种方法,当属性路径中有null值导致无法评估绑定时,可以分配一个特殊值?

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

{Binding CurrentCustomer.Name}

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

“TargetNullValue” 和 “FallbackValue” 看起来无法解决这个问题。

非常感谢您的帮助。

编辑:

实际上,我试图在没有真实值可用时替换一个新的源值

真正的场景如下:

布尔值用于确定控件的可见性,但当此值不可获取时,我想将其替换为“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已经为WPF提供了完美的解决方案——PriorityBinding,但在Silverlight中不存在。

最终编辑:Abe Heidebrecht的第二个解决方案,即将内容包裹在另一个元素中,效果非常好。

3个回答

20

你可以使用PriorityBinding

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

如果是针对Silverlight,可以更容易地将元素包装在一个“Border”中。 然后,您需要使用 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}。谢谢! - Rachel
谢谢,如果我没有使用似乎不支持PriorityBinding的Silverlight 4,那么这将是有效的解决方案... - Pragmateek
1
我已经更新了答案,以反映如何在Silverlight中完成它。 - Abe Heidebrecht
再次感谢您的帮助,但是……Silverlight 4似乎也不支持DataTrigger!令人非常恼火的是,绑定和样式的支持尚未完全实现。如果没有其他干净的解决方案,我将标记您的答案为已接受。 - Pragmateek
1
哈哈,我是个白痴。我更新了它,现在它能够正常工作了。每次需要这种功能时都要这样做,真的很烦人。 - Abe Heidebrecht

13

嘿,TargetNullValue 和 FallbackValue 起作用了。也许您正在使用的 .NET 版本不正确。

它需要 .NET Framework 3.5 SP1。TargetNullValue 和 FallbackValue 是 Binding 类的新添加。


谢谢,你说得对,但我的实际情况更复杂;我会更新我的初始问题以使其更清晰。 - Pragmateek

0

如果您使用 .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>            

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