data - wpf trigger property null




DataTrigger wo Wert ist nicht null? (8)

Ich weiß, dass ich einen Setter machen kann, der überprüft, ob ein Wert NULL ist und etwas tut. Beispiel:

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

Aber wie kann ich nach einem "Nicht" Wert suchen ... wie in "NOT NULL" oder "NOT = 3"? Ist das in XAML möglich?

Ergebnisse: Vielen Dank für Ihre Antworten ... Ich wusste, dass ich einen Wertkonverter erstellen könnte (was bedeutet, dass ich in Code gehen müsste, und das wäre nicht reines XAML, wie ich es mir erhofft hatte). Dies beantwortet jedoch die Frage, dass effektiv "Nein" Sie es in reinem XAML nicht tun können. Die ausgewählte Antwort zeigt jedoch wahrscheinlich die beste Möglichkeit , diese Art von Funktionalität zu erstellen . Guter Fund.


Dies ist ein bisschen ein Cheat, aber ich habe nur einen Standard-Stil festgelegt und dann mit einem DataTrigger überschrieben, wenn der Wert null ist ...

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

Halt! Kein Konverter! Ich möchte die Bibliothek dieses Typen nicht "verkaufen", aber ich hasste die Tatsache, Konverter zu machen, immer wenn ich Sachen in XAML vergleichen wollte.

Also mit dieser Bibliothek: https://github.com/Alex141/CalcBinding

Du kannst das [und noch viel mehr] tun:

Zuerst in der Deklaration des windows / userControl:

<Windows....
     xmlns:conv="clr-namespace:CalcBinding;assembly=CalcBinding"
>

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

Der magische Teil ist der Conv: Binding 'MYValue == null' . In der Tat könnten Sie jede Bedingung setzen, die Sie wollten [siehe das Dokument].

Beachten Sie, dass ich kein Fan von Dritten bin. Aber diese Bibliothek ist kostenlos und hat wenig Auswirkungen (fügen Sie einfach 2. dll zum Projekt hinzu).


Ich bin mit DataTriggers auf eine ähnliche Einschränkung gestoßen, und es scheint, dass Sie nur nach Gleichheit suchen können. Die nächste Sache, die ich gesehen habe, die Ihnen helfen könnte, ist eine Technik für andere Arten von Vergleichen als Gleichheit.

In diesem Blogbeitrag wird beschrieben, wie Vergleiche wie LT, GT usw. in einem DataTrigger durchgeführt werden.

Diese Einschränkung des DataTriggers kann bis zu einem gewissen Grad umgangen werden, indem ein Konverter verwendet wird, um die Daten in einen speziellen Wert zu mahlen, mit dem Sie dann vergleichen können, wie in Robert Macnees Antwort vorgeschlagen.


Konverter:

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

Bindung:

Visibility="{Binding PropertyToBind, Converter={StaticResource nullableToVisibilityConverter}}"

Sie können dafür einen IValueConverter verwenden:

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

Wo IsNullConverter an anderer Stelle definiert ist (und conv auf seinen Namespace verweist):

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.");
    }
}

Eine allgemeinere Lösung wäre es, einen IValueConverter zu implementieren, der mit ConverterParameter auf Gleichheit prüft, so dass Sie gegen alles und nicht nur gegen null prüfen können.


Sie können die DataTrigger Klasse in Microsoft.Expression.Interactions.dll verwenden , die mit Expression Blend DataTrigger .

Codebeispiel:

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

Mit dieser Methode können Sie auch gegen GreaterThan und LessThan . Um diesen Code zu verwenden, sollten Sie auf zwei DLLs verweisen:

System.Windows.Interactivity.dll

Microsoft.Expression.Interaktionen.dll


Vergleiche mit null (wie Michael Noonan sagte):

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

Vergleichen Sie mit nicht null (ohne Konverter):

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

Wenn Sie nach einer Lösung suchen, die den IValueConverter nicht verwendet, können Sie immer mit dem unten genannten Mechanismus arbeiten

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