6

在 SQL 中,我可以这样做:

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

如果 Property1、2 和 3 都为空,那么我会得到 '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”

我希望我的问题很清楚。

4

3 回答 3

10

您必须构建一个自定义IMultiValueConverter来执行此操作并使用 MultiBinding。PriorityBinding使用集合中成功生成值的第一个绑定。在您的情况下, Property1 绑定立即解析,因此使用它。由于 Property1 为空,因此使用 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>
于 2011-08-04T19:55:54.737 回答
3

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

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

于 2011-08-04T20:02:48.360 回答
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。

于 2011-08-04T20:32:06.347 回答