Home > OS >  Tab-focused button border color and style
Tab-focused button border color and style

Time:04-27

I have this button in my User Control:

<Button
    x:Name="OkButton"
    Grid.Column="1"
    Command="{Binding Confirm}"
    IsDefault="True"
    IsEnabled="{Binding ConfirmEnabled}"
    Style="{StaticResource okCancelbuttons}"
    Visibility="{Binding ConfirmVisibility}">
    <Image
        Grid.Column="0"
        Margin="0"
        Source="{DynamicResource ResourceKey=confirm_res}" />

<!-- Style Dictionary -->
<Style x:Key="okCancelbuttons" TargetType="{x:Type Button}">
    <Setter Property="BorderBrush" Value="Black" />
    <Setter Property="BorderThickness" Value="3" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border
                    x:Name="Border"
                    Padding="3"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="0"
                    CornerRadius="3"
                    Style="{DynamicResource bordoPulsante}">
                    <ContentPresenter />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Resources>
        <Style TargetType="Image">
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="True">
                    <Setter Property="Opacity" Value="1" />
                </Trigger>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Opacity" Value="0.5" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Style.Resources>
</Style>

<Style x:Key="bordoPulsante" TargetType="{x:Type Border}">
    <Setter Property="BorderBrush" Value="Black" />
    <Setter Property="CornerRadius" Value="3" />
    <Setter Property="Background" Value="Transparent" />
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="{StaticResource brushverdechiaro}" />
        </Trigger>
        <Trigger Property="IsMouseOver" Value="False">
            <Setter Property="Background" Value="Transparent" />
        </Trigger>
    </Style.Triggers>
</Style>

It can happen that someone might want to navigate through the form hitting Tab repeatedly, but while the other controls are clearly highlighted, the buttons present this very tiny dashed black line which is almost impossible to see:

A from with text boxes and date pickers and an OK and cancel button that has a black dashed border around it after tabbing into it.

I've tried some modifications in the style, but nothing seems to have effect on it. Any suggestion?

CodePudding user response:

There is a dedicated property called FocusVisualStyle on FrameworkElement.

Gets or sets a property that enables customization of appearance, effects, or other style characteristics that will apply to this element when it captures keyboard focus.

Although you can create setters and supply a control template, this is not very flexible, as it adds the control template on top of the control template of the control itself.

A FocusVisualStyle is additive to any control template style that comes either from an explicit style or a theme style; the primary style for a control can still be created by using a ControlTemplate and setting that style to the Style property.

Here is an example of a focus visual style in your own style. The contained template draws a two pixels wide blue line around the button when focused.

<Style x:Key="okCancelbuttons" TargetType="{x:Type Button}">
    <Setter Property="FocusVisualStyle">
        <Setter.Value>
            <Style>
                <Setter Property="Control.Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Rectangle Margin="2" Stroke="Blue" StrokeThickness="2"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
    <!-- ...other markup. -->
</Style>

A more flexible approach is to use the IsFocused and IsKeyboardFocusWithin properties in setters of the style or the control template. The latter allows you to change properties of any control within the control template by referencing it with TargetName.

Please also note, that the FocusVisualStyle is explicitly set to {x:Null} in order to remove the default focus style with the dashed border.

<Style x:Key="okCancelbuttons" TargetType="{x:Type Button}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <!-- ...other setters. -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border
                  x:Name="Border"
                  Padding="3"
                  BorderBrush="{TemplateBinding BorderBrush}"
                  BorderThickness="0"
                  CornerRadius="3"
                  Style="{DynamicResource bordoPulsante}">
                    <ContentPresenter />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <!-- ...your control template setters. -->
                    </Trigger>
                    <Trigger Property="IsKeyboardFocusWithin" Value="True">
                        <!-- ...your control template setters. -->
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsFocused" Value="True">
            <!-- ...your style setters. -->
        </Trigger>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
            <!-- ...your style setters. -->
        </Trigger>
    </Style.Triggers>
    <!-- ...other markup. -->
</Style>

A word of caution from from the documentation on changing focus visual styles:

Conceptually, the appearance of focus visual styles applied to controls should be coherent from control to control. One way to ensure coherence is to change the focus visual style only if you are composing an entire theme, where each control that is defined in the theme gets either the very same focus visual style, [...]

Setting FocusVisualStyle on individual control styles that are not part of a theme is not the intended usage of focus visual styles.

For more information, you can refer to the following articles:

  • Related