tags:

views:

7481

answers:

8

In WPF, how would I apply multiple styles to a FrameworkElement? For instance, I have a control which already has a style. I also have a separate style which I would like to add to it without blowing away the first one. The styles have different TargetTypes, so I can't just extend one with the other.

+1  A: 

But you can extend from another.. take a look at the BasedOn property

 <Style TargetType="TextBlock">
  <Setter Property="Margin" Value="3" />
 </Style>

 <Style x:Key="AlwaysVerticalStyle" TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
  <Setter Property="VerticalAlignment" Value="Top" />
 </Style>
Arcturus
A: 

you can define a style like this:

    <Style x:Key=”buttonStyle”>
    <Setter Property=”Button.FontSize” Value=”22”/>
    <Setter Property=”Button.Background” Value=”Purple”/>
    <Setter Property=”Button.Foreground” Value=”White”/>
    <Setter Property=”Button.Height” Value=”50”/>
    <Setter Property=”Button.Width” Value=”50”/>
    <Setter Property=”Button.RenderTransformOrigin” Value=”.5,.5”/>
    <Setter Property=”Button.RenderTransform”>
    <Setter.Value>
    <RotateTransform Angle=”10”/>
    </Setter.Value>
    </Setter>
</Style>

and apply like this:

<Button Style=”{StaticResource buttonStyle}”>1</Button>
<Button Style=”{StaticResource buttonStyle}”>2</Button>
<Button Style=”{StaticResource buttonStyle}”>3</Button>

if you wants to define another style just give it another name like:

<Style x:Key=”buttonStyleBlue”>
<Setter Property=”Button.FontSize” Value=”22”/>
<Setter Property=”Button.Background” Value=”Blue”/>
<Setter Property=”Button.Foreground” Value=”Black”/>
<Setter Property=”Button.Height” Value=”50”/>
<Setter Property=”Button.Width” Value=”50”/>
<Setter Property=”Button.RenderTransformOrigin” Value=”.5,.5”/>
<Setter Property=”Button.RenderTransform”>
<Setter.Value>
<RotateTransform Angle=”10”/>
</Setter.Value>
</Setter>

and then apply it with the x:Key you defined it

darkdog
the author asked for appling multiple styles, tho
Steav
A: 

If I could use BasedOn, that would definitely work. But, because the two styles have to have different TargetTypes, I can't use BasedOn.

MojoFilter
+1  A: 

if you are not touching any specific properties, you can get all base and common properties to the style which's target type would be FrameworkElement. then, you can create specific flavours for each target types you need, without need of copying all those common properties again.

Greg
+16  A: 
cplotts
A: 

You can probably get something similar if applying this to a collection of items by the use of a StyleSelector, i have used this to approach a similar problem in using different styles on TreeViewItems depending on the bound object type in the tree. You may have to modify the class below slightly to adjust to your particular approach but hopefully this will get you started

public class MyTreeStyleSelector : StyleSelector
{
    public Style DefaultStyle
    {
        get;
        set;
    }

    public Style NewStyle
    {
        get;
        set;
    }

    public override Style SelectStyle(object item, DependencyObject container)
    {
        ItemsControl ctrl = ItemsControl.ItemsControlFromItemContainer(container);

        //apply to only the first element in the container (new node)
        if (item == ctrl.Items[0])
        {
            return NewStyle;
        }
        else
        {
            //otherwise use the default style
            return DefaultStyle;
        }
    }
}

You then apply this as so

 <TreeView>
     <TreeView.ItemContainerStyleSelector
         <myassembly:MyTreeStyleSelector DefaultStyle="{StaticResource DefaultItemStyle}"
                                         NewStyle="{StaticResource NewItemStyle}" />
     </TreeView.ItemContainerStyleSelector>
  </TreeView>
Dave
+3  A: 

WPF/XAML doesn't provide this functionality natively, but it does provide the extensibility to allow you to do what you want.

We ran into the same need, and ended up creating our own XAML Markup Extension (which we called "MergedStylesExtension") to allow us to create a new Style from two other styles (which, if needed, could probably be used multiple times in a row to inherit from even more styles).

Due to a WPF/XAML bug, we need to use property element syntax to use it, but other than that it seems to work ok. E.g.,

<Button
    Content="This is an example of a button using two merged styles">
    <Button.Style>
      <ext:MergedStyles
                BasedOn="{StaticResource FirstStyle}"
                MergeStyle="{StaticResource SecondStyle}"/>
   </Button.Style>
</Button>

I recently wrote about it here: http://swdeveloper.wordpress.com/2009/01/03/wpf-xaml-multiple-style-inheritance-and-markup-extensions/

+1  A: 

Bea Stollnitz has a good blog post about using a markup extension for this, under the heading "How can I set multiple styles in WPF?"

Wilka