WPF связывается с родительским свойством из вложенного элемента с использованием стиля

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

  •  30-09-2019
  •  | 
  •  

Вопрос

Я пытался построить текстовое поле со намеком, который отображается, пока он пуст. У меня проблемы с нарушением текста подсказка из в стиле.

Быть точным, это работает (То есть он связывается правильно):

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

Но, когда я перемещаю его в стиль, это не так:

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

Так что же уловите? Как я могу привязать к имуществу предков изнутри стиля?

Это было полезно?

Решение

Проблема не сочествием, но с тем, как вы используете VisualBrush. Напомним, что стили распределяются между элементами, которые вы применяете их. Причина, по которой ваш пример не работает, заключается в том, что, по сути, вы пытаетесь поделиться одним текстовым ящиком (тот, который вы пометили «внутреннее») с несколькими родительскими текстовыми коробками.

Чтобы понять, почему это проблема, попробуйте мыслительный эксперимент: внутреннее текстовое поле создается один раз (грубо говоря, это произойдет, когда стиль создан). Какой из текстовых ящиков в том, что стиль применяется к тому, что должен быть выбран в качестве предка внутреннего текстового поля при использовании привязки Ructrientource?

Вот почему DataTemplates. а также ControlTemplates. существуют в WPF. Вместо того, чтобы на самом деле создавать непосредственное мнение изображения, они определяют шаблон, который позволяет создавать несколько копий визуальных эффектов по мере необходимости.

Другие советы

ReativeSource не работает должным образом. Лучше создать текстовое поле водяного знака, используя шаблон управления. Но ваша версия может работать:

<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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top