I wish to have one WPF Custom Control Library
with multiple styles and to be able to access deferent style for deferent use.
Assuming i have a project called IconButtonControl
with one cs
class file with all the needed dependencies, several .xaml
files such: Blue.Generic.xaml
, Green.Generic.xaml
(and so on) in which they all referenced in the main Generic.xaml
using <ResourceDictionary.MergedDictionaries>
.
<Style TargetType="{x:Type local:IconButton}" x:Key="BlueButton">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="FlowDirection" Value="LeftToRight"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:IconButton}">
<Grid Background="Transparent">
<Viewbox Height="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IconScale}">
<Path Name="PurplePath"
Fill="{StaticResource LightBlueBrush}"
Stretch="Fill"
Data="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IconPath}"/>
</Viewbox>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
<LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource Blue}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
<LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource LightBlue}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="PreviewMouseLeftButtonDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
<LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource DeepBlue}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="PreviewMouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
<LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource Blue}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:IconButton}" x:Key="GreenButton">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="FlowDirection" Value="LeftToRight"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:IconButton}">
<Grid Background="Transparent">
<Viewbox Height="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IconScale}">
<Path Name="PurplePath"
Fill="{StaticResource LightGreenBrush}"
Stretch="Fill"
Data="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IconPath}"/>
</Viewbox>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
<LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource Green}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
<LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource LightGreen}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="PreviewMouseLeftButtonDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
<LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource DeepGreen}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="PreviewMouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="path" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)">
<LinearColorKeyFrame KeyTime="0:0:0:0.1" Value="{StaticResource Green}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And so on...
#region Dependency Properties
public static readonly DependencyProperty IconScaleProperty = DependencyProperty.Register(nameof(IconScale), typeof(double), typeof(IconButton), new PropertyMetadata(10.0));
public static readonly DependencyProperty IconPathProperty = DependencyProperty.Register(nameof(IconScale), typeof(Geometry), typeof(IconButton));
#endregion Dependency Properties
#region Properties
public double IconScale
{
get => (double)GetValue(IconScaleProperty);
set => SetValue(IconScaleProperty, value);
}
public Geometry IconPath
{
get => (Geometry)GetValue(IconPathProperty);
set => SetValue(IconPathProperty, value);
}
#endregion Properties
How can I use <IconButtonControl:IconButton>
with GreenButton
style for example?
If there is a property for setting the Style
of the IconButton
(which I assume is part of the template of the IconButtonControl
) you could use this one:
<local:IconButtonControl IconButtonStyle="{StaticResource GreenButton}" />
If there is no such property like IconButtonStyle
, you may be able to change the Style
of the IconButton
using an implicit Style
:
<local:IconButtonControl>
<local:IconButtonControl.Resources>
<Style TargetType="{x:Type local:IconButton}" BasedOn="{StaticResource GreenButton}" />
</local:IconButtonControl.Resources>
</local:IconButtonControl>
Whether this works depends on how the template of the IconButtonControl
is defined. If the template explicitly sets the Style
of the IconButton
, you will have to create a custom template for the entire IconButtonControl
to be able to change the Style
of the "inner" IconButton
.