WPF binden mit Style an die übergeordnete Eigenschaft aus dem verschachtelten Element

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

  •  30-09-2019
  •  | 
  •  

Frage

Ich habe versucht, ein Textfeld mit einem Hinweis zu erstellen, der angezeigt wird, während es leer ist. Ich habe Probleme, den Hinweistext aus einem Stil auszulegen.

Genau sein, dies Arbeiten (Das heißt, es bindet richtig):

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

Aber wenn ich es in den Stil bewege, nicht:

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

Also, was ist der Haken? Wie kann ich aus einem Stil an eine Ankunftseigentum binden?

War es hilfreich?

Lösung

Das Problem liegt nicht bei der Verwandten, sondern mit der Art und Weise, wie Sie den VisualBrush verwenden. Denken Sie daran, dass Stile zwischen den Elementen geteilt werden, auf die Sie sie anwenden. Der Grund, warum Ihr Beispiel nicht funktioniert, ist, dass Sie in der Tat versuchen, ein einzelnes Textfeld (das Sie mit "inneren") mit mehreren übergeordneten Textboxen zu teilen.

Um zu sehen, warum dies ein Problem ist, probieren Sie ein Gedankenexperiment aus: Die innere Textbox wird einmal erstellt (grob gesehen wird dies geschehen, wenn der Stil erstellt wird). Auf welchen der Textboxen, auf die der Stil angewendet wird, sollte als Vorfahr des inneren Textfelds ausgewählt werden, wenn Sie die Bindung von Verwandten für die Verfügbarkeit verwenden?

Deshalb DataTemplates und ControlTemplates existieren in WPF. Anstatt tatsächlich Visuals direkt zu instanziieren, definieren sie eine Vorlage, mit der mehrere Kopien von Visuals nach Bedarf erstellt werden können.

Andere Tipps

Reatesiveource funktioniert nicht wie erwartet. Es ist besser, eine Wassermarke -Textbox mithilfe der Steuervorlage zu erstellen. Aber Ihre Version könnte funktionieren:

<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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top