当量。在XAML绑定中的Coalesce()?

时间:2011-08-04 19:51:58

标签: wpf xaml data-binding coalesce targetnullvalue

在SQL中我可以这样做:

Select Coalesce(Property1, Property2, Property3, 'All Null') as Value
From MyTable 

如果Property1,2和3都为null,那么我得到'All Null'

我如何在XAML中执行此操作?我试过以下,但没有运气:

<Window.Resources>
    <local:Item x:Key="MyData" 
                Property1="{x:Null}"
                Property2="{x:Null}"
                Property3="Hello World" />
</Window.Resources>

<TextBlock DataContext="{StaticResource MyData}">
    <TextBlock.Text>
        <PriorityBinding TargetNullValue="All Null">
            <Binding Path="Property1" />
            <Binding Path="Property2" />
            <Binding Path="Property3" />
        </PriorityBinding>
    </TextBlock.Text>
</TextBlock>

结果应该是'Hello World',而是'All Null'

我希望我的问题很明确。

3 个答案:

答案 0 :(得分:9)

您必须构建自定义IMultiValueConverter才能执行此操作并使用MultiBinding。 PriorityBinding使用集合中的第一个绑定成功生成值。在您的情况下,Property1绑定立即解析,因此使用它。由于Property1为null,因此使用TargetNullValue。

像这样的转换器:

public class CoalesceConverter : System.Windows.Data.IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, 
            object parameter, System.Globalization.CultureInfo culture)
    {
        if (values == null)
            return null;
        foreach (var item in values)
            if (item != null)
                return item;
        return null;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, 
            object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

和MultiBinding一样:

<Window.Resources>
    <local:Item x:Key="MyData" 
                Property1="{x:Null}"
                Property2="{x:Null}"
                Property3="Hello World" />
    <local:CoalesceConverter x:Key="MyConverter" />
</Window.Resources>

<TextBlock DataContext="{StaticResource MyData}">
    <TextBlock.Text>
        <MultiBinding Converter="{StaticResource MyConverter}">
            <Binding Path="Property1" />
            <Binding Path="Property2" />
            <Binding Path="Property3" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

答案 1 :(得分:3)

由于您绑定到String,因此null是PriorityBinding的有效值。我不确定您的Item类的属性类型是什么,但是如果您使用Object并将它们设置为DependencyProperty.UnsetValue,您将获得您正在寻找的行为。

PriorityBinding文档的备注部分更详细地介绍了它的工作原理。

答案 2 :(得分:0)

PriorityBinding仅查找DependencyProperty.UnsetValue前进到下一个Binding。由于Property1存在,因此已设置,PriorityBinding正在取值。

对于纯XAML解决方案,此Style将完成此任务:

   <TextBlock>
        <TextBlock.Style>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="Text"
                        Value="{Binding Property1}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Property1}"
                                 Value="{x:Null}">
                        <Setter Property="Text"
                                Value="{Binding Property2}" />
                    </DataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Property1}"
                                       Value="{x:Null}" />
                            <Condition Binding="{Binding Property2}"
                                       Value="{x:Null}" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Text"
                                Value="{Binding Property3}" />
                    </MultiDataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Property1}"
                                       Value="{x:Null}" />
                            <Condition Binding="{Binding Property2}"
                                       Value="{x:Null}" />
                            <Condition Binding="{Binding Property3}"
                                       Value="{x:Null}" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Text"
                                Value="All Null" />
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>

虽然,这有点令人费解,但恕我直言,不属于UI但属于ViewModel。