Триггер WPF TextBox Border Style IsFocused работает, только если имеет фокус, но не фокус клавиатуры

Я хотел бы милую оранжевую рамочку вокруг моего Textbox пока пользователь печатает в нем (имеет фокус).

Я определил стили для тигров, я думаю, что мне нужно, но есть странное поведение.

Когда курсор находится в TextBox и приложение WPF имеет фокус, оно имеет синюю рамку.

Но когда курсор сфокусирован и я нажимаю за пределами приложения (как в Visual Studio), он становится оранжевым.

Я пытался переопределить много триггеров, но безрезультатно.

Вот что происходит, когда я фокусируюсь на текстовом поле, но фокусируюсь на другом приложении:

Фокус но вне приложения

Это текстовое поле с фокусом в приложении:

Сосредоточены в приложении

И вот код:

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>

1 ответ

Решение

Взгляните на стиль 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"/>

Здесь вы видите, что только один BorderBrush Border связан со свойством BorderBrush TextBox. Когда элемент управления переходит в сфокусированное состояние - становится видимой другая граница (FocusVisualElement) и, поскольку она позиционируется позже в визуальном дереве, - она ​​перекрывает обычную границу. То же самое верно, когда управление переходит в отключенное или только для чтения состояние. Так что ваши сеттеры в основном не имеют никакого эффекта.

Теперь, когда вы переключаетесь на другое приложение - TextBox больше не считает его сфокусированным (обратите внимание, что он не просто использует свойство IsFocused, чтобы определить это). Таким образом, он скрывает FocusVisualElement, и здесь вы видите цвет границы, примененный вашим триггером.

Короче говоря, разработчики элементов управления не обязаны связывать одно свойство BorderBrush для каждого возможного состояния. Они могли бы предоставить что-то вроде свойства FocusedBorderBrush, но они этого не сделали - поэтому вам нужно перезаписать ControlTemplate TextBox (вы можете использовать шаблон по умолчанию, как указано выше по ссылке, и перезаписать некоторые цвета).

Другие вопросы по тегам