DataTrigger的值不为空?
我知道我可以创build一个setter来检查一个值是否为NULL,并执行一些操作。 例:
<TextBlock> <TextBlock.Style> <Style> <Style.Triggers> <DataTrigger Binding="{Binding SomeField}" Value="{x:Null}"> <Setter Property="TextBlock.Text" Value="It's NULL Baby!" /> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock>
但是,我怎么能检查一个“不”的价值…如“非空”或“不= 3”? 在XAML中可能吗?
结果:谢谢你的回答…我知道我可以做一个值转换器(这意味着我将不得不在代码中,这不会是我所希望的纯XAML)。 但是,这确实回答了有效的“否”你不能在纯XAML中做的问题。 然而,select的答案显示了创build这种function的最好方法。 很好找。
我遇到了与DataTriggers类似的限制,似乎只能检查平等。 我所见过的最接近的东西可能会帮助你做其他types的比较,而不是平等的技术。
这篇博客文章介绍了如何在DataTrigger中比较LT,GT等。
DataTrigger的这种限制可以在一定程度上通过使用Converter将数据按摩到一个特殊的值,然后可以与之比较,如Robert Macnee的答案中所build议的那样。
你可以使用一个IValueConverter来达到这个目的:
<TextBlock> <TextBlock.Resources> <conv:IsNullConverter x:Key="isNullConverter"/> </TextBlock.Resources> <TextBlock.Style> <Style> <Style.Triggers> <DataTrigger Binding="{Binding SomeField, Converter={StaticResource isNullConverter}}" Value="False"> <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!"/> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock>
IsNullConverter在其他地方定义(并且conv被设置为引用其名称空间):
public class IsNullConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (value == null); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new InvalidOperationException("IsNullConverter can only be used OneWay."); } }
一个更一般的解决scheme是实现一个IValueConverter,它检查与ConverterParameter是否相等,所以你可以检查任何东西,而不是空。
这是一个骗子,但我只是设置一个默认的样式,然后覆盖它使用DataTrigger如果值为空…
<Style> <!-- Highlight for Reviewed (Default) --> <Setter Property="Control.Background" Value="PaleGreen" /> <Style.Triggers> <!-- Highlight for Not Reviewed --> <DataTrigger Binding="{Binding Path=REVIEWEDBY}" Value="{x:Null}"> <Setter Property="Control.Background" Value="LightIndianRed" /> </DataTrigger> </Style.Triggers> </Style>
比较null(正如Michael Noonan所说):
<Style> <Style.Triggers> <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}"> <Setter Property="Visibility" Value="Collapsed" /> </DataTrigger> </Style.Triggers> </Style>
与非空(不带转换器)比较:
<Style> <Setter Property="Visibility" Value="Collapsed" /> <Style.Triggers> <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}"> <Setter Property="Visibility" Value="Visible" /> </DataTrigger> </Style.Triggers> </Style>
我正在使用这个来只启用一个button,如果列表视图项被选中(即非空):
<Style TargetType="{x:Type Button}"> <Setter Property="IsEnabled" Value="True"/> <Style.Triggers> <DataTrigger Binding="{Binding ElementName=lvMyList, Path=SelectedItem}" Value="{x:Null}"> <Setter Property="IsEnabled" Value="False"/> </DataTrigger> </Style.Triggers> </Style>
您可以使用Expression Blend附带的Microsoft.Expression.Interactions.dll中的DataTrigger
类。
代码示例:
<i:Interaction.Triggers> <i:DataTrigger Binding="{Binding YourProperty}" Value="{x:Null}" Comparison="NotEqual"> <ie:ChangePropertyAction PropertyName="YourTargetPropertyName" Value="{Binding YourValue}"/> </i:DataTrigger </i:Interaction.Triggers>
使用这种方法,您可以触发GreaterThan
和LessThan
。 为了使用这个代码,你应该引用两个DLL的:
System.Windows.Interactivity.dll
Microsoft.Expression.Interactions.dll
<StackPanel.Style> <Style> <Setter Property="StackPanel.Visibility" Value="Visible"></Setter> <Style.Triggers> <DataTrigger Binding="{Binding ElementName=ProfileSelectorComboBox, Path=SelectedItem.Tag}" Value="{x:Null}"> <Setter Property="StackPanel.Visibility" Value="Collapsed"></Setter> </DataTrigger> </Style.Triggers> </Style> </StackPanel.Style>
我只是在这里使用了相反的逻辑…当我的comboitem没有填充时,设置我的堆栈面板不可见,它工作得很好!
停止! 没有转换器! 我不想“卖”这个家伙的图书馆,但我讨厌做转换器的事实,每次我想比较XAML的东西。
所以这个库: https : //github.com/Alex141/CalcBinding
你可以做到这一点[和更多]:
首先,在windows / userControl的声明中:
<Windows.... xmlns:conv="clr-namespace:CalcBinding;assembly=CalcBinding" >
然后,在文本块中
<TextBlock> <TextBlock.Style> <Style.Triggers> <DataTrigger Binding="{conv:Binding 'MyValue==null'}" Value="false"> <Setter Property="Background" Value="#FF80C983"></Setter> </DataTrigger> </Style.Triggers> </TextBlock.Style> </TextBlock>
魔术部分是conv:Binding'MYValue == null' 。 事实上,你可以设置你想要的任何条件[看看文档]。
请注意,我不是第三方的粉丝。 但是这个库是免费的,影响不大(只需要添加2个DLL到项目中)。
我的解决scheme是在DataContext实例(如果使用MVVM,则为ViewModel)。 我添加一个属性返回true,如果我想要的不空条件满足。
Public ReadOnly Property IsSomeFieldNull() As Boolean Get Return If(SomeField is Null, True, False) End Get End Property
并将DataTrigger绑定到上述属性。 注意:在VB.NET中,一定要使用运算符If和NOT IIf函数,它不适用于Null对象。 那么XAML是:
<DataTrigger Binding="{Binding IsSomeFieldNull}" Value="False"> <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" /> </DataTrigger>
转换器:
public class NullableToVisibilityConverter: IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value == null ? Visibility.Collapsed : Visibility.Visible; } }
捆绑:
Visibility="{Binding PropertyToBind, Converter={StaticResource nullableToVisibilityConverter}}"
您可以使用转换器或在您的ViewModel中创build新的属性:
public bool CanDoIt { get { return !string.IsNullOrEmpty(SomeField); } }
并使用它:
<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
如果你正在寻找一个不使用IValueConverter的解决scheme,你可以随时使用下面的机制
<StackPanel> <TextBlock Text="Border = Red when null value" /> <Border x:Name="border_objectForNullValueTrigger" HorizontalAlignment="Stretch" Height="20"> <Border.Style> <Style TargetType="Border"> <Setter Property="Background" Value="Black" /> <Style.Triggers> <DataTrigger Binding="{Binding ObjectForNullValueTrigger}" Value="{x:Null}"> <Setter Property="Background" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </Border.Style> </Border> <TextBlock Text="Border = Green when not null value" /> <Border HorizontalAlignment="Stretch" Height="20"> <Border.Style> <Style TargetType="Border"> <Setter Property="Background" Value="Green" /> <Style.Triggers> <DataTrigger Binding="{Binding Background, ElementName=border_objectForNullValueTrigger}" Value="Red"> <Setter Property="Background" Value="Black" /> </DataTrigger> </Style.Triggers> </Style> </Border.Style> </Border> <Button Content="Invert Object state" Click="Button_Click_1"/> </StackPanel>