2010-11-28 4 views
6

Sur ma fenêtre, il y a plusieurs contrôles GroupBox, chacun contenant un contrôle de grille. À ces grilles je veux asigner un style. Mais uniquement pour les Grids directement dans un GroupBox, toutes les autres Grilles ne devraient pas être affectées.Style DataTrigger avec référence au type de contrôle parent

J'ai essayé ce qui suit, qui ne fonctionne pas car GetType() n'a pas de propriété.

<Style TargetType="Grid"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Parent.GetType()}" Value="{x:Type GroupBox}"> 
       <!-- <Setter Property="..." Value="..."/> --> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 

J'ai trouvé une solution de contournement, mais ce n'est pas vraiment une belle solution, que je dois modifier les zones de groupe:

<Style TargetType="GroupBox"> 
     <Setter Property="Tag" Value="blub"/> 
    </Style> 
    <Style TargetType="Grid"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding Path=Parent.Tag, RelativeSource={RelativeSource Mode=Self}}" Value="blub"> 
       <!-- <Setter Property="..." Value="..."/> --> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 

Il est évident que je pourrais définir le style pour chaque grille manuellement, mais je J'essaie d'éviter cela, car il y en a beaucoup. J'espère que vous pouvez trouver un moyen de faire fonctionner le premier exemple.

Répondre

5
<DataTrigger Binding="{Binding Path=Parent.Tag, RelativeSource={RelativeSource Mode=Self}}" Value="blub"> 

Ce code ne fonctionnerait pas, car le type de mode est en fait BindingMode qui est un Enumeration, et rien de tout cela est membre est auto. Donc cette affectation Mode = Self est erronée dans votre code. Pour connaître les valeurs possibles de Mode, click this.

La bonne façon d'écrire c'est,

<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}, Path=Tag}" Value="blub"> 

Et bien sûr, pour que cela fonctionne, vous avez à garder ce style pour GroupBox que vous avez déjà écrit.

+0

Je crains que vous vous trompiez à ce sujet. Mon code fonctionne très bien. Le mode n'est pas de type BindingMode, mais de type RelativeSourceMode. Ma conjecture serait que vous avez négligé les accolades dans RelativeSource = {RelativeSource Mode = Self} qui fait de Mode une propriété de RelativeSource et non de Binding. – PeterE

+0

@Peter: Vous avez raison. Ce défilement horizontal m'a dérangé et je n'ai pas vraiment remarqué les accolades internes qui font de la propriété 'Mode' de RelativeSource. Merci d'avoir signalé l'erreur! :-) – Nawaz

0

Utilisez le code suivant:

using DevExpress.Xpf.Core.Native; 
using System; 
using System.Globalization; 
using System.Windows; 
using System.Windows.Data; 

namespace BindingErrorHelper 
{ 
    public class IsTypeFoundConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      FrameworkElement element = value as FrameworkElement; 
      Type type = parameter as Type; 
      if (element != null && type != null) 
      { 
       element = LayoutHelper.FindElement(element,type); 
       if (element != null) 
        return true; 
      } 
      return false; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      return value; 
     } 
    } 

    public class LayoutHelper 
    { 
     public static FrameworkElement FindElement(FrameworkElement treeRoot, Type type) 
     { 
     FrameworkElement parentElement = VisualTreeHelper.GetParent(treeRoot) as FrameworkElement; 
     while (parentElement != null) 
     { 
      if (parentElement.GetType() == type) 
       return parentElement; 
      else 
       parentElement = VisualTreeHelper.GetParent(parentElement) as FrameworkElement; 
     } 
     return null; 
     } 
    } 
} 

Recopiez le code XAML comme:

<tt:IsTypeFoundConverter x:Key="isTypeFoundConverter"/> 

<Style TargetType="Grid"> 
    <Style.Triggers> 
     <DataTrigger Binding={Binding RelativeSource={RelativeSource Self}, Converter={StaticResource isTypeFoundConverter}, ConverterParameter={x:Type GroupBox}}" Value="true"> 
      <!-- <Setter Property="..." Value="..."/> --> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 
1

Cela a fonctionné pour moi:

 <Style.Triggers> 
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StatusBar}}, Path=DependencyObjectType.Name}" Value="StatusBar"> 
       <Setter Property="Margin" Value="0"/> 
       <Setter Property="Padding" Value="0"/> 
       <Setter Property="Background" Value="Chartreuse"/> 
      </DataTrigger> 
     </Style.Triggers> 

Il vous permet de définir le style en fonction du type de parent sans avoir à utiliser Tag qui devrait vraiment être utilisé par le code plutôt que par le balisage.

+0

Cela semble prometteur. Je trouve intéressant que le type (CLR) soit uniquement disponible via la méthode GetType(), alors que le DependencyObjectType, dont AFAIK est essentiellement un wrapper autour du type CLR, est une propriété. – PeterE

+0

Oui, je l'ai trouvé intéressant aussi. Je cherchais aussi à savoir pourquoi GetType est une méthode au lieu d'une propriété. Il y a une variété d'opinions, y compris l'efficacité, l'abus, les conventions sur ce qu'un acquéreur de propriété devrait faire, etc. – bigbyte

+0

ATM Je n'ai pas l'opportunité de le tester. Pouvez-vous me dire si les définitions de déclencheurs suivantes sont équivalentes? (Le mien fonctionne-t-il?) Mon idée originale: '' Votre version: '' – PeterE

Questions connexes