Reputation: 123
I start this question by saying that I don't have much experience using WPF, since I just started using it (All my previous C# experience is with Windows Forms and ASP.net).
Let's say that I have two styles defined in my App.xaml, one that defines a Blue button and one that defines a red button:
<Style x:Key="BlueButton" TargetType="Button">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF50D0FF"/>
<GradientStop Color="#FF0092C8" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="2" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF0092C8"/>
<GradientStop Color="#FF50D0FF" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="RedButton" TargetType="Button">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFAE00" Offset="0"/>
<GradientStop Color="Red" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="2" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="#FFFFAE00" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
How can I merge those two styles to make a general style that "contains both"?
EDIT:
Dmitriy Polyanskiy's answer works, but I still have to set every property every time I want to create a new style. Is there a way to do something like this: <Style x:Key="RedButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}" Color1="#FFFFAE00" Color2="Red" />
or
<Style x:Key="RedButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Color1" Value="#FFFFAE00" />
<Setter Property="Color2" Value="Red" />
</Style>
and then have the two gradient colors set automatically?
Upvotes: 0
Views: 1131
Reputation: 4322
Essentially, you are wanting to create are styles based off a 'parameterized' style.
What you need to do is create your base style using DynamicResources for the GradientStop's colors. Then, in the styles you base off it, override the resource colors.
BaseButtonStyle:
<Style x:Key="BaseButtonStyle" TargetType="Button">
<Style.Resources>
<Color x:Key="Color1">White</Color>
<Color x:Key="Color2">Gray</Color>
</Style.Resources>
<Setter Property="Foreground" Value="White" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource Color1}"/>
<GradientStop Color="{DynamicResource Color2}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="2" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource Color2}" />
<GradientStop Color="{DynamicResource Color1}" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
BasedOn Styles:
<Style x:Key="RedButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Style.Resources>
<Color x:Key="Color1">#FFFFAE00</Color>
<Color x:Key="Color2">Red</Color>
</Style.Resources>
</Style>
<Style x:Key="BlueButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Style.Resources>
<Color x:Key="Color1">#FF50D0FF</Color>
<Color x:Key="Color2">#FF0092C8</Color>
</Style.Resources>
</Style>
<Style x:Key="GreenButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Style.Resources>
<Color x:Key="Color1">Green</Color>
<Color x:Key="Color2">LightGreen</Color>
</Style.Resources>
</Style>
<Style x:Key="PurpleYellowButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Style.Resources>
<Color x:Key="Color1">Purple</Color>
<Color x:Key="Color2">Yellow</Color>
</Style.Resources>
</Style>
Screenshot of a stackpanel of buttons:
Upvotes: 2
Reputation: 18580
One way of achieving this is to define a style and instead of giving gradients in the style itself you can use DynamicResource like below. And then for each button you can define the a local resource LinearGradientBrush it is going to use and set your colors there.
<Window x:Class=""
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="BaseButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="{DynamicResource GradientBrushNormal}">
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="2" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{DynamicResource GradientBrushPressed}">
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<Button Style="{StaticResource BaseButtonStyle}" Content="Blue Button">
<Button.Resources>
<LinearGradientBrush x:Key="GradientBrushPressed" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF0092C8"/>
<GradientStop Color="#FF50D0FF" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="GradientBrushNormal" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF50D0FF"/>
<GradientStop Color="#FF0092C8" Offset="1"/>
</LinearGradientBrush>
</Button.Resources>
</Button>
<Button Style="{StaticResource BaseButtonStyle}" Content="Red Button">
<Button.Resources>
<LinearGradientBrush x:Key="GradientBrushPressed" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="#FFFFAE00" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="GradientBrushNormal" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFAE00" Offset="0"/>
<GradientStop Color="Red" Offset="1"/>
</LinearGradientBrush>
</Button.Resources>
</Button>
</StackPanel>
</Window>
Upvotes: 0
Reputation: 575
I have just created a quick example for you to show you how to do that. You should describe base style with common properties. And then just use BaseOn={StaticResource BaseStyle}
<Style x:Key="BaseButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border
CornerRadius="2"
Background="{TemplateBinding Background}">
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RedButton" TargetType="Button"
BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFAE00" Offset="0"/>
<GradientStop Color="Red" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="#FFFFAE00" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Upvotes: 0