Триггер 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 (вы можете использовать шаблон по умолчанию, как указано выше по ссылке, и перезаписать некоторые цвета).