Consolidating common WPF Styles
styles, wpf, wpf-4.0, xaml
Solution
I would create an attached property and have my triggers on that instead of having data triggers. Sample code as below:
Attached Property
public static class TextBlockBehavior
{
public static readonly DependencyProperty HasValueProperty =
DependencyProperty.RegisterAttached("HasValue", typeof(bool), typeof(TextBlockBehavior),
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.None));
public static void SetHasValue(DependencyObject depObject, bool value)
{
depObject.SetValue(HasValueProperty, value);
}
public static bool GetHasValue(DependencyObject depObject)
{
return (bool)depObject.GetValue(HasValueProperty);
}
}
and then your combined style would become
<Style x:Key="HasValueStyle" TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="behaviors:TextBlockBehavior.HasValue" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
<Trigger Property="behaviors:TextBlockBehavior.HasValue" Value="False">
<Setter Property="Background" Value="LightGreen"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="Normal"/>
</Trigger>
</Style.Triggers>
</Style>
and you can write your textblocks as
<TextBlock Style="{StaticResource HasValueStyle}"
behaviors:TextBlockBehavior.HasValue="{Binding Path=HasAlpha, UpdateSourceTrigger=PropertyChanged}" .../>
<TextBlock Style="{StaticResource HasValueStyle}"
behaviors:TextBlockBehavior.HasValue="{Binding Path=HasBeta, UpdateSourceTrigger=PropertyChanged}" .../>
Problem
I have various Style elements in my WPF XAML that are the same except for the data binding property, e.g.: ``` <Style x:Key="HasAlphaStyle" TargetType="TextBlock"> <Style.Triggers> <DataTrigger Binding="{Binding Path=HasAlpha, UpdateSourceTrigger=PropertyChanged}" Value="True"> <Setter Property="Background" Value="Red"/> <Setter Property="Foreground" Value="White"/> <Setter Property="FontWeight" Value="Bold"/> </DataTrigger> <DataTrigger Binding="{Binding Path=HasAlpha, UpdateSourceTrigger=PropertyChanged}" Value="False"> <Setter Property="Background" Value="LightGreen"/> <Setter Property="Foreground" Value="Black"/> <Setter Property="FontWeight" Value="Normal"/> </DataTrigger> </Style.Triggers> </Style> <Style x:Key="HasBetaStyle" TargetType="TextBlock"> <Style.Triggers> <DataTrigger Binding="{Binding Path=HasBeta, UpdateSourceTrigger=PropertyChanged}" Value="True"> <Setter Property="Background" Value="Red"/> <Setter Property="Foreground" Value="White"/> <Setter Property="FontWeight" Value="Bold"/> </DataTrigger> <DataTrigger Binding="{Binding Path=HasBeta, UpdateSourceTrigger=PropertyChanged}" Value="False"> <Setter Property="Background" Value="LightGreen"/> <Setter Property="Foreground" Value="Black"/> <Setter Property="FontWeight" Value="Normal"/> </DataTrigger> </Style.Triggers> </Style> ``` The style is applied to a control like: ``` <TextBlock Style="{StaticResource HasAlphaStyle}" .../> ``` Is there a way I can consolidate my HasAlphaStyle and HasBetaStyle so that the property setters don't have to be duplicated? The only difference between the two is the Binding Path to the property.