49

I declared a style that I want to apply to ALL the buttons in the project, the style resides in the ResourceDictionary:

<Style TargetType="StackPanel">
    <Setter Property="Orientation" Value="Horizontal" />
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
</Style>

Now, in some window, I want to inherit from this style but add a value:

<Style TargetType="StackPanel"> 
    <Setter Property="Margin" Value="5"/>
</Style>

The problem is that it doesn't inherit from the global style, in order to inherit I have to assign a key to the global style:

<Style TargetType="StackPanel" x:Key="StackPanelStyle" />

And then in the window's XAML inherit (or/and override - optional) it:

<Style TargetType="StackPanel" BasedOn="StackPanelStyle" />

The problem is that if you assign a key, it's not global and you have to call it on each window/scope.

A solution to my question should be one of the two (is there anything else I am missing out?):

  1. Have a global style with a key, that is automatically applied to all its targeted controls in the entire application.
  2. A way to refer to the ResourceDictionary-level unnamed style without and override it.

I thought about redeclaring the styles near the named styles (in the ResourceDictionary) which actually works:

<!--In the ResourceDictionary-->
<Style x:Key="StackPanelStyle" TargetType="StackPanel">
    <Setter Property="Orientation" Value="Horizontal" />
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
<!--In the app.xaml-->
<Style TargetType="StackPanel" BasedOn="{StaticResource StackPanelStyle}"/>
<!--In the window/page scope-->
<Style TargetType="StackPanel" BasedOn="{StaticResource StackPanelStyle}"/

But I am looking for better stuff than stupidly redeclare all the styles.

Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632

3 Answers3

80

Try this:

<Style TargetType="{x:Type StackPanel}" BasedOn="{StaticResource {x:Type StackPanel}}">
  <!-- ... -->
</Style>

I have declared my base styles in a ResourceDictionary in App.xaml, if i override them in a specific window like this, it usually works.

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • Thanks buddy, that was short, quick and accurate! – Shimmy Weitzhandler Aug 22 '09 at 23:12
  • 2
    How About this in Silverlight? – MSNetDev May 06 '13 at 23:14
  • @MSNetDev I don't use Silverlight, but as far as i know it should work there, too. – Botz3000 May 07 '13 at 06:15
  • I wonder how we can get this: BasedOn="{StaticResource {x:Type StackPanel}}. x:Type is not supported in silverlight. – MSNetDev May 07 '13 at 20:30
  • This solution doesn't work for me unless I set the x:Key: ` – chriga Oct 29 '13 at 11:24
  • @chriga Have you tried setting the key to `x:Key="{x:Type StackPanel}"`? (at least if you're using WPF, no idea about silverlight) – Botz3000 Oct 31 '13 at 07:46
  • @Botz3000 When I use `x:Key="{x:Type StackPanel}"` explicitly, I get the same result. – chriga Nov 20 '13 at 11:07
  • @chriga I don't know then. Are you using Silverlight, or XAML for Windows Store Apps? Is the resource even in scope? It should work for normal Desktop WPF. – Botz3000 Nov 21 '13 at 07:32
  • I'd still love to hear how this can be done in Silverlight. There is no way to specify the x:Type syntax. It's a total pain in the rear having to specify the same property settings repeatedly throughout the XAML. Attempting to specify a style setter completely resets the style for that particular control. – Jake Shakesworth Oct 15 '15 at 01:21
  • Is there a way to do this if there isn't an App.xaml file? For example - in a control library? – Will Feb 26 '16 at 18:09
  • @Will The most important thing is that the defined Style is in scope wherever it should be used. This could just as well be in a shared ResourceDictionary or a default theme. – Botz3000 Feb 29 '16 at 07:51
  • The XAML Designer indicates that this won't work (`Hides resource from `) when it actually does – Joseph Nov 13 '19 at 22:39
1

Somewhere in global resource dictionary you define a base style with a key. This base style is targeted to a type which is base for all types for which you intend to apply that style. Then you define styles which target the types that you want and are based on the above mentioned base style.

<Style
    x:Key="upDownBaseStyle"
    TargetType="{x:Type Control}">
    <Setter
      Property="Margin"
      Value="2" />
    <Setter
      Property="HorizontalAlignment"
      Value="Stretch" />
    <Setter
      Property="VerticalAlignment"
      Value="Center" />
  </Style>

  <Style
    TargetType="{x:Type xceed:IntegerUpDown}"
    BasedOn="{StaticResource upDownBaseStyle}">
  </Style>

  <Style
    TargetType="{x:Type xceed:DoubleUpDown}"
    BasedOn="{StaticResource upDownBaseStyle}">
  </Style>

Now the two last styles are applied to all the IntegerUpDown and DoubleUpDown controls within your application without any mention of a key.

So the base rule: the base style must have the key to refer to it, and the derived styles may not and therefore they can be applied without any keys - only by target types.

user808128
  • 511
  • 1
  • 7
  • 24
0

I would suggest that what you may be looking for here is a master style or behavior scenario that is generally achieved by creating a user control. If you were to create a new button control with your 'global' style applied to it, then anywhere you would use that control you could simply add any 'New styles or override styles if / when they were needed.

If you haven't created a user control, they are easy to implement.

Hannish
  • 1,482
  • 1
  • 21
  • 33
PortageMonkey
  • 2,675
  • 1
  • 27
  • 32