Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify button style when receiving focus via <tab> but not when clicked on

What I want to do

When tabbing through the user interface most WPF controls display a dashed border when they receive keyboard focus. They do not display this border when they are clicked on with the mouse.

I have a button with a custom control template and I want the same behavior as above however I don't just want to add a border but I want to modify the appearance of the button itself.

What I tried

  • Customizing the FocusVisualStyle. This doesn't give me enough flexibility because the template set by the FocusVisualStyle is added on-top of the button. As far as I am aware this can not be used to modify (style, animate,...) the button itself in any way.

  • Styling the button using Triggers with the IsFocused and/or IsKeyboardFocused properties as well as EventTriggers with the Got/LostFocus and/or Got/LostKeyboardFocus events. That doesn't work either because all of those seem to get triggered when I click on the button too.

Example 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 how the custom red focus border shows up only when you tab between the two buttons but not when you click the buttons. The custom button text however gets modified in either case.

How can I achieve this?

like image 308
Roman Reiner Avatar asked Oct 22 '25 12:10

Roman Reiner


1 Answers

Ok, after countless hours, I finally found a solution that works for my scenario. I hope it works for yours as well.

Forget FocusVisualStyle, it is junk. I'm using a MultiTrigger that is tied to IsKeyboardFocused=True and IsMouseCaptured=False.

Here is what my style looks like now:

<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 tabbed to, not when focused via mouse.

like image 107
Matt Jacobi Avatar answered Oct 25 '25 03:10

Matt Jacobi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!