Some people dislike Bootstrap because many websites out there use the starting Bootstrap template, hence the notion that all Bootstrap sites look the same. Let me just say, they don't. It's probably fairer to say that website looks alike if their designers are lazy. Bootstrap itself is a great tool.
I commonly use Bootstrap buttons, because they come with good default styles which can give hints to the users. I mainly use the primary, default, and danger styles to indicate the kind of actions that are being performed. So today, I will be discussing how to get those Bootstrap-style buttons in WPF.
First, what do they look like? Here is a sample from the website (using Chrome):
This style matches pretty well with a so-called "modern ui" style.
Here is what my WPF attempt at these buttons looks like:
Here is the XAML style for these buttons, including disable, hover and click effects.
<Style x:Key="btn" TargetType="Button">
<Setter Property="FontFamily" Value="Helvetica Neue,Helvetica,Arial,sans-serif"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="12,8"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border Name="border" CornerRadius="4" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<Border Name="dropShadowBorder" CornerRadius="4" BorderBrush="Transparent" BorderThickness="0" Visibility="Hidden">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,0.16">
<GradientStop Color="#22000000" Offset="0"/>
<GradientStop Color="#00000000" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<ContentPresenter Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<!--default button highlight-->
<Trigger Property="Button.IsDefaulted" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<!--inner drop shadow when pressed / checked-->
<Trigger Property="IsPressed" Value="True">
<Setter Property="Visibility" TargetName="dropShadowBorder" Value="Visible"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Visibility" TargetName="dropShadowBorder" Value="Visible"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="border" Value="0.60"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="btn-default" TargetType="Button" BasedOn="{StaticResource btn}">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="#333"/>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#fff"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#ccc"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#e6e6e6"/>
<Setter Property="BorderBrush" Value="#adadad"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#e6e6e6"/>
<Setter Property="BorderBrush" Value="#adadad"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Background" Value="#e6e6e6"/>
<Setter Property="BorderBrush" Value="#adadad"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="btn-primary" TargetType="Button" BasedOn="{StaticResource btn}">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="#fff"/>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#428bca"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#357ebd"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#3071a9"/>
<Setter Property="BorderBrush" Value="#285e8e"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#3071a9"/>
<Setter Property="BorderBrush" Value="#285e8e"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Background" Value="#3071a9"/>
<Setter Property="BorderBrush" Value="#285e8e"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="btn-success" TargetType="Button" BasedOn="{StaticResource btn}">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="#fff"/>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#5cb85c"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#4cae4c"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#449d44"/>
<Setter Property="BorderBrush" Value="#398439"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#449d44"/>
<Setter Property="BorderBrush" Value="#398439"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Background" Value="#449d44"/>
<Setter Property="BorderBrush" Value="#398439"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="btn-info" TargetType="Button" BasedOn="{StaticResource btn}">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="#fff"/>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#5bc0de"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#46b8da"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#31b0d5"/>
<Setter Property="BorderBrush" Value="#269abc"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#31b0d5"/>
<Setter Property="BorderBrush" Value="#269abc"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Background" Value="#31b0d5"/>
<Setter Property="BorderBrush" Value="#269abc"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="btn-warning" TargetType="Button" BasedOn="{StaticResource btn}">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="#fff"/>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#f0ad4e"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#eea236"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#ec971f"/>
<Setter Property="BorderBrush" Value="#d58512"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#ec971f"/>
<Setter Property="BorderBrush" Value="#d58512"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Background" Value="#ec971f"/>
<Setter Property="BorderBrush" Value="#d58512"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="btn-danger" TargetType="Button" BasedOn="{StaticResource btn}">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="#fff"/>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#d9534f"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#d43f3a"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#c9302c"/>
<Setter Property="BorderBrush" Value="#ac2925"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#c9302c"/>
<Setter Property="BorderBrush" Value="#ac2925"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Background" Value="#c9302c"/>
<Setter Property="BorderBrush" Value="#ac2925"/>
</Trigger>
</Style.Triggers>
</Style>
Then to utilize these, you only have to set the style on the button. It's style name matches the class name for the equivalent bootstrap button. For example:
<Button Content="Default" Style="{StaticResource btn-default}"/>
Notes: Xaml styling is not as robust as CSS, and is a lot more verbose. You can't set more than one style, but this capability wasn't needed in this case.
3 comments:
this is amazing. thank you. any more bootstrap mimics for me to use? :)
None at this time. My foray into WPF has ended for now.
Thank you!
Post a Comment