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
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? 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>
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...
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>
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.