Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Consolidating common WPF Styles

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.

like image 421
Stealth Rabbi Avatar asked Apr 04 '13 14:04

Stealth Rabbi


1 Answers

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}"            .../>
like image 176
Suresh Avatar answered Oct 05 '22 13:10

Suresh