在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'
我希望我的问题很明确。
答案 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。