値がnullではないDataTrigger?


162

値が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」のように、「not」値を確認するにはどうすればよいですか?XAMLでそれは可能ですか?

結果:回答をありがとう...値コンバーターを実行できることはわかっていました(つまり、コードで実行する必要があり、期待どおりの純粋なXAMLではありません)。ただし、これは、純粋なXAMLでは効果的に "いいえ"を実行できないという質問に答えるものです。ただし、選択した答えは、おそらくそのような機能を作成するための最良の方法を示しています。良い発見。

回答:


42

私はDataTriggersで同様の制限に遭遇しましたが、同等かどうかしかチェックできないようです。私が見た中であなたに役立つかもしれない最も近いものは、等式以外の他のタイプの比較を行うための手法です。

このブログ投稿では、DataTriggerでLT、GTなどの比較を行う方法について説明します。

このDataTriggerの制限は、Robert Macneeの回答で提案されているように、コンバーターを使用してデータを比較できる特別な値にデータをマッサージすることである程度回避できます。


10
興味深いことに、DataTriggerには実際に、等しいかどうかをテストするかどうかを制御する内部フィールドがあります。残念ながら、必要なフィールドに到達するには、適度な量の反射を行わなければなりません。問題は、次のバージョンの.netで壊れる可能性があることです。
Caleb Vear、2009

154

これには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.");
    }
}

より一般的な解決策は、ConverterParameterとの同等性をチェックするIValueConverterを実装することです。これにより、nullだけでなく、何でもチェックできます。


6
コンバーターをもう少し汎用的にし、ConverterParameterを使用して比較する値を渡すことができると思います(NOT nullとNOT 3の両方の比較をサポートするために
J c

これは私にとってはうまくいきました-マルチトリガーを使用すると、それは素晴らしいと強力になります。
バーティ2015

149

これはちょっとしたチートですが、デフォルトのスタイルを設定し、値が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>

1
これは私のシナリオに最適なソリューションでした!この答えを提供してくれてありがとう!
スコット

14
これはハックではないと思います。これは何度も行う必要があります。これはこれを行う最もクリーンな方法です。
akjoshi

3
デフォルトのセッターは、Style.Setterタグなしで使用できます。
Naser Asadi 2013

1
チケットだけ!私はデフォルトをスタイルを所有するコントロールに入れ続けました、そしてそれがなぜ私のスタイルを上書きし続けるのか理解できませんでした:-)ありがとうございます!
Heliac 2014年

2
コンバーターを使用するよりも答えがはるかに良い...シンプルでクリーン。
DasDas

27

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>

4
これは、最も簡単な答えです。私はそれが好きです!
TimothyP 2014

15

これを使用して、リストビュー項目が選択されている(つまり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>

4
場合によっては、最も単純な解決策がはっきりと見えないところに隠れています。XAMLコードは上から下に解釈されると思います。これにより、リストビューの要素が選択されていない場合、ボタンが最初に有効になり、次に無効になります。しかし教えてください、リストビューでアイテムが選択されるとスタイルは更新されますか?
froeschli

ボタンは、リスト項目が選択されたときに有効になります(はい)。
SteveCav

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>

この方法を使用するとGreaterThan、トリガーすることLessThanもできます。このコードを使用するには、2つのDLLを参照する必要があります。

System.Windows.Interactivity.dll

Microsoft.Expression.Interactions.dll


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>

ここで逆ロジックを使用しただけです...私のコンボアイテムが入力されていないときにスタックパネルを非表示に設定すると、かなりうまくいきます!


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を追加するだけです)。


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では、Nullオブジェクトでは機能しないIIf関数ではなく、演算子Ifを必ず使用してください。次に、XAMLは次のとおりです。

    <DataTrigger Binding="{Binding IsSomeFieldNull}" Value="False">
      <Setter Property="TextBlock.Text" Value="It's NOT NULL Baby!" />
    </DataTrigger>

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>

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

2

コンバーターを使用するか、次のようにViewModelで新しいプロパティを作成できます。

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

そしてそれを使う:

<DataTrigger Binding="{Binding SomeField}" Value="{Binding CanDoIt}">
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.