Change button style when getting focus with <tab> but not when pressed
What i want to do
When navigating through the UI, most WPF controls display a dashed border when they receive keyboard focus. They do not display this border when they click on it.
I have a button with a custom control template and I want the same behavior above, but I don't just want to add a border, but I want to change the appearance of the button itself.
What i tried
-
Customization
FocusVisualStyle
. This doesn't give me much flexibility, because the template setFocusVisualStyle
is added on top of the button. As far as I know, this cannot be used to change (style, animation, ...) the button itself. -
Arrangement of a button using triggers using properties
IsFocused
and / orIsKeyboardFocused
, and EventTriggers with eventsGot/LostFocus
and / orGot/LostKeyboardFocus
. It doesn't work either because all of them seem to fire when I click on the button too.
Sample code
<StackPanel VerticalAlignment="Center" Width="150">
<StackPanel.Resources>
<ControlTemplate x:Key="CustomButtonTemplate" TargetType="Button">
<!--A simple black border with a content presenter-->
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="2">
<ContentPresenter x:Name="Presenter" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2" />
</Border>
<ControlTemplate.Triggers>
<!--When receiving keyboard focus modify the button text-->
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="Presenter" Property="Content" Value="I have keyboard focus" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="CustomFocusVisualStyle" TargetType="Control">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<!--Display a red border-->
<Border BorderThickness="1" CornerRadius="2" BorderBrush="Red" Margin="-1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<Button Content="I am a normal button" Margin="5" />
<Button Content="I am a custom button" Margin="5"
Template="{StaticResource CustomButtonTemplate}"
FocusVisualStyle="{StaticResource CustomFocusVisualStyle}" />
</StackPanel>
Note that the custom red border is only shown when you click between two buttons, not when you click on the buttons. The custom button text, however, changes anyway.
How can I achieve this?
source to share
Ok, after countless hours, I finally found a solution that works for my scenario. I hope this works for you too.
Forget FocusVisualStyle
it's trash. I am using MultiTrigger bound to IsKeyboardFocused=True
and IsMouseCaptured=False
.
This is what my style looks like:
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsKeyboardFocused" Value="True"/>
<Condition Property="IsMouseCaptured" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="BorderThickness" Value="2" />
</MultiTrigger>
</Style.Triggers>
This gives me a green ring around my button only when using tab, not when focusing with the mouse.
source to share