2010-09-03 10 views
13

He intentado crear un cuadro de texto con una sugerencia que se muestra mientras está vacío. Tengo problemas para configurar el texto de sugerencia dentro de un estilo.WPF Vinculación de la propiedad primaria dentro del elemento anidado usando el estilo

Para ser precisos, esto funciona (es decir, se une correctamente):

<TextBox Tag="hint text"> 
     <TextBox.Background> 
      <VisualBrush Stretch="None"> 
       <VisualBrush.Visual> 
        <TextBlock Text="{Binding Tag, RelativeSource={RelativeSource AncestorType=TextBox}}" FontStyle="Italic" Foreground="LightGray" /> 
       </VisualBrush.Visual> 
      </VisualBrush> 
     </TextBox.Background> 
    </TextBox> 

pero, cuando lo muevo al estilo, no es así:

<Style TargetType="TextBox" x:Key="stlHintbox"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Mode=Self}}" Value=""> 
      <Setter Property="Background"> 
       <Setter.Value> 
        <VisualBrush Stretch="None"> 
         <VisualBrush.Visual> 
          <TextBlock Tag="inner" Text="{Binding Tag, RelativeSource={RelativeSource AncestorType=TextBox}}" 
             FontStyle="Italic" Foreground="LightGray" /> 
         </VisualBrush.Visual> 
        </VisualBrush> 
       </Setter.Value> 
      </Setter> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

<TextBox Tag="hint text" Style="{StaticResource stlHintbox}" /> 

Entonces, ¿cuál es el truco? ¿Cómo puedo vincularme a la propiedad del antepasado desde dentro de un estilo?

Respuesta

12

El problema no es con el RelativeSource pero con la forma en que están utilizando el VisualBrush. Recuerde que los estilos se comparten entre los elementos a los que los aplica. El motivo por el que su ejemplo no funciona es que, de hecho, está intentando compartir un único cuadro de texto (el que etiquetó "interno") con varios cuadros de texto primarios.

Para ver por qué esto es un problema, intente con un experimento mental: el cuadro de texto interno se crea una vez (en términos generales, esto sucederá cuando se cree el estilo). ¿Cuál de los cuadros de texto a los que se aplica el estilo debe elegirse como el antecesor del cuadro de texto interno cuando usa el enlace RelativeSource?

Es por eso que DataTemplates y ControlTemplates existen en WPF. En lugar de crear instancias visuales directamente, definen una plantilla que permite crear múltiples copias de imágenes según sea necesario.

+0

Ok, eso realmente tiene sentido ... Pasé por libros demasiado rápido, parece :) – veljkoz

5

Reativesource no funciona como se esperaba. Es mejor crear un cuadro de texto de marca de agua usando la plantilla de control. Sin embargo, su versión podría funcionar:

<Window.Resources> 
    <Style TargetType="TextBox" x:Key="stlHintbox"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Mode=Self}}" Value=""> 
       <Setter Property="TextBox.Background"> 
        <Setter.Value> 
         <VisualBrush Stretch="None" Visual="{Binding ElementName=hintText}"/> 
        </Setter.Value> 
       </Setter> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<StackPanel> 
    <TextBox Tag="hint text" x:Name="myTextBox" Style="{StaticResource stlHintbox}" /> 
    <Border Visibility="Hidden"> 
     <TextBlock x:Name="hintText" Text="{Binding Tag, ElementName=myTextBox}" FontStyle="Italic" Foreground="LightGray" /> 
    </Border> 
</StackPanel> 
+0

Esto está bien, pero me impide tener más de una hintbox en la misma ventana, y su uso no sería tan obvio. Gracias por la sugerencia sobre plantillas de control, lo investigaré más ... – veljkoz

Cuestiones relacionadas