2010-09-03 3 views
13

J'ai essayé de construire une zone de texte avec un indice qui est l'affichage alors qu'il est vide. Je n'arrive pas à définir le texte de l'indice dans un style.WPF Bind à la propriété parent de l'intérieur élément imbriqué en utilisant le style

Pour être précis, ce fonctionne (qui est, il se lie correctement):

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

mais, quand je me déplace au style, il ne fait pas:

<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}" /> 

Alors, quel est le piège? Comment puis-je lier à une propriété ancêtre à l'intérieur d'un style?

Répondre

12

Le problème est pas avec le RelativeSource mais avec la façon dont vous utilisez le VisualBrush. Rappelez-vous que les styles sont partagés entre les éléments auxquels vous les appliquez. La raison pour laquelle votre exemple ne fonctionne pas est que, en fait, vous essayez de partager une seule zone de texte (celle que vous avez appelée "inner") avec plusieurs zones de texte parentes.

Pour voir pourquoi cela est un problème, essayez une expérience de pensée: La zone de texte intérieur est créé une fois (en gros, cela se produira quand le style est créé). Lequel des champs de texte auxquels le style est appliqué doit être choisi comme ancêtre de la zone de texte interne lorsque vous utilisez la liaison RelativeSource? C'est pourquoi il existe DataTemplates et ControlTemplates dans WPF. Plutôt que d'instancier des visuels directement, ils définissent un modèle qui permet de créer plusieurs copies de visuels selon les besoins.

+0

Ok, ça a vraiment du sens ... J'ai passé trop vite dans les livres il me semble :) – veljkoz

5

Reativesource ne fonctionne pas comme prévu. Il est préférable de créer une zone de texte en filigrane à l'aide du modèle de contrôle. Mais votre version pourrait fonctionner:

<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

Ceci est OK, mais il me empêche d'avoir plus d'un hintbox dans la même fenêtre, et il est ne serait pas évident que l'utilisation. Merci pour la suggestion sur les gabarits de contrôle, je vais y regarder de plus ... – veljkoz

Questions connexes