WPF TextBox Border Style Trigger IsFocused 仅在具有焦点但没有键盘焦点时才有效

WPF TextBox Border Style Trigger IsFocused only works if has focus but not keyboard focus

我希望在用户输入时(有焦点)在我的 Textbox 周围有一个漂亮的橙色小边框。

我为我认为需要的跳跳虎定义了样式,但是有一个奇怪的行为。

当光标位于 TextBox 并且 WPF 应用程序有焦点时,它有一个蓝色边框。

但是,当光标处于焦点状态并且我在应用程序外部单击时(如 visual studio),它会变成橙色。

我已经尝试覆盖许多触发器但无济于事。

这是当我关注文本框但关注另一个应用程序时发生的情况:

这是应用程序中的文本框 w/focus:

这是代码:

CTRL Xaml:

   <TextBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
                                         Style="{StaticResource RegistrationTextbox}" 
                                         IsReadOnly="{Binding Path=IsFirstNameReadOnly}" Text="{Binding FirstName}"  BorderThickness="0.99">
                                        <b:Interaction.Triggers>
                                            <b:EventTrigger EventName="GotFocus">
                                                <b:InvokeCommandAction Command="{Binding GotFocusFirstNameCommand}" />
                                            </b:EventTrigger>
                                        </b:Interaction.Triggers>
                                    </TextBox>

样式:

  <Style x:Key="RegistrationTextbox" TargetType="{x:Type TextBox}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>

    <Style.Triggers>
        <Trigger Property="IsReadOnly" Value="true">
            <Setter Property="Background" Value="#f2f2f2"/>
            <Setter Property="BorderBrush" Value="#f2f2f2"/>
            <Setter Property="BorderThickness" Value="2"/>
        </Trigger>
        <Trigger Property="IsKeyboardFocused" Value="true">
            <Setter Property="BorderBrush" Value="Red"/>
            <Setter Property="BorderThickness" Value="2"/>
        </Trigger>
        <Trigger Property="IsFocused"  Value="True">
            <Setter Property="BorderBrush" Value="#FAA634"/>
            <Setter Property="BorderThickness" Value="2"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="BorderBrush" Value="#F8B963"/>
            <Setter Property="BorderThickness" Value="2"/>
        </Trigger>
    </Style.Triggers>        
</Style>

在这里查看默认的 TextBox 样式:https://msdn.microsoft.com/en-us/library/cc645061%28v=vs.95%29.aspx

您会注意到在 ControlTemplate 中有这个块:

     <Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
     <Grid>
           <Border x:Name="ReadOnlyVisualElement" Opacity="0" Background="#5EC9C9C9"/>
           <Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
               <ScrollViewer x:Name="ContentElement" Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False"/>
           </Border>
     </Grid>
     </Border>
     <Border x:Name="DisabledVisualElement" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}" Opacity="0" IsHitTestVisible="False"/>
     <Border x:Name="FocusVisualElement" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}" Margin="1" Opacity="0" IsHitTestVisible="False"/>

你看这里只有一个Border的BorderBrush绑定到TextBox的BorderBrush属性。当控件进入聚焦状态时 - 另一个边框 (FocusVisualElement) 变得可见并且因为它在可视化树中稍后被定位 - 它覆盖常规边框。当控件进入禁用或只读状态时也是如此。所以你的style setters基本没有作用

现在,当您切换到另一个应用程序时 - TextBox 不再认为它具有焦点(请注意,它不只是使用 IsFocused 属性 来确定)。因此它隐藏了 FocusVisualElement,在这里您可以看到触发器应用的边框颜色。

长话短说 - 控件开发人员不必为每种可能的状态强制绑定到单个 BorderBrush 属性。他们本可以提供 FocusedBorderBrush 属性 之类的东西,但他们没有 - 所以你必须覆盖 TextBox 的 ControlTemplate(你可以使用上面 link 提供的默认模板并覆盖一些颜色)。