2010-11-28 14 views
6

En mi ventana hay varios controles GroupBox, cada uno con un control de cuadrícula. Para esas grillas quiero asignar un estilo. Pero solo para aquellas Grids que están directamente en un GroupBox, todas las demás Grids no deberían verse afectadas.Style DataTrigger con referencia al tipo de control principal

He intentado lo siguiente, que no funciona ya que GetType() no es propiedad.

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

he encontrado una solución, pero no es realmente una solución hermosa, ya que tengo que modificar las GroupBoxes:

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

Obviamente, podría establecer el estilo para cada cuadrícula de forma manual, pero me estoy tratando de evitar eso, ya que hay muchos de ellos. Espero que encuentren la forma de que el primer ejemplo funcione.

Respuesta

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

Este código no funcionaría, porque el tipo de modo es en realidad BindingMode que es una enumeración, y nada de esto es miembro es Ser. Entonces esta asignación Mode = Self está mal en su código. Para conocer los valores posibles de Mode, click this.

La forma correcta de escribir esto es,

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

Y, por supuesto, para que esto funcione, usted tiene que mantener ese estilo de GroupBox que ya ha escrito.

+0

Me temo que estás equivocado al respecto. Mi código funciona bien. El modo no es del tipo BindingMode, sino del tipo RelativeSourceMode. Me imagino que omitiste las llaves en RelativeSource = {RelativeSource Mode = Self} que hacen que Mode sea una propiedad de RelativeSource y no una de Binding. – PeterE

+0

@Peter: tienes razón. Este desplazamiento horizontal me molestó y realmente no noté las llaves internas que hacen propiedad 'Mode' de RelativeSource. Gracias por señalar el error! :-) – Nawaz

0

Utilice el código siguiente:

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

Escribir el código XAML como:

<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

Esto funcionó para mí:

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

Se le permite configurar el estilo en función del tipo de los padres sin tener que recurrir a Tag, que realmente debería ser utilizado por código en lugar de por marcado.

+0

Esto parece prometedor. Me parece interesante, que el Tipo (CLR) solo está disponible a través del método GetType(), mientras que el DependencyObjectType, que AFAIK es básicamente un contenedor alrededor del tipo CLR, es una propiedad. – PeterE

+0

Sí, me pareció interesante también. También estaba investigando por qué GetType es un método en lugar de una propiedad. Hay una variedad de opiniones que incluyen eficiencia, abuso, convenciones sobre lo que debe hacer un comprador de propiedades, etc. – bigbyte

+0

Cajero automático No tengo la oportunidad de probarlo. ¿Me puede decir si las siguientes definiciones de disparador son equivalentes? (¿El mío incluso funciona?) Mi idea original: '' Su versión: '' – PeterE

Cuestiones relacionadas