2
votes

I'm trying to make a wpf style that will allow me to: 1. Base alternate styles off a base style 2. Have the base style be a default that every control uses when no style is applied.

For example, I have code to make style for a button...

<!--Base Button-->
<Style TargetType="Button" x:Key="BaseButton">
    <Setter Property="Width" Value="auto"/>
    <Setter Property="MaxWidth" Value="100"/>
    <Setter Property="Height" Value="auto"/>
    <Setter Property="MaxHeight" Value="50"/>

    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Cursor" Value="Hand"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Opacity" Value=".85"/>
        </Trigger>
    </Style.Triggers>
</Style>
<!--Apply Base to any Button without a style-->
<Style TargetType="Button" BasedOn="{StaticResource BaseButton}"/>

and here is a style for a specific button...

<Style TargetType="Button" x:Key="DeleteBtn" BasedOn="{StaticResource BaseButton}">
    <Setter Property="Width" Value="100"/>
    <Setter Property="Height" Value="35"/>
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Image Source="(some url)" Height="16" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                    <Label Content="Delete" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                </StackPanel>                    
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

As you can see, I would like to be able to base the "DeleteBtn" Style off of the base, but also have the base be the default for every button placed on the screen that doesn't have a specific style set. This currently only works for buttons and no other control. The above example does work, but I can't seem to do the same thing for labels, textboxes etc. Any thoughts or input would be greatly appreciated :)

Here's an example of one that doesn't work..

<!--Base Icon-->
<Style TargetType="Image" x:Key="BaseIcon">
    <Setter Property="VerticalAlignment" Value="Top"/>
    <Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
<!--Apply Base to any Icon without a style-->
<Style TargetType="Image" BasedOn="{DynamicResource BaseIcon}"/>

It gives an error: 'DynamicResourceExtension' cannot be set on the 'BasedOn' property of type 'Style'. A 'DynamicResourceExtension' can only be set on a DependencyProperty of a DependencyObject.

2
Which controls exactly? Labels contain other controls inside which must be addressed when styled. Try a TextBlock instead a Label as its atomic.BlueM
Right now, images, textblocks, labels, combo boxes, checkboxes... it goes on and on don't work. I'd rather not post all of my code, so I've included an example above.Kapow36
It could help to enable WPF tracing msdn.microsoft.com/en-us/library/dd409960.aspxBlueM
See my example. It just works.BlueM

2 Answers

1
votes

Your example only works for Buttons because your "base" style is targeting buttons only. i.e.

TargetType="Button"

You can try creating a style that targets the parent FrameworkElement instead. Just be warned that not all properties are supported. Some properties are unique to the child control.

1
votes

It works for me, just tested it.

<Window.Resources>
    <Style TargetType="Label" x:Key="BaseLabel">
        <Setter Property="Background" Value="Red"/>
        <Setter Property="HorizontalContentAlignment" Value="Right"/>
    </Style>
    <Style TargetType="Label" BasedOn="{StaticResource BaseLabel}"/>
</Window.Resources>
<Grid>
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Orientation="Horizontal">
        <Label Width="100" Content="TestLabel1"/>
        <Label Width="100" Content="TestLabel1" Foreground="White"/>
    </StackPanel>
</Grid>

Edit: Added derived right alignment for fun.

enter image description here