WPF:将ControlTemplate与Placeholder Textbox一起使用时,将焦点移至上一个控件(SHIFT + Tab)

时间:2018-10-09 12:36:04

标签: c# wpf textbox keyboard-navigation

我创建了一个WPF TextBox,其中包含占位符文本,方法是创建一个自定义的Style,该TextBox在{{1}中的另一个TextBox上覆盖一个ControlTemplate(作为placholder文本) }}。

这是样式定义:

<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上触发时,通过Tab键浏览多个TextBox时,可以使子_textSource控件(名为TextBox)集中。

通过按 SHIFT + Tab 导航到上一个元素不起作用。如何获得 SHIFT + Tab 来将焦点设置到上一个元素?

1 个答案:

答案 0 :(得分:0)

如果您希望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}" />