2010-11-28 2 views
6

В моем окне есть несколько элементов управления GroupBox, каждый из которых содержит Grid Control. Для тех Grids я хочу присвоить стиль. Но только для тех гридов, которые находятся непосредственно в GroupBox, все другие гриды не должны быть затронуты.Стиль DataTrigger со ссылкой на Тип родительского элемента управления

Я пробовал следующее, что не работает, поскольку GetType() не является свойством.

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

Я нашел обходной путь, но это на самом деле не красивое решение, так как я должен изменить рамок группы:

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

Очевидно, что я мог бы задать стиль для каждой сетки вручную, но я м, пытаясь избежать этого, так как их очень много. Надеюсь, вы сможете найти способ сделать первый пример работы.

ответ

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

Этот код не будет работать, так как тип режима фактически BindingMode который является перечисление, и ни один из них не является членом это Атман. Итак, это назначение Mode = Self неверно в вашем коде. Чтобы узнать возможные значения режима, click this.

Правильный способ написать это,

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

И, конечно, для этого работать, вы, чтобы сохранить этот стиль для GroupBox, которые вы уже написали.

+0

Боюсь, вы ошибаетесь в этом. Мой код работает очень хорошо. Режим не относится к типу BindingMode, а относится к типу RelativeSourceMode. Я предполагаю, что вы не заметили фигурные скобки в RelativeSource = {RelativeSource Mode = Self}, которые делают режим «Свойство RelativeSource», а не одним из Binding. – PeterE 2010-12-12 13:52:52

+0

@Peter: Вы правы. Эта горизонтальная прокрутка меня беспокоила, и я не замечал внутренних фигурных скобок, которые делают свойство «Mode» RelativeSource. Спасибо, что указали на ошибку! :-) – Nawaz 2010-12-12 14:06:37

0

Используйте следующий код:

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

Написать XAML код как:

<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

Это работало для меня:

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

Это позволяет установить стиль, основанный на родительском типе без необходимости прибегать к тегу, который действительно должен использоваться кодом, а не разметкой.

Смежные вопросы