Hi!
I'm looking for a simplest way to remove duplication in my WPF code.
Code below is a simple traffic light with 3 lights - Red
, Amber
, Green
. It is bound to a ViewModel that has one enum property State
taking one of those 3 values.
Code declaring 3 ellipses is very duplicative. Now I want to add animation so that each light fades in and out - styles will become even bigger and duplication will worsen.
Is it possible to parametrize style with State
and Color
arguments so that I can have a single style in resources describing behavior of a light and then use it 3 times - for 'Red', 'Amber' and 'Green' lights?
<UserControl.Resources>
<l:TrafficLightViewModel x:Key="ViewModel" />
</UserControl.Resources>
<StackPanel Orientation="Vertical" DataContext="{StaticResource ViewModel}">
<StackPanel.Resources>
<Style x:Key="singleLightStyle" TargetType="{x:Type Ellipse}">
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="Stroke" Value="Black" />
<Setter Property="Height" Value="{Binding Width, RelativeSource={RelativeSource Self}}" />
<Setter Property="Width" Value="60" />
<Setter Property="Fill" Value="LightGray" />
</Style>
</StackPanel.Resources>
<Ellipse>
<Ellipse.Style>
<Style TargetType="{x:Type Ellipse}" BasedOn="{StaticResource singleLightStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding State}" Value="Red">
<Setter Property="Fill" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<Ellipse>
<Ellipse.Style>
<Style TargetType="{x:Type Ellipse}" BasedOn="{StaticResource singleLightStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding State}" Value="Amber">
<Setter Property="Fill" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<Ellipse>
<Ellipse.Style>
<Style TargetType="{x:Type Ellipse}" BasedOn="{StaticResource singleLightStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding State}" Value="Green">
<Setter Property="Fill" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</StackPanel>