0

I have created a custom Button component in my WinUI3 application. The code for the same is given below.

<Button
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Background="Transparent"
    BorderThickness="0"
    Width="{x:Bind Width}"
    Height="{x:Bind Height}">
    <StackPanel
        Orientation="Vertical"
        VerticalAlignment="Center"
        HorizontalAlignment="Center">
        <FontIcon
            VerticalAlignment="Center"
            FontFamily="{StaticResource SymbolThemeFontFamily}"
            Glyph="{x:Bind Glyph}"
            FontSize="{x:Bind IconSize}" />
        <TextBlock
            VerticalAlignment="Center"
            HorizontalAlignment="Center"
            Margin="0,10,0,0"
            Text="{x:Bind Label}"
            FontSize="{x:Bind FontSize}" />
    </StackPanel>
</Button>

By default, it is giving a very light grey colour background which is hardly visible in the white background of the page. So I want to change the background colour of the button when the cursor hovers over it, or when the button is in focus via tabs. Current Button on hover

How can I achieve this?

I tried <ControlTemplate>, <VisualStateManager.VisualStateGroups> <VisualState x:Name="PointerOver"> and <Storybaord> but am unable to make it work.

I would want it to have a colour of my choice, so that it is more prominent. Just like it is in the default <AppBarButton> Default WinUI3 AppBarButton on hover

Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21

1 Answers1

1

As you can see in the DefaultButtonStyle (generic.xaml), the VisualState PointerOver changes the Button's Background to a ThemeResource called ButtonBackgroundPointerOver.

(Check this answer if you don't know how to find the generic.xaml.)

You can override the ButtonBackgroundPointerOver like this:

<Button>
    <Button.Resources>
        <Button.Resources>
            <SolidColorBrush
                x:Key="ButtonBackgroundPointerOver"
                Color="HotPink" />
        </Button.Resources>
    </Button.Resources>
</Button>

Unfortunately, the Button control doesn't have a VisualState for focused event. What you can do is change the Button's Background using GotFocus and LostFocus events in the code-behind, but you can also create a custom control:

AwesomeButton.cs

public class AwesomeButton : Button
{
    public static readonly DependencyProperty FocusedBackgroundProperty =
        DependencyProperty.Register(
            nameof(FocusedBackground),
            typeof(Brush),
            typeof(AwesomeButton),
            new PropertyMetadata(default));

    public AwesomeButton()
    {
        GotFocus += AwesomeButton_GotFocus;
        LostFocus += AwesomeButton_LostFocus;
    }

    public Brush FocusedBackground
    {
        get => (Brush)GetValue(FocusedBackgroundProperty);
        set => SetValue(FocusedBackgroundProperty, value);
    }

    private Brush? BackgroundBeforeGettingFocus { get; set; }

    private void AwesomeButton_GotFocus(object sender, RoutedEventArgs e)
    {
        BackgroundBeforeGettingFocus = Background;
        Background = FocusedBackground;
    }

    private void AwesomeButton_LostFocus(object sender, RoutedEventArgs e)
    {
        Background = BackgroundBeforeGettingFocus;
    }
}

and use it like this:

<local:AwesomeButton
    x:Name="AwesomeButton"
    Width="{x:Bind Width}"
    Height="{x:Bind Height}"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Background="Transparent"
    BorderThickness="0"
    FocusedBackground="LightGreen">
    <Button.Resources>
        <SolidColorBrush
            x:Key="ButtonBackgroundPointerOver"
            Color="HotPink" />
    </Button.Resources>
    <StackPanel
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        Orientation="Vertical">
        <FontIcon
            VerticalAlignment="Center"
            FontFamily="{StaticResource SymbolThemeFontFamily}"
            FontSize="{x:Bind IconSize}"
            Glyph="{x:Bind Glyph}" />
        <TextBlock
            Margin="0,10,0,0"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            FontSize="{x:Bind FontSize}"
            Text="{x:Bind Label}" />
    </StackPanel>
</local:AwesomeButton>
Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21