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

发布于 2024-10-04 04:40:06 字数 3192 浏览 2 评论 0原文

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

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

{Binding CurrentCustomer.Name}

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

“TargetNullValue”和“FallbackValue”似乎不起作用。

预先感谢您的帮助。

编辑

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

布尔值用于确定控件的可见性,但是当无法获得该值时,我想将其替换为“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 的第二个解决方案,即包装在另一个元素中,运行得很好。

is there a way to assign a special value when a binding cannot be evaluated because of a null value in the property path ?

For instance if I have a property Name in a class Customer and a binding like this :

{Binding CurrentCustomer.Name}

When CurrentCustomer is null I'd like the binding to produce the string "---".

"TargetNullValue" and "FallbackValue" don't seem to do the trick.

Thanks in advance for your help.

EDIT :

In fact what I'm trying to do is substituting a new source value in place of the true when it is not available.
The real scenario is the following :

a bool value is used to determine the visibility of a control, but when this value is not attainable I'd like to replace it with "false".

Here is an illustration that perfectly mimics my real use-case :

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 is not the solution because it would only change the generated value and not the source value.

Abe Heidebrecht has provided the perfect solution for WPF with PriorityBinding but it does not exist in Silverlight.

FINAL EDIT :
The second solution of Abe Heidebrecht, ie wrapping in another element, is working perfectly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青萝楚歌 2024-10-11 04:40:06

您可以使用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>

You could use a PriorityBinding:

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

Okay, for Silverlight it is a probably easier to wrap the element in a wrapper (like a Border). You then have an IValueConverter to convert null to Visibility.Collapsed, and anything else to 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();
    }
}

And use it like so:

<Border Visibility="{Binding CurrentCustomer, Converter={StaticResource NullToVisibilityConverter}}">
    <TextBlock Text="You have a car"  Visibility="{Binding CurrentCustomer.HasACar,Converter={StaticResource boolToVisibilityConverter}}" />
</Border>
九歌凝 2024-10-11 04:40:06

嘿 TargetNullValue 和 FallbackValue 有效。可能是您使用的.NET版本错误。

需要 .NET Framework 3.5 SP1。TargetNullValue 和 FallbackValue 是 Binding 类的新增内容

Hey TargetNullValue and FallbackValue works. May be the version of .NET you are using is wrong.

It requires .NET Framework 3.5 SP1.TargetNullValue and FallbackValue is a new addition to the Binding class

烈酒灼喉 2024-10-11 04:40:06

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

if you use .NET framework 3.5 or higher you can use targetnullValue
In this example if you have created the dependency property called BackgroundProperty you can use targetNullvalue in binding declaration.
In this case I pass the color from ResourcesDictionary.

  <Style x:Key="LabelAxisNameStyle" TargetType="{x:Type Label}">
            <Setter Property="Background">
                <Setter.Value>
                    <Binding Path="BackgroundProperty" TargetNullValue="{StaticResource LabelTitleBrush}"/>
                </Setter.Value>
            </Setter>
        </Style>            
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文