J'apprends WPF et j'ai rencontré le problème suivant:
J'ai un type enum dans un autre espace de noms que mon XAML:
public enum NodeType
{
Type_SYSTEM = 1, // System
Type_DB = 2, // Database
Type_ROOT = 512, // Root folder
Type_FOLDER = 1024, // Folder
}
dans mon XAML, je voudrais déclencher une image avec un entier
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="{NodeType: }">
<Setter Property="Source" Value="/Images/DB.PNG"/>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="128">
<Setter Property="Source" Value="/Images/SERVER.PNG"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
Existe-t-il un moyen d'obtenir une valeur entière et de la comparer avec un type d'énumération directement dans le code XAML?
Mon énumération est dans l'espace de noms AnotherNamespace.Types
<DataTrigger Binding="{Binding IntegerType}" Value="MyEnumType.Type_DB">
<Setter Property="Source" Value="/Images/SERVER.PNG"/>
J'avais une question similaire ici , et mon résultat final a été de créer un générique IValueConverter qui a passé la valeur enum
que je voulais faire correspondre en tant que ConverterParameter
, et il renvoie true
ou false
selon que la valeur liée correspond à (int)
valeur de l'énumération.
Le résultat final ressemble à ceci:
Code XAML:
<DataTrigger Value="True"
Binding="{Binding SomeIntValue,
Converter={StaticResource IsIntEqualEnumConverter},
ConverterParameter={x:Static local:NodeType.Type_DB}}">
Convertisseur
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (parameter == null || value == null) return false;
if (parameter.GetType().IsEnum && value is int)
{
return (int)parameter == (int)value;
}
return false;
}
Il vous suffit de vous assurer que votre espace de noms est pris en compte dans votre en-tête XAML, puis vous pouvez référencer les DP personnalisés et les valeurs d'énumération directement dans votre balisage.
Par exemple, j'utilise ce code pour faire exactement cela:
<DataTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True" />
<Condition Binding="{Binding Type}" Value="{x:Static loc:AppProfileItemType.Custom}" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="PART_Delete" Property="Visibility" Value="{x:Static Visibility.Visible}" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</DataTemplate.Triggers>
Notez que vous ne pouvez pas accéder aux DataTriggers dans un style, vous devez plutôt créer un DataTemplate ou ControlTemplate pour cela (cependant, .NET 4 ajoute la possibilité de définir des déclencheurs dans les styles). Vous pouvez remplacer le ControlTemplate d'un style comme ceci:
<Style x:Key="MyCustomButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter />
<ControlTemplate.Triggers>
<!-- Put your DataTriggers here -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Pour les DataTemplates que vous souhaitez avoir des liaisons à un objet, vous pouvez simplement utiliser un ContentPresenter et définir son contenu sur l'objet que vous souhaitez afficher avec une définition DataTemplate à utiliser pour l'affichage de l'objet. Il y a toujours un moyen d'utiliser DataTriggers, ce n'est pas toujours direct ou aussi simple que d'utiliser un style.