178

我知道我可以创建一个 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>

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

结果:感谢您的回答...我知道我可以做一个值转换器(这意味着我必须编写代码,而这不会是我希望的纯 XAML)。但是,这确实回答了您不能在纯 XAML 中有效地“不”执行此操作的问题。然而,选择的答案可能显示了创建这种功能的最佳方式。很好的发现。

4

12 回答 12

175

这有点作弊,但我只是设置了默认样式,然后如果值为空,则使用 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>
于 2009-02-27T02:12:11.320 回答
163

您可以为此使用 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.");
    }
}

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

于 2008-12-10T16:35:23.453 回答
41

我在使用 DataTriggers 时遇到了类似的限制,看来您只能检查是否相等。我见过的可能对您有所帮助的最接近的事情是一种用于进行除相等以外的其他类型比较的技术。

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

正如 Robert Macnee 的回答中所建议的那样,DataTrigger 的这种限制可以在某种程度上通过使用 Converter 将数据按摩成一个特殊的值来解决,然后您可以进行比较。

于 2008-12-10T16:33:25.220 回答
32

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

<Style>
    <Style.Triggers>
       <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
           <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
     </Style.Triggers>
</Style>

与 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>
于 2012-05-09T14:21:30.783 回答
17

如果选择了列表视图项(即不为空),我只使用它来启用按钮:

<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>
于 2011-09-02T01:08:01.057 回答
15

您可以使用Expression Blend附带的Microsoft.Expression.Interactions.dllDataTrigger中的类。

代码示例:

<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

于 2013-04-23T10:52:49.577 回答
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>

我只是在这里使用了逆逻辑......当我的组合项没有填充时,将我的堆栈面板设置为不可见,它工作得很好!

于 2013-08-30T20:47:22.673 回答
6

停止!没有转换器!我不想“出售”这个人的库,但我讨厌每次我想比较 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 即可)。

于 2015-12-09T13:57:53.510 回答
5

我的解决方案在 DataContext 实例中(如果使用 MVVM,则为 ViewModel)。如果满足我想要的 Not Null 条件,我添加一个返回 true 的属性。

    Public ReadOnly Property IsSomeFieldNull() As Boolean
        Get
            Return If(SomeField is Null, True, False)
        End Get
    End Property

并将 DataTrigger 绑定到上述属性。注意:在 VB.NET 中,请务必使用运算符 If 而不是 IIf 函数,该函数不适用于 Null 对象。那么 XAML 是:

    <DataTrigger Binding="{Binding IsSomeFieldNull}" Value="False">
      <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" />
    </DataTrigger>
于 2012-03-10T09:01:10.297 回答
3

如果您正在寻找不使用 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>
于 2016-06-10T10:33:30.207 回答
2

转换器:

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}}"
于 2012-05-10T12:35:18.993 回答
2

您可以使用转换器或在 ViewModel 中创建新属性,如下所示:

public bool CanDoIt
{
    get
    {
        return !string.IsNullOrEmpty(SomeField);
    }
}

并使用它:

<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
于 2016-02-26T10:49:29.297 回答