WPF Bind à la propriété parent de l'intérieur élément imbriqué en utilisant le style

StackOverflow https://stackoverflow.com/questions/3639537

  •  30-09-2019
  •  | 
  •  

Question

J'ai essayé de construire une zone de texte avec un indice qui est l'affichage alors qu'il est vide. Je vais avoir du mal à mettre le texte à partir d'un soupçon de 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 à la propriété ancêtre à partir d'un style?

Était-ce utile?

La solution

Le problème est pas avec le RelativeSource mais avec la façon dont vous utilisez le VisualBrush. Rappelons que les styles sont partagés entre les éléments que vous les appliquer. La raison pour laquelle votre exemple ne fonctionne pas est que, en effet que vous essayez de partager une seule zone de texte (celui que vous tagged « intérieur ») avec plusieurs zones de texte parent.

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éé). Laquelle des zones de texte que le style soit appliquée à doit être choisi comme l'ancêtre de la zone de texte interne lorsque vous utilisez le RelativeSource de liaison?

C'est pourquoi DataTemplates et ControlTemplates existent dans WPF. Plutôt que de réellement visuels instancier directement, ils définissent un modèle qui permettent à plusieurs copies de visuels à créer au besoin.

Autres conseils

Reativesource ne fonctionne pas comme prévu. Il est préférable de créer textbox filigrane à l'aide 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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top