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

北慕城南 提交于 2019-12-23 03:12:16

问题


I would like a nice little orange border around my Textbox whilst the user is typing in it (Has Focus).

I defined styles for the tiggers I think I need, but there is a strange behavior.

When the cursor is in the TextBox and the WPF app has focus, it has a blue border.

But while the cursor is focused and I click outside of the app (like in visual studio) it becomes orange.

I've tried overriding many triggers but to no avail.

This is what happens when I focus on the textbox but am focused on another app:

This is the textbox w/focus in the app:

And here is the code:

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>

Styles:

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

回答1:


Take a look at default TextBox style here: https://msdn.microsoft.com/en-us/library/cc645061%28v=vs.95%29.aspx

You will notice that in ControlTemplate there is this block:

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

You see here that only one Border's BorderBrush is bound to BorderBrush property of TextBox. When control goes to focused state - another border (FocusVisualElement) becomes visible and because it's positined later in visual tree - it overlays regular Border. Same is true when control goes to disabled or readonly state. So your style setters basically have no effect.

Now when your are switching to another app - TextBox does not consider it focused any more (note that it does not just use IsFocused property to determine that). So it hides FocusVisualElement and here you see border color applied by your trigger.

Long story short - control developers are not forced to bind to single BorderBrush property for every possible state. They could have provided something like FocusedBorderBrush property, but they did not - so you have to overwrite ControlTemplate of TextBox (you can use default template as provided by link above and overwrite some colors).



来源:https://stackoverflow.com/questions/36605387/wpf-textbox-border-style-trigger-isfocused-only-works-if-has-focus-but-not-keybo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!