wpf DataTrigger 其中值不为空?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/356194/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
DataTrigger where value is NOT null?
提问by Timothy Khouri
I know that I can make a setter that checks to see if a value is NULL and do something. Example:
我知道我可以创建一个 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>
But how can I check for a "not" value... as in "NOT NULL", or "NOT = 3"? Is that possible in XAML?
但是如何检查“非”值……如“NOT NULL”或“NOT = 3”?这在 XAML 中可能吗?
Results:Thanks for your answers... I knew I could do a value converter (which means I would have to go in code, and that would not be pure XAML as I hoped for). However, that does answer the question that effectively "no" you can't do it in pure XAML. The answer selected, however, shows probably the best way to createthat kind of functionality. Good find.
结果:感谢您的回答...我知道我可以做一个值转换器(这意味着我必须编写代码,这不会是我希望的纯 XAML)。但是,这确实回答了“不”您不能在纯 XAML 中做到这一点的问题。然而,所选择的答案可能显示了创建这种功能的最佳方式。好找。
采纳答案by J c
I ran into a similar limitation with DataTriggers, and it would seem that you can only check for equality. The closest thing I've seen that might help you is a technique for doing other types of comparisons other than equality.
我在使用 DataTriggers 时遇到了类似的限制,看起来您只能检查相等性。我见过的最接近的可能对您有帮助的方法是进行除相等之外的其他类型比较的技术。
This blog postdescribes how to do comparisons such as LT, GT, etc in a DataTrigger.
这篇博文描述了如何在 DataTrigger 中进行 LT、GT 等比较。
This limitation of the DataTrigger can be worked around to some extent by using a Converter to massage the data into a special value you can then compare against, as suggested in Robert Macnee's answer.
DataTrigger 的这种限制可以在一定程度上解决,方法是使用 Converter 将数据转换为一个特殊值,然后您可以进行比较,如 Robert Macnee 的回答中所建议的那样。
回答by Robert Macnee
You can use an IValueConverter for this:
您可以为此使用 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>
Where IsNullConverter is defined elsewhere (and conv is set to reference its namespace):
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.");
}
}
A more general solution would be to implement an IValueConverter that checks for equality with the ConverterParameter, so you can check against anything, and not just null.
更通用的解决方案是实现一个 IValueConverter 来检查与 ConverterParameter 的相等性,因此您可以检查任何内容,而不仅仅是 null。
回答by Robert Macnee
This is a bit of a cheat but I just set a default style and then overrode it using a DataTrigger if the value is null...
这有点作弊,但我只是设置了默认样式,然后如果值为空,则使用 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>
回答by JoanComasFdz
Compare with null (As Michael Noonan said):
与 null 比较(正如 Michael Noonan 所说):
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
Compare with not null (without a converter):
与 not null 比较(没有转换器):
<Style>
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
回答by SteveCav
I'm using this to only enable a button if a listview item is selected (ie not null):
如果选择了列表视图项(即不为空),我将使用它来仅启用按钮:
<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>
回答by yossharel
You can use DataTrigger
class in Microsoft.Expression.Interactions.dllthat come with Expression Blend.
您可以DataTrigger
在Microsoft.Expression.Interactions.dll中使用Expression Blend附带的类。
Code Sample:
代码示例:
<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>
Using this method you can trigger against GreaterThan
and LessThan
too.
In order to use this code you should reference two dll's:
使用此方法,您也可以触发反对GreaterThan
和LessThan
。为了使用此代码,您应该引用两个 dll:
System.Windows.Interactivity.dll
Microsoft.Expression.Interactions.dll
系统.Windows.Interactivity.dll
Microsoft.Expression.Interactions.dll
回答by aromore
<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>
I just used the inverse logic here...setting my stackpanel to invisible when my comboitem is not populated, it works pretty well!
我只是在这里使用了逆逻辑......当我的组合项没有填充时,将我的堆栈面板设置为不可见,它工作得很好!
回答by Simon
Stop! No converter! I dont want to "sell" the library of this guy, but I hated the fact of doing converter everytime I wanted to compare stuff in XAML.
停止!没有转换器!我不想“出售”这个人的库,但我讨厌每次我想比较 XAML 中的东西时都做转换器的事实。
So with this library : https://github.com/Alex141/CalcBinding
所以有了这个库:https: //github.com/Alex141/CalcBinding
you can do that [and a lot more] :
你可以做到[以及更多]:
First, In the declaration of the windows/userControl :
首先,在 windows/userControl 的声明中:
<Windows....
xmlns:conv="clr-namespace:CalcBinding;assembly=CalcBinding"
>
then, in the textblock
然后,在文本块中
<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>
The magic part is the conv:Binding 'MYValue==null'. In fact, you could set any condition you wanted [look at the doc].
神奇的部分是conv:Binding 'MYValue==null'。事实上,你可以设置任何你想要的条件 [查看文档]。
note that I am not a fan of third party. but this library is Free, and little impact (just add 2 .dll to the project).
请注意,我不是第三方的粉丝。但是这个库是免费的,影响很小(只需在项目中添加 2 个 .dll)。
回答by APaglia
My solution is in the DataContext instance (or ViewModel if using MVVM). I add a property that returns true if the Not Null condition I want is met.
我的解决方案是在 DataContext 实例中(如果使用 MVVM,则在 ViewModel 中)。如果满足我想要的 Not Null 条件,我添加了一个返回 true 的属性。
Public ReadOnly Property IsSomeFieldNull() As Boolean
Get
Return If(SomeField is Null, True, False)
End Get
End Property
and bind the DataTrigger to the above property. Note: In VB.NET be sure to use the operator If and NOT the IIf function, which doesn't work with Null objects. Then the XAML is:
并将 DataTrigger 绑定到上述属性。注意:在 VB.NET 中,一定要使用操作符 If 而不是 IIf 函数,它不适用于 Null 对象。那么 XAML 是:
<DataTrigger Binding="{Binding IsSomeFieldNull}" Value="False">
<Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" />
</DataTrigger>
回答by Chaitanya Kadamati
If you are looking for a solution that does not use IValueConverter, you can always go with below mechanism
如果您正在寻找不使用 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>