Search code examples
wpfbuttonwpf-style

WPF Button Style with roundend corners relative to the button size and colored line


I need help making a button looking like this:

enter image description here

It should have those rounded corners, no matter what the size of the button.

What I have so far:

A style for the Button in the App.xaml

<!-- Standard Button Colors-->
<SolidColorBrush x:Key="StandardButtonBackground" Color="#1C536F" />
<SolidColorBrush x:Key="StandardButtonForeground" Color="#FEFEFE" />

<!-- Standard Button Template-->
<Style x:Key="StandardButton" TargetType="Button">
    <Setter Property="Background" Value="{StaticResource StandardButtonBackground}" />
    <Setter Property="Foreground" Value="{StaticResource StandardButtonForeground}" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border CornerRadius="55" Background="{StaticResource StandardButtonBackground}">
                    <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Used in the view:

<Button Style="{StaticResource StandardButton}" Content="Test" FontSize="20"/>

It looks like this:

enter image description here

But the corners are in pixel-size, so when the size of the button changes, the corners do not accordingly.

And next thing is this colored line which should show a status. How can I add such a line?


Solution

  • You can use a converter to get the radius and a second border for the highlight.

    MainWindow.xaml

    <Window 
    
        ...
    
        >
        <Window.Resources>
            <!-- Converter -->
            <local:HeightToRadiusConverter x:Key="HeightToRadiusConverter"/>
            <!-- Standard Button Colors-->
            <SolidColorBrush x:Key="StandardButtonBackground" Color="#1C536F" />
            <SolidColorBrush x:Key="StandardButtonForeground" Color="#FEFEFE" />
            <SolidColorBrush x:Key="StandardButtonHighlight" Color="GreenYellow" />
            <!-- Standard Button Template-->
            <Style x:Key="StandardButton" TargetType="Button">
                <Setter Property="Background" Value="{StaticResource StandardButtonBackground}" />
                <Setter Property="Foreground" Value="{StaticResource StandardButtonForeground}" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <Border CornerRadius="{Binding ActualHeight, RelativeSource={RelativeSource Self}, Converter={StaticResource HeightToRadiusConverter}}"
                                    Background="{TemplateBinding Background}">
                                <Border Margin="5" BorderThickness="2" BorderBrush="{StaticResource StandardButtonHighlight}"
                                    CornerRadius="{Binding ActualHeight, RelativeSource={RelativeSource Self}, Converter={StaticResource HeightToRadiusConverter}}">
                                    <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
                                </Border>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Window.Resources>
        <Grid>
            <Button Style="{StaticResource StandardButton}" Content="Test" FontSize="20"/>
        </Grid>
    </Window>
    

    Converter

    public class HeightToRadiusConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double height = (double)value;
            return height / 2;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return new NotImplementedException();
        }
    }
    

    Resizing the window will resize the button accordingly.