inherit style from default style - wpf

In my project there is a custom style for text box. It is defined as:
<Style TargetType="TextBox"/>
So it is applied to all text box child controls by default.
I need to create another style that is based on default style. But how do I specify in the BasedOn attribute that my new style should use the default style?

Use the type of the control you would like to extend
BasedOn="{StaticResource {x:Type TextBox}}"
Full example:
<Style x:Key="NamedStyle" TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter property="Opacity" value="0.5" />
</Style>

#Aphelion has the correct answer. I would like to add that the order in which items are defined in the ResourceDictionary matter.
If you override the default style of a slider and you want to base another slider style on that, you must declare the "based on" slider after the override style.
For example, if you do this:
<Style x:Key="BlueSlider" TargetType="{x:Type Slider}" BasedOn="{StaticResource {x:Type Slider}}">
<Setter Property="Background" Value="Blue"/>
</Style>
<Style TargetType="{x:Type Slider}">
<Setter Property="Foreground" Value="Yellow"/>
</Style>
BlueSlider will have a blue background with the default (white) foreground.
But if you do this:
<Style TargetType="{x:Type Slider}">
<Setter Property="Foreground" Value="Yellow"/>
</Style>
<Style x:Key="BlueSlider" TargetType="{x:Type Slider}" BasedOn="{StaticResource {x:Type Slider}}">
<Setter Property="Background" Value="Blue"/>
</Style>
BlueSlider will have a blue background and a yellow foreground.

Related

Wpf - Create a Style in a resource dictionary that sets properties of children of a grid [duplicate]

Is it possible to define a ResourceDictionary in a Style?
For example, suppose I wanted to have two different Styles for StackPanels and in one I want all the buttons to be blue and the other I want them to be red. Is this possible?
Something like
<Style x:Key="RedButtonsPanel" TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Horizontal" />
<Setter Property="StackPanel.Resources">
<Setter.Value>
<ResourceDictionary>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
</Setter.Value>
</Setter>
</Style>
The above code fails with an error about the Property value of a Setter cannot be null (even though it's obviously not null).
I can do something like
<ResourceDictionary x:Key="RedButtons">
<Style TargetType="{x:Type Button}">
<Setter Property="Width" Value="100" />
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
<StackPanel Resources={StaticResource RedButtons} />
However I was wondering if there was a way to merge the ResourceDictionary into the style.
Try adding the Style(s) for each TargetType to the DockPanel Style.Resources.
I did something similar with a DockPanel Style. Wanted all Buttons or Separators added to the DockPanel to get styled in a consistent manner.
Here's a sample:
<Style x:Key="DockPanelToolBarStyle" TargetType="{x:Type DockPanel}">
<Style.Resources>
<Style TargetType="Button" BasedOn="{StaticResource ButtonToolBarStyle}" />
<Style TargetType="Separator" BasedOn="{StaticResource SeparatorToolBarStyle}" />
</Style.Resources>
<Setter Property="Height" Value="45"/>
<Setter Property="Background" Value="{StaticResource ToolBarBrush}"/>
</Style>
StackPanel.Resources is not a DependencyProperty and therefore I don't believe you will be able to set that property within the style.

What is the Equivalent in XAML

What is the equivalent in XAML? Make Background Red for every Label which are inside a StackPanel.
/*In CSS*/
StackPanel Label {
Background:Red
}
//XAML
<Style TargetType="Label">
<!-- Condition??? -->
<Setter Property="Background" Value="Red"/>
</Style>
You can put a default Style for Labels in a default Style for StackPanels:
<Style TargetType="StackPanel">
<Style.Resources>
<Style TargetType="Label">
<Setter Property="Background" Value="Red"/>
</Style>
</Style.Resources>
</Style>

Style breaks when x:Key is added

Under <Window.Resources>, I have the following style defined:
<Style TargetType="TextBox">
<Setter Property="Height" Value="22" />
<Setter Property="Width" Value="125" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="WhiteSmoke" />
</Style>
It works fine until I needed to inherit the style on another style
<Style BasedOn="{StaticResource TextBoxStyle}" TargetType="{x:Type PasswordBox}">
Which means I need to add the x:Key=TextBoxStyle to the Text box style above.
But when I do this, the styling for the text box breaks altogether.
I tried doing the same to Button styling, and the same thing happens, where the style will break if I add a key to it.
The only solution I thought of is to individually add the style to the elements, but that is what I am trying not to do.
No, you do not need to add x:Key to reference it:
<Style BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type PasswordBox}">
Well to provide a better understandability and maintainance, I would prefer the following approach. IMHO, another programmer could get better into the code, if the implicities are reduced to a minimum.
<Style x:Key="BasicTextBoxStyle" TargetType="{x:Type TextBox}">
<!--some settings here-->
</Style>
<!--Declare BasicTextBoxStyle as default style for TextBoxes-->
<Style BasedOn="{StaticResource BasicTextBoxStyle}" TargetType="{x:Type TextBox}"/>
<!--Create some special style based on the basic style-->
<Style BasedOn="{StaticResource BasicTextBoxStyle}" TargetType="{x:Type PasswordBox}">
<!--some more specific settings-->
</Style>
Just my two cents...

Putting Styles on controls inside a Grid style

I want' to define that every control of specific type inisde a grid gets a Style. This is easy just put the styles with TargetType inside the grid resources. But what then if I wan't to reuse this grid as a style?
I can create a grid style and have a setter to resources but can only put one style there.
<Style x:Key="GridStyle" TargetType="Grid">
<Setter Property="Resources">
<Setter.Value>
<Style TargetType="TextBlock" BasedOn="{StaticResource MainText}" />
<Style TargetType="{x:Type RowDefinition}">
<Setter Property="Height" Value="Auto"/>
</Style>
<Style TargetType="Button" BasedOn="{StaticResource MainButton}" />
</Setter.Value>
</Setter>
</Style>
Won't work because the setter can only put one style in.
This is probably something very simple but I'm not getting it and I don't wan't to repeat these styles in each and every grid.
If you put the Styles inside the Resources of the outer style, they will be in scope inside the grids:
<Style x:Key="GridStyle" TargetType="Grid">
<Style.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource MainText}" />
<Style TargetType="{x:Type RowDefinition}">
<Setter Property="Height" Value="Auto"/>
</Style>
<Style TargetType="Button" BasedOn="{StaticResource MainButton}" />
</Style.Resources>
</Style>

"inherit" style of theme in wpf

I'm using one of the themes in CodePlex and I want to add some modifications on the style but not to change their code. How can I inherit the theme style?
<Style x:Key="Style1">
<Setter Property="Control.Background" Value="Yellow"/>
</Style>
<Style x:Key="Style2" BasedOn="{StaticResource Style1}">
<Setter Property="Control.Foreground" Value="Blue"/>
</Style>
MSDN reference: http://msdn.microsoft.com/en-us/library/system.windows.style.basedon.aspx
Another example (basing a style on a style with no explicit key):
<Style x:Key="Style3" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="Control.Foreground" Value="Blue"/>
</Style>
Just load the extending resource dictionary after the base resource dictionary via XAML or code.

Resources