WPF: переместить фокус на предыдущий элемент управления (SHIFT + вкладка) при использовании ControlTemplate с текстовым полем-заполнителем - PullRequest
0 голосов
/ 09 октября 2018

Я создал WPF TextBox с текстом заполнителя, создав пользовательский Style, который накладывает один TextBox (как текст плашдолдера) на другой TextBox в ControlTemplate.

Вотопределение стиля:

<Style x:Key="TextBoxFormBaseStyle"
       BasedOn="{StaticResource {x:Type TextBox}}"
       TargetType="{x:Type TextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <TextBox x:Name="_textSource"
                             Panel.ZIndex="2"
                             Background="Transparent"
                             Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                    <TextBox x:Name="_textTag"
                             Panel.ZIndex="1"
                             Focusable="False"
                             Text="{TemplateBinding Tag}">
                        <TextBox.Style>
                            <Style TargetType="{x:Type TextBox}">
                                <Setter Property="Foreground" Value="Transparent" />
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Path=Text, Source={x:Reference _textSource}}" Value="">
                                        <Setter Property="Foreground" Value="{Binding Path=OpacityMask, Source={x:Reference _textSource}}" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBox.Style>
                    </TextBox>
                </Grid>
                <!--  Move Focus to child control  -->
                <ControlTemplate.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter TargetName="_textSource" Property="FocusManager.FocusedElement" Value="{Binding ElementName=_textSource}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Триггер для свойства IsFocused позволяет фокусировать дочерний элемент управления TextBox (с именем _textSource) при навигации по нескольким TextBox с помощью клавиши Tab.

Переход к предыдущему элементу нажатием SHIFT + Tab не работает.Как я могу получить SHIFT + Tab , чтобы установить фокус на предыдущий элемент?

1 Ответ

0 голосов
/ 09 октября 2018

Существуют более эффективные способы добавления водяных знаков, если вы хотите, чтобы TextBox действительно вел себя и фокусировался, как встроенный TextBox.Попробуйте этот стиль:

<Style x:Key="TextBoxFormBaseStyle" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type TextBox}">
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <Grid>
                        <TextBox x:Name="_textTag"
                                 Focusable="False"
                                 Text="{TemplateBinding Tag}"
                                 BorderThickness="0">
                            <TextBox.Style>
                                <Style TargetType="{x:Type TextBox}">
                                    <Setter Property="Foreground" Value="Transparent" />
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding Path=Text, RelativeSource={RelativeSource AncestorType=TextBox}}" Value="">
                                            <Setter Property="Foreground" Value="{Binding Path=OpacityMask, RelativeSource={RelativeSource AncestorType=TextBox}}" />
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBox.Style>
                        </TextBox>
                        <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Opacity" TargetName="border" Value="0.56"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
                    </Trigger>
                    <Trigger Property="IsKeyboardFocused" Value="true">
                        <Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Пример использования:

<TextBox OpacityMask="Red" Tag="Red Watermark" Text="text" Style="{StaticResource TextBoxFormBaseStyle}" />
<TextBox OpacityMask="Green" Tag="Green Watermark" Text="text" Style="{StaticResource TextBoxFormBaseStyle}" />
...