DataTrigger 的值不为空?

发布于 2024-07-09 10:15:29 字数 671 浏览 8 评论 0原文

我知道我可以创建一个 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”值...如“NOT NULL”或“NOT = 3”? 这在 XAML 中可能吗?

结果:感谢您的回答...我知道我可以做一个值转换器(这意味着我必须使用代码,而且这不会是我希望的纯 XAML)。 然而,这确实回答了一个问题:实际上“不”,你不能在纯 XAML 中做到这一点。 然而,所选的答案可能显示了创建此类功能的最佳方法。 很好的发现。

I know that I can make a setter that checks to see if a value is NULL and do something. Example:

<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?

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 create that kind of functionality. Good find.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

征﹌骨岁月お 2024-07-16 10:15:30

您可以为此使用 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 是否相等,因此您可以检查任何内容,并且不只是空。

You can use an IValueConverter for this:

<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):

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.

饮惑 2024-07-16 10:15:30

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

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

DataTrigger 的这种限制可以在一定程度上解决,方法是使用转换器将数据转换为特殊值,然后可以进行比较,如 Robert Macnee 的答案中所建议的。

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.

This blog post describes how to do comparisons such as LT, GT, etc in a DataTrigger.

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.

情释 2024-07-16 10:15:30

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

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

与非 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>

Compare with null (As Michael Noonan said):

<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):

<Style>
    <Setter Property="Visibility" Value="Collapsed" />
    <Style.Triggers>
       <DataTrigger Binding="{Binding SomeProperty}" Value="{x:Null}">
           <Setter Property="Visibility" Value="Visible" />
        </DataTrigger>
     </Style.Triggers>
</Style>
仙女山的月亮 2024-07-16 10:15:30

我使用它仅在选择列表视图项(即不为空)时启用按钮:

<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>

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>
一口甜 2024-07-16 10:15:30

您可以使用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>

使用此方法,您也可以针对 GreaterThanLessThan 触发。
为了使用此代码,您应该引用两个 dll:

System.Windows.Interactivity.dll

Microsoft.Expression.Interactions.dll

You can use DataTrigger class in Microsoft.Expression.Interactions.dll that come with 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:

System.Windows.Interactivity.dll

Microsoft.Expression.Interactions.dll

眼中杀气 2024-07-16 10:15:30

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

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.

So with this library : https://github.com/Alex141/CalcBinding

you can do that [and a lot more] :

First, In the declaration of the 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].

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).

柠檬色的秋千 2024-07-16 10:15:30
<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>

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

<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!

她说她爱他 2024-07-16 10:15:30

我的解决方案是在 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>

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.

    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 Binding="{Binding IsSomeFieldNull}" Value="False">
      <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" />
    </DataTrigger>
风柔一江水 2024-07-16 10:15:30

如果您正在寻找不使用 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>

If you are looking for a solution that does not use IValueConverter, you can always go with below mechanism

       <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>
东京女 2024-07-16 10:15:30

转换器:

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}}"

Converter:

public class NullableToVisibilityConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Collapsed : Visibility.Visible;
    }
}

Binding:

Visibility="{Binding PropertyToBind, Converter={StaticResource nullableToVisibilityConverter}}"
空气里的味道 2024-07-16 10:15:30

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

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

并使用它:

<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">

You can use a converter or create new property in your ViewModel like that:

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

and use it:

<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
橙幽之幻 2024-07-16 10:15:29

这有点作弊,但我只是设置了一个默认样式,然后如果该值为 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>

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...

  <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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文