2009-10-30 4 views
34

Existe-t-il un moyen de faire une comparaison sur un type d'objet pour un déclencheur?WPF Déclencheur basé sur le type d'objet

<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type"> 
</DataTrigger> 

Contexte: J'ai une barre d'outils et je veux cacher le bouton de fonction de ce que la sous-classe est actuellement fixé à l'objet de l'élément sélectionné.

Merci

Répondre

29

Pourquoi ne pas simplement utiliser un convertisseur qui prend un objet et renvoie une chaîne du type d'objet?

Binding="{Binding SelectedItem, Converter={StaticResource ObjectToTypeString}}"

et définir le convertisseur:

public class ObjectToTypeStringConverter : IValueConverter 
{ 
    public object Convert(
    object value, Type targetType, 
    object parameter, System.Globalization.CultureInfo culture) 
    { 
     return value.GetType().Name;    
    } 

    public object ConvertBack(
    object value, Type targetType, 
    object parameter, System.Globalization.CultureInfo culture) 
    { 
     // I don't think you'll need this 
     throw new Exception("Can't convert back"); 
    } 
} 

Vous aurez besoin de déclarer la ressource statique quelque part dans votre XAML:

<Window.Resources> 
    <convs:ObjectToTypeStringConverter x:Key="ObjectToTypeString" /> 
</Window.Resources> 

Où est CONVS 'dans ce cas est l'espace de noms de l'endroit où se trouve le convertisseur.

Espérons que cela aide.

+10

+1 pour l'idée générale, mais le convertisseur devrait renvoyer l'objet Type plutôt que son nom ... –

+2

Cela fonctionnerait-il? Est-ce que le runtime ne comparerait pas quelque chose de type String à quelque chose de type Type? Je sais qu'il gère la conversion/la comparaison de la plupart des types de valeur, mais ne sait pas comment il gère les autres comparaisons de type. – AndyG

+5

Oui, cela fonctionnerait, il vous suffit d'utiliser l'extension de balisage {x: Type} dans la valeur de DataTrigger. –

4

L'utilisation d'un convertisseur comme suggéré par AndyG est une bonne option. Vous pouvez également utiliser un DataTemplate différent pour chaque type de cible. WPF sélectionne automatiquement le DataTemplate qui correspond au type d'objet

+0

Mais cela affectera également tous les sous-éléments de ce type de données – Staeff

42

Ceci est basé sur la réponse de @ AndyG mais est un peu plus sûr car il est fortement typé.

Mettre en œuvre un IValueConverter nommé DataTypeConverter, qui accepte un objet et renvoie son type (comme System.Type):

public class DataTypeConverter:IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
     CultureInfo culture) 
    { 
     return value.GetType(); 
    } 

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

Changer votre DataTrigger d'utiliser le convertisseur, et définir la valeur à la Type:

<DataTrigger Binding="{Binding SelectedItem, 
     Converter={StaticResource DataTypeConverter}}" 
     Value="{x:Type local:MyType}"> 
... 
</DataTrigger> 

Declare DataTypeConverter des ressources:

<UserControl.Resources> 
    <v:DataTypeConverter x:Key="DataTypeConverter"></v:DataTypeConverter> 
</UserControl.Resources> 
+1

Ceci ne fonctionne pas pour moi. Je reçois une exception XamlParseException si j'essaie d'utiliser une extension markup dans DataTrigger.Value, donc je viens d'utiliser la méthode de comparaison de chaînes à la place. Voir ici: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/14cbdb99-fd33-4ad0-8b1b-a0139c7fbf95/ – RobJohnson

+3

Mieux vaut vérifier si la valeur est null avant d'essayer GetType(). valeur de retour! = null? value.GetType(): null; – Viv

+0

'Binding =" {Binding SelectedItem} "Convertisseur = {StaticResource DataTypeConverter}}" 'doit être' Binding = "{Liaison SelectedItem, Convertisseur = {StaticResource DataTypeConverter}}" ' – Firo

3

Pas un déclencheur mais cela a fonctionné pour moi. (Le déclencheur approche n'a pas car il ne peut pas créer une case à cocher pour une chaîne Ceci est à peu près Thomas Levesque's suggestion.)

utilisant:

xmlns:mscorlib="clr-namespace:System;assembly=mscorlib" 

A ou CheckBox TextBox en fonction du type:

<ContentPresenter Content="{TemplateBinding SelectedItem}"> 
     <ContentPresenter.Resources> 
       <DataTemplate DataType="{x:Type mscorlib:Boolean}"> 
        <CheckBox Height="25" Width="25" HorizontalAlignment="Left" IsChecked="{Binding Path=.}"/> 
       </DataTemplate> 
        <DataTemplate DataType="{x:Type mscorlib:String}"> 
        <TextBox Height="25" Width="200" HorizontalAlignment="Left" Text="{Binding Path=.}"/> 
       </DataTemplate> 
     </ContentPresenter.Resources> 
</ContentPresenter> 

note: pour la solution de Greg Sansom vous soit arrivé à renvoyer le type sous forme de chaîne ou d'utiliser mscorlib comme ci-dessus

Questions connexes