Wpf 值不为null的DataTrigger?
我知道我可以做一个setter,检查一个值是否为NULL,然后做一些事情。例如:Wpf 值不为null的DataTrigger?,wpf,xaml,binding,visibility,datatrigger,Wpf,Xaml,Binding,Visibility,Datatrigger,我知道我可以做一个setter,检查一个值是否为NULL,然后做一些事情。例如: <TextBlock> <TextBlock.Style> <Style> <Style.Triggers> <DataTrigger Binding="{Binding SomeField}" Value="{x:Null}"> <Setter Property="TextBlock.Te
<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>
但是我如何检查“not”值。。。如“NOT NULL”或“NOT=3”?这在XAML中可能吗
结果:感谢您的回答。。。我知道我可以做一个值转换器(这意味着我必须使用代码,而这并不是我所希望的纯XAML)。然而,这确实回答了一个问题,即在纯XAML中不能有效地做到“不”。然而,选择的答案可能显示了创建此类功能的最佳方式。很好的发现。我在DataTriggers上遇到了类似的限制,似乎您只能检查是否相等。我所见过的最有可能帮助你的东西是一种做其他类型比较的技巧,而不是平等 描述如何在DataTrigger中进行比较,如LT、GT等
如Robert Macnee的回答所示,通过使用转换器将数据转换成一个特殊值,然后与之进行比较,可以在一定程度上解决DataTrigger的这一限制。您可以使用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>
一个更通用的解决方案是实现一个检查与ConverterParameter是否相等的IValueConverter,这样您就可以检查任何内容,而不仅仅是空值。这有点欺骗,但我只是设置了一个默认样式,然后在值为空时使用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>
我使用此选项仅在选择listview项(即非空)时启用按钮:
我的解决方案位于DataContext实例中(如果使用MVVM,则为ViewModel)。我添加了一个属性,如果满足我想要的NOTNULL条件,该属性将返回true
Public ReadOnly Property IsSomeFieldNull() As Boolean
Get
Return If(SomeField is Null, True, False)
End Get
End Property
并将DataTrigger绑定到上述属性。
注意:在VB.NET中,请确保使用运算符If而不是IIf函数,该函数不适用于空对象。
那么XAML是:
<DataTrigger Binding="{Binding IsSomeFieldNull}" Value="False">
<Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" />
</DataTrigger>
与null比较(正如Michael Noonan所说):
与非空比较(不带转换器):
转换器:
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}}"
您可以在Microsoft.Expression.Interactions.dll中使用Expression Blend附带的
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>
我只是在这里使用了相反的逻辑…当我的comboitem未填充时,将stackpanel设置为不可见,效果非常好 住手!没有转换器!我不想“出售”这个家伙的库,但我讨厌每次我想在XAML中比较东西时都使用converter
因此,对于这个库:
你可以做到这一点[还有更多]:
首先,在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添加到项目中即可)。您可以使用转换器或在ViewModel中创建新属性,如下所示:
public bool CanDoIt
{
get
{
return !string.IsNullOrEmpty(SomeField);
}
}
并使用它:
<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
如果您正在寻找不使用IValueConverter的解决方案,则始终可以使用以下机制
<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>
我想您可以让转换器更通用一些,并使用ConverterParameter传入一个值进行比较(为了同时支持比较非空和非3。这对我来说是一件好事——使用多重触发器,它使它变得漂亮和强大。有趣的是,DataTrigger实际上有一个内部字段,它控制着它是否测试相等。不幸的是,你必须进行合理的反射才能到达e必填字段。问题是它可能会在下一版本的.net中中断。这是我的方案的最佳解决方案!感谢您提供此答案!我不认为这是一个黑客行为,您需要花费大量时间来完成此操作;这是最干净的方法。默认Setter可以在没有样式的情况下使用。Setter标记。way更好的答案是使用converter…简单且干净。如果默认样式/属性依赖于数据,则输出窗口中可能会出现绑定错误。有时,最简单的解决方案隐藏在clear view中。我相信,XAML代码是从上到下解释的。这样,如果li中没有元素,按钮将首先启用,然后禁用选择了stview。但是请告诉我,一旦在listview中选择了一个项目,样式是否会更新?当选择了一个列表项目时,按钮将启用,是的。这是迄今为止最直接的答案。我喜欢它!
<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>
public bool CanDoIt
{
get
{
return !string.IsNullOrEmpty(SomeField);
}
}
<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
<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>