4

Lets say I want to set background of all StackPanel in my application to some color. I got the following in my App.xaml:

<Style TargetType="StackPanel">
    <Setter Property="Background" Value="#222222" />
</Style>

This will work only if the StackPanel is a pure StackPanel, and the StackPanel must be under the App. However, background color of subclass of StackPanel or StackPanel in a popup dialog will not be changed by this. For example:

public class MyStackPanel : StackPanel { ... }

One way to solve the subclassing problem is to extend UserControl, and embed the StackPanel into the UserControl. This is ok as long as you don't need access to properties of the StackPanel.

Any idea?

What is the best way to do WPF theming?

David
  • 185
  • 4
  • 13
  • Possible duplicate of http://stackoverflow.com/questions/1026635/setting-a-styles-targettype-property-to-a-base-class – Adi Lester Sep 06 '12 at 18:30
  • @AdiLester How about controls that are in popup dialogs/windows? Is there a way to apply the same look and feel to them without duplicating the styles? – David Sep 07 '12 at 09:52

2 Answers2

3

You can create an implicit style for your custom class that inherits from the base class's style

<Style TargetType="StackPanel">
    <Setter Property="Background" Value="#222222" />
</Style>

<Style TargetType="{x:Type local:MyStackPanel}" 
       BasedOn="{StaticResource {x:Type StackPanel}}" />
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Thx. How about controls that are in popup dialogs/windows? Is there a way to apply the same look and feel to them without duplicating the styles? – David Sep 07 '12 at 09:53
  • 1
    @David If you put the style in `Application.Resources`, they should get applied to controls in popup dialogs or other windows. Otherwise, you can put all your styles in a Resource file, and simply import that file in each major section, such as `Window.Resources` – Rachel Sep 07 '12 at 11:25
  • Is it possible to do this within MyStackPanel? – David Sep 10 '12 at 10:24
  • @David Yes, since it inherits from a `StackPanel` you'd have to add it to `StackPanel.Resources` – Rachel Sep 10 '12 at 11:53
  • I tried that, doesn't work. The style is applied to child controls, but not the control that contains the style. – David Sep 10 '12 at 13:12
  • @David If you want to apply it to all instances of `MyStackPanel`, set it in `Application.Resources` or `Window.Resources`. If you want to apply it to a specific `MyStackPanel` only, set it in `MyStackPanel.Style`. If you want to set it to all instances of `MyStackPanel` inside a specific `MyStackPanel`, set it in `MyStackPanel.Resources` – Rachel Sep 10 '12 at 13:27
  • Why do I get a XamlParseException when I try this? It says I need to use the same type for TargetType and BasedOn, not different types, how you suggest. – ygoe Nov 17 '14 at 13:50
  • @LonelyPixel Does your custom type inherit from your `TargetType`? If so it should work.... if that's not the case I'd suggest posting a new question with the relevant information :) – Rachel Nov 17 '14 at 15:30
0

It is not a good practice to override WPF controls. As you mentioned, you need to design a UserControl descendant for this.

You can bind properties of your StackPanel (inside your UserControl) to the properties of your UserControl descendant, which you could add in code or to the builtin properties of UserControl.

<UserControl DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <StackPanel Background="{Binding Path=Background}">
    ...
    </StackPanel>
</UserControl>
Yurii Zhukow
  • 345
  • 1
  • 2
  • 10
  • Thank you, however, I don't want to go down this way. The reasons are extra work is required, and it is not flexible. For example, I will not be able to add controls to the stack panel. – David Sep 07 '12 at 09:57
  • 1
    While this doesn't apply to the StackPanel example: It's also not good practice to design a built-in WPF theme that doesn't match the native theme. Microsoft violated it for Windows 8 and thinks its great. So we have to fix that in our applications. For all controls. – ygoe Nov 17 '14 at 13:48