web-dev-qa-db-fra.com

Comment faire pour que DataTemplate.DataTrigger vérifie supérieur ou inférieur à?

Le suivant DataTemplate.DataTrigger fait apparaître l'âge en rouge s'il est égal à 30.

Comment puis-je faire apparaître l'âge en rouge s'il est supérieur à 30?

<DataTemplate DataType="{x:Type local:Customer}">
    <Grid x:Name="MainGrid" Style="{StaticResource customerGridMainStyle}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="150"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Column="0" Grid.Row="0" Text="First Name" Margin="5"/>
        <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding FirstName}" Margin="5"/>
        <TextBlock Grid.Column="0" Grid.Row="1" Text="Last Name" Margin="5"/>
        <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding LastName}" Margin="5"/>
        <TextBlock Grid.Column="0" Grid.Row="2" Text="Age" Margin="5"/>
        <TextBlock x:Name="Age" Grid.Column="1" Grid.Row="2" Text="{Binding Age}" Margin="5"/>
    </Grid>

    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Age}">
            <DataTrigger.Value>30</DataTrigger.Value>
            <Setter TargetName="Age" Property="Foreground" Value="Red"/> 
        </DataTrigger>
    </DataTemplate.Triggers>

</DataTemplate>
44
Edward Tanguay

Vous pouvez créer un IValueConverter, qui convertit un entier en booléen basé sur le CutOff. Utilisez ensuite DataTrigger.Value de True (ou False, selon ce que vous retournez).

WPF DataTriggers sont strictement des comparateurs d'égalité si je me souviens bien.

Donc quelque chose de similaire à:

public class CutoffConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        return ((int)value) > Cutoff;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }

    public int Cutoff { get; set; }
}

Utilisez ensuite le XAML suivant.

<Window.Resources>
    <myNamespace:CutoffConverter x:Key="AgeConverter" Cutoff="30" />
</Window.Resources>

<DataTemplate.Triggers>
    <DataTrigger Binding="{Binding Path=Age,
                                   Converter={StaticResource AgeConverter}}">
        <DataTrigger.Value>true</DataTrigger.Value>
        <Setter TargetName="Age" Property="Foreground" Value="Red"/> 
    </DataTrigger>
</DataTemplate.Triggers>
71
Mikko Rantanen

Je recommanderais d'utiliser un IValueConverter pour se lier à l'élément Foreground de l'âge TextBlock et d'y isoler la logique de coloration.

<TextBlock x:Name="Age" Grid.Column="1" Grid.Row="2" Text="{Binding Age}" Foreground="{Binding Path=Age, Converter={StaticResource AgeToColorConverter}}" Margin="5"/>

Puis dans le Code:

[ValueConversion(typeof(int), typeof(Brush))]
public class AgeToColorConverter : IValueConverter
{
   public object Convert(object value, Type target)
   {
      int age;
      Int32.TryParse(value.ToString(), age);
      return (age >= 30 ? Brushes.Red : Brushes.Black);
   }
}
11
Drew McGhie

Je crois qu'il existe un moyen plus simple d'atteindre l'objectif en utilisant les pouvoirs de MVVM et de INotifyPropertyChanged.


Avec la propriété Age, créez une autre propriété qui sera un booléen appelé IsAgeValid. Le IsAgeValid sera simplement un contrôle à la demande qui techniquement n'a pas besoin d'un appel OnNotify. Comment?

Pour obtenir des modifications poussées dans le Xaml, placez plutôt le OnNotifyPropertyChanged pour IsAgeValid dans le setter Age.

Toute liaison à IsAgeValid aura un message de notification envoyé sur tout changement de Age qui est vraiment ce qui est examiné.


Une fois la configuration effectuée, liez bien sûr le déclencheur de style pour false et true en conséquence au résultat IsAgeValid.

public bool IsAgeValid{ get { return Age > 30; } }

public int Age
{ 
  get { return _Age; }

  set
  {
   _Age=value;
   OnPropertyChanged("Age");   
   OnPropertyChanged("IsAgeValid"); // When age changes, so does the
                                    // question *is age valid* changes. So 
                                    // update the controls dependent on it.
   } 
 }
9
ΩmegaMan

Si possible, vous pouvez ajouter une propriété à votre modèle, c'est le moyen le plus simple. Par exemple.

public int AgeBoundry
{
    get
    {
        if (Age < 30)
            return 0;
        else if (Age == 30)
            return 1;
        else
            return 2;
    }
}

alors vous pouvez vérifier la valeur de l'entier.

<DataTemplate.Triggers>
    <DataTrigger Binding="{Binding Path=Age}">
        <DataTrigger.Value>0</DataTrigger.Value>
        <Setter TargetName="Age" Property="Foreground" Value="Green"/> 
    </DataTrigger>
    <DataTrigger Binding="{Binding Path=Age}">
        <DataTrigger.Value>1</DataTrigger.Value>
        <Setter TargetName="Age" Property="Foreground" Value="Orange"/> 
    </DataTrigger>
    <DataTrigger Binding="{Binding Path=Age}">
        <DataTrigger.Value>2</DataTrigger.Value>
        <Setter TargetName="Age" Property="Foreground" Value="Red"/> 
    </DataTrigger>
</DataTemplate.Triggers>
1
Mark