DataTrigger的值是否为null?

Tim*_*uri 150 wpf xaml binding visibility datatrigger

我知道我可以创建一个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>
Run Code Online (Sandbox Code Playgroud)

但是如何检查"非"值...如"NOT NULL"或"NOT = 3"?这可能在XAML中吗?

结果:感谢您的回答......我知道我可以做一个值转换器(这意味着我必须使用代码,这不是我希望的纯XAML).但是,这确实回答了在纯XAML中有效"不"你无法做到的问题.但是,选择的答案可能是创建这种功能的最佳方式.很好找.

Rob*_*nee 143

您可以使用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>
Run Code Online (Sandbox Code Playgroud)

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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

更通用的解决方案是实现一个IValueConverter,它检查与ConverterParameter的相等性,因此您可以检查任何内容,而不仅仅是null.

  • 我想你可以使转换器更通用,并使用ConverterParameter传入一个值进行比较(为了支持比较NOT null和NOT 3. (6认同)

小智 138

这有点作弊,但我只是设置了默认样式,然后使用DataTrigger覆盖它,如果值为null ...

  <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>
Run Code Online (Sandbox Code Playgroud)

  • 我不认为这是一个黑客,你需要做很多时间; 这是最干净的方法. (11认同)
  • 默认Setter可以在没有Style.Setter标记的情况下使用. (3认同)
  • 方式更好的答案然后使用转换器......简单而干净. (2认同)
  • 如果默认样式/属性依赖于不为空的数据,这可能会在输出窗口中出现绑定错误... (2认同)

J c*_*J c 39

我遇到了与DataTriggers类似的限制,看起来你只能检查是否相等.我见过的最接近你可能会帮助你的是一种除了平等之外进行其他类型比较的技巧.

这篇博文描述了如何在DataTrigger中进行比较,如LT,GT等.

DataTrigger的这种限制可以在某种程度上解决,通过使用转换器将数据按到一个特殊的值,然后你可以比较,如罗伯特麦金尼的答案所示.

  • 有趣的是,DataTrigger实际上有一个内部字段来控制它是否测试是否相等.不幸的是,您必须进行合理的反射才能到达所需的字段.问题是它可能会破坏.net的下一个版本. (9认同)

Joa*_*Fdz 22

与null比较(正如Michael Noonan所说):

<Style>
    <Style.Triggers>
       <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
           <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
     </Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)

与非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>
Run Code Online (Sandbox Code Playgroud)

  • 这是迄今为止最直接的答案.我喜欢! (3认同)

Ste*_*Cav 14

如果选择了listview项(即非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>
Run Code Online (Sandbox Code Playgroud)

  • 有时最简单的解决方案隐藏在清晰的视图中.我相信,XAML代码是从上到下解释的.这样,如果未选择列表视图中的元素,则首先启用该按钮,然后禁用该按钮.但请告诉我,一旦在列表视图中选择了一个项目,样式是否会更新? (3认同)

yos*_*rel 14

您可以使用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>
Run Code Online (Sandbox Code Playgroud)

使用这种方法,你可以触发打击GreaterThanLessThan太.要使用此代码,您应该引用两个dll:

System.Windows.Interactivity.dll

Microsoft.Expression.Interactions.dll


aro*_*ore 6

<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>
Run Code Online (Sandbox Code Playgroud)

我刚刚在这里使用了逆逻辑...当我的comboitem没有填充时,将我的stackpanel设置为隐形,它运行得很好!


小智 5

我的解决方案是在DataContext实例中(如果使用MVVM,则在ViewModel中)。如果满足所需的“非空”条件,我添加了一个返回true的属性。

    Public ReadOnly Property IsSomeFieldNull() As Boolean
        Get
            Return If(SomeField is Null, True, False)
        End Get
    End Property
Run Code Online (Sandbox Code Playgroud)

并将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>
Run Code Online (Sandbox Code Playgroud)


Sim*_*mon 5

停止!没有转换器!我不想"卖"这个人的库,但我讨厌每次我想在XAML中比较东西时做转换器的事实.

所以使用这个库:https://github.com/Alex141/CalcBinding

你可以做到[还有更多]:

首先,在windows/userControl的声明中:

<Windows....
     xmlns:conv="clr-namespace:CalcBinding;assembly=CalcBinding"
>
Run Code Online (Sandbox Code Playgroud)

然后,在文本块中

<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>
Run Code Online (Sandbox Code Playgroud)

神奇的部分是conv:Binding'MYValue == null'.事实上,您可以设置您想要的任何条件[查看文档].

请注意,我不是第三方的粉丝.但这个库是免费的,影响不大(只需在项目中添加2个.dll).