Pregunta

Estoy tratando de trabajar y entiendo la jerarquía XAML para los estilos ... en simple, un cuadro de texto simple ... visto por todo el lugar sobre cómo establecer el color de fondo "deshabilitado" basado en el indicador "isEnabled". Genial, tengo eso.

Ahora, quiero tener otra clase derivada del cuadro de texto ... MyTextBox. Para esta clase, tengo una propiedad (no propiedad de dependencia, por lo que estaba usando DataTrigger). Por lo tanto, quiero mantener todas las acciones normales del cuadro de texto que funcionaban, pero ahora obtenga el nuevo desencadenante para actualizar correctamente el color de fondo a otro color. Entonces, esto es lo que tengo. Solo para aclarar, todos mis recursos estáticos para colores son cepillos sólidos ...

<Style TargetType="TextBox" >
  <Setter Property="FontFamily" Value="Courier New" />
  <Setter Property="FontSize" Value="12" />
  <Setter Property="Foreground" Value="{StaticResource MyForeground}" />
  <Setter Property="Background" Value="{StaticResource MyBackground}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TextBox">
        <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            Background="{TemplateBinding Background}" 
            SnapsToDevicePixels="true">

            <ScrollViewer Name="PART_ContentHost" 
                Background="{TemplateBinding Background}" 
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        </Border>

        <ControlTemplate.Triggers>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{StaticResource MyDisBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="MyDisBackground"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!--  Now, my derived (or so I was hoping) style that just adds additional trigger -->
<Style TargetType="local:MyTextBox"  BasedOn="{StaticResource {x:Type TextBox}}" >
  <Style.Triggers>
    <DataTrigger Binding="{Binding Path=IsRequired}" Value="True">
      <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
    </DataTrigger>
  </Style.Triggers>
</Style>

¿Me estoy perdiendo algo simple?

¿Fue útil?

Solución

Primero tu DataTrigger está mirando el DataContext de tu MyTextBox (no el control en sí). Así que mira el control, necesitarías hacer algo como:

<DataTrigger Binding="{Binding Path=IsRequired, RelativeSource={RelativeSource Self}}" Value="True">
    <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
</DataTrigger>

Ahora eso establecerá el MyTextBox.Background propiedad cuando MyTextBox.IsRequired es verdad. Pero los valores de la propiedad de dependencia tienen un orden de precedencia. Entonces lo anterior cambiará visualmente el fondo utilizado como:

<local:MyTextBox />

En el siguiente caso tu RequiredBackground El cepillo no se usará. En su lugar verás el MyDisBackground cepillo:

<local:MyTextBox IsEnabled="False" />

En este caso, el ScrollViewer.Background se cambia a MyDisBackground y ya no se une al MyTextBox.Background propiedad. los MyTextBox.Background todavía sería RequiredBackground, pero ya no se usa en ningún lado.

Finalmente, en el siguiente caso tu RequiredBackground El cepillo no se usará.

<local:MyTextBox Background="Yellow" />

Aquí, el valor local (amarillo) está en el n. ° 3 en la lista de precedencias, mientras que el setter de estilo está en el n. ° 8.

Si hace de su propiedad una propiedad de dependencia que vale por defecto a False, entonces podría hacer algo como:

<Style TargetType="TextBox" >
  <Setter Property="FontFamily" Value="Courier New" />
  <Setter Property="FontSize" Value="12" />
  <Setter Property="Foreground" Value="{StaticResource MyForeground}" />
  <Setter Property="Background" Value="{StaticResource MyBackground}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TextBox">
        <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            Background="{TemplateBinding Background}" 
            SnapsToDevicePixels="true">

            <ScrollViewer Name="PART_ContentHost" 
                Background="{TemplateBinding Background}" 
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        </Border>

        <ControlTemplate.Triggers>
          <Trigger Property="local:MyTextBox.IsRequired" Value="False">
            <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="RequiredBackground"/>
          </Trigger>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{StaticResource MyDisBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="MyDisBackground"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<Style TargetType="local:MyTextBox"  BasedOn="{StaticResource {x:Type TextBox}}" />

A pesar de que la propiedad no existe para el cuadro de texto, aún puede obtener el valor predeterminado de su propiedad de dependencia y activarla. Pero dado que se configuraría para un cuadro de texto, ese disparador nunca se utilizará.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top