2010-11-28 5 views
6

Auf meinem Fenster befinden sich mehrere GroupBox Controls, die jeweils ein Grid Control enthalten. Diesen Gittern möchte ich einen Style zuordnen. Aber nur für diese Grids, die sich direkt in einer GroupBox befinden, sollten alle anderen Grids nicht betroffen sein.Style DataTrigger mit Bezug auf Typ des übergeordneten Steuerelements

Ich habe Folgendes versucht, was nicht funktioniert, da GetType() keine Eigenschaft ist.

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

Ich habe eine Abhilfe gefunden, aber es ist nicht wirklich eine schöne Lösung, wie ich die Groupboxes ändern haben:

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

Offensichtlich konnte ich den Stil für jedes Gitter manuell einstellen, aber ich Ich versuche das zu vermeiden, da es ziemlich viele sind. Ich hoffe, Sie können einen Weg finden, um das erste Beispiel zum Laufen zu bringen.

Antwort

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

würde dieser Code nicht funktioniert, weil Art von Modus tatsächlich Binding ist, die eine Enumeration ist, und nichts davon ist Mitglied Selbst ist. Also diese Zuordnung Mode = Self ist falsch in Ihrem Code. Um die möglichen Werte von Mode zu kennen, click this.

Der richtige Weg, dies zu schreiben,

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

Und natürlich für diese zu arbeiten, Sie haben für GroupBox diesen Stil zu halten, die Sie bereits geschrieben haben.

+0

Ich fürchte, du liegst falsch. Mein Code funktioniert gut. Der Modus ist nicht vom Typ BindingMode, sondern vom Typ RelativeSourceMode. Meine Vermutung wäre, dass Sie die Klammern in RelativeSource = {RelativeSource Mode = Self} übersehen haben, die Mode zu einer Eigenschaft von RelativeSource und nicht zu einer von Binding machen. – PeterE

+0

@Peter: Du hast Recht. Dieses horizontale Scrollen hat mich gestört und ich habe nicht wirklich die inneren Klammern bemerkt, die die 'Mode'-Eigenschaft von RelativeSource ausmachen. Danke für den Hinweis auf den Fehler! :-) – Nawaz

0

Verwenden folgenden Code:

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

Schreiben Sie den XAML-Code als:

<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

Das ist für mich gearbeitet:

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

Es Sie Stil basierend festlegen können auf Elterntyp ohne auf den Tag zurückgreifen zu müssen, der eigentlich vom Code und nicht vom Markup verwendet werden sollte.

+0

Das sieht vielversprechend aus. Ich finde es interessant, dass der Typ (CLR) nur über die GetType() -Methode verfügbar ist, während der DependencyObjectType, bei dem es sich bei AFAIK im Grunde genommen um einen Wrapper um den CLR-Typ handelt, eine Eigenschaft ist. – PeterE

+0

Ja, ich fand es auch interessant. Ich habe auch untersucht, warum GetType eine Methode anstelle einer Eigenschaft ist. Es gibt eine Vielzahl von Meinungen, einschließlich Effizienz, Missbrauch, Konventionen darüber, was ein Immobilien-Getter tun sollte usw. – bigbyte

+0

ATM Ich habe keine Gelegenheit, es zu testen. Können Sie mir sagen, ob die folgenden Triggerdefinitionen gleichwertig sind? (Funktioniert meine sogar?) Meine ursprüngliche Idee: '' Ihre Version: '' – PeterE

Verwandte Themen