I am trying to set a global style for multiple control derived types by putting this in my app.xaml:
<Style TargetType="{x:Type Control}">
<Setter Property="Background" Value="{Binding BackgroundBrush, Source={x:Static m:Settings.Instance}, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="Foreground" Value="{Binding ForegroundBrush, Source={x:Static m:Settings.Instance}, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="BorderBrush" Value="{Binding ForegroundBrush, Source={x:Static m:Settings.Instance}, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="UseLayoutRounding" Value="True" />
</Style>
<Style TargetType="{x:Type Window}" BasedOn="{StaticResource {x:Type Control}}" />
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Control}}" />
Right now the window style only works in the visual studio design window and the button style doesn't work at all. What have I done wrong?
I've found sometimes that BasedOn is rather particular.
If you assign a key then it tends to work more often.
I'm not sure if the value bindings are causing your issue as i didn't make and external static class to use.
<Grid.Resources>
<Style x:Key="simpleStyle" TargetType="{x:Type Control}">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="Yellow" />
<Setter Property="BorderBrush" Value="CornflowerBlue" />
</Style>
<Style TargetType="{x:Type Control}" BasedOn="{StaticResource simpleStyle}" />
<Style TargetType="{x:Type Window}" BasedOn="{StaticResource simpleStyle}" />
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource simpleStyle}" />
</Grid.Resources>
<Button Height="50" Width="100">
Hello
</Button>
Related
Here is my Application ResourceDictionary
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CABI_PO_Manager.Themes">
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="14"/>
</Style>
<Style BasedOn="{StaticResource {x:Type TextBlock}}"
TargetType="TextBlock"
x:Key="YellowTextBlock">
<Setter Property="FontSize" Value="16"/>
<Setter Property="Foreground" Value="#d8b243"/>
</Style>
<Style BasedOn="{StaticResource {x:Type TextBlock}}"
TargetType="TextBlock"
x:Key="GreenTextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="Green"/>
</Style>
<Style BasedOn="{StaticResource {x:Type TextBlock}}"
TargetType="TextBlock"
x:Key="RedTextBlock">
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="#a01e21"/>
</Style>
</ResourceDictionary>
I want to have some default styles for a TextBlock which works
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="14"/>
</Style>
I found somewhere to use x:Key but I can't get it to work.
I will have several TextBlock's, How do I identify a TextBlock in the UI XAML as Red, Yellow or Green TextBlock and apply that style to them? This isn't recognized x:Key="GreenTextBlock"
<TextBlock x:Key="GreenTextBlock" Grid.Column="1" Margin="0,10,0,0" TextWrapping="Wrap" Text="PO Manager" VerticalAlignment="Top" TextAlignment="Center" FontWeight="ExtraBold"/>
If u want apply style on for example all TextBlocks in application, just use style without x:key defined e.g
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="14"/>
</Style>
When you are applying a style, use TargetType="{x:Type TextBlock}" instead of TargetType="TextBlock"
When do you use want to base on other style use
BasedOn="{StaticResource StyleUWantToBaseOn}"
where StyleUWantToBaseOn is style with x:Key property
And when you want to apply a specific style on lets say textblock you want to use Style property e.g:
<TextBlock Style="{StaticResource GreenTextBlock}" Grid.Column="1" />
I am having an issue trying to make use of the BasedOn attribute of Xaml styles. I created a fairly simple style as an example.
The project consists of two main files. MainWindow.xaml and SquareButtonStyle.xaml. SquareButtonStyle makes use of the FontAwesome.WPF project to quickly get some images.
MainWindow is basically a series of buttons with an image inside it and some text.
The goal of this example is to have three different button sizes. A "medium" size, and two variants, "small" and "large", based on the medium size.
The problem is most easily seen with the large variant. The center TextAlignment, Margin and Red text color set from the Medium style, which the large is based on, is lost. It seems that instead of inheriting the style and only override the specific property I am instead inheriting the default style and overriding the property.
What am I doing wrong? It seems the only way to correct this is to not bother with BasedOn, and just make three separate styles with the full list of properties being set. Is there a way to get around this?
SquareButtonStyle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button" x:Key="SquareButtonMediumStyle">
<Setter Property="Margin" Value="5" />
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Style.Resources>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Vertical" />
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="12" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Foreground" Value="Red"></Setter>
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonSmallStyle">
<Setter Property="Width" Value="55" />
<Setter Property="Height" Value="55" />
<Style.Resources>
<Style TargetType="StackPanel">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="10" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonLargeStyle">
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Style.Resources>
<Style TargetType="StackPanel">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="14" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
</ResourceDictionary>
MainWindow.xaml
<Window x:Class="XamlStyleExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SquareButtonStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<WrapPanel>
<WrapPanel.Resources>
<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" />
</WrapPanel.Resources>
<Button>
<StackPanel>
<TextBlock>Button 1</TextBlock>
</StackPanel>
</Button>
<Button>
<StackPanel>
<TextBlock>Button 2</TextBlock>
</StackPanel>
</Button>
<Button>
<StackPanel>
<TextBlock>Button 3</TextBlock>
</StackPanel>
</Button>
</WrapPanel>
<WrapPanel>
<WrapPanel.Resources>
<Style BasedOn="{StaticResource SquareButtonSmallStyle}" TargetType="Button" />
</WrapPanel.Resources>
<Button>
<StackPanel>
<TextBlock>Button 1</TextBlock>
</StackPanel>
</Button>
<Button>
<StackPanel>
<TextBlock>Button 2</TextBlock>
</StackPanel>
</Button>
<Button>
<StackPanel>
<TextBlock>Button 3</TextBlock>
</StackPanel>
</Button>
</WrapPanel>
<WrapPanel>
<WrapPanel.Resources>
<Style BasedOn="{StaticResource SquareButtonLargeStyle}" TargetType="Button" />
</WrapPanel.Resources>
<Button>
<StackPanel>
<TextBlock>Button 1</TextBlock>
</StackPanel>
</Button>
<Button>
<StackPanel>
<TextBlock>Button 2</TextBlock>
</StackPanel>
</Button>
<Button>
<StackPanel>
<TextBlock>Button 3</TextBlock>
</StackPanel>
</Button>
</WrapPanel>
</StackPanel>
</Window>
Update
Based Upon a few answers I came up with a solution, but I don't particularly like it. It seems messy.
I now have two keyed styles. One for the StackPanel and one for the TextBlock.
MainWindow.Xaml stays the same but SquaredButtonStyle.xaml now has:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="TextBlock" x:Key="SpecialTextBlockStyle">
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Foreground" Value="Red" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style TargetType="StackPanel" x:Key="MediumNestedStackPanel">
<Style.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource SpecialTextBlockStyle}" />
</Style.Resources>
</Style>
<Style TargetType="Button" x:Key="SquareButtonMediumStyle">
<Setter Property="Margin" Value="5" />
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Style.Resources>
<Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
</Style>
</Style.Resources>
</Style>
<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonSmallStyle">
<Setter Property="Width" Value="55" />
<Setter Property="Height" Value="55" />
<Style.Resources>
<!--
Implicit stack panel style in the scope of SquareButtonMediumStyle
inherits from MediumNestedStackPanel, adds stuff
-->
<Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
<Style.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource SpecialTextBlockStyle}" >
<Setter Property="FontSize" Value="10" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonLargeStyle">
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Style.Resources>
<Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
<Style.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource SpecialTextBlockStyle}">
<Setter Property="FontSize" Value="14" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
</ResourceDictionary>
Those nested StackPanel styles aren't going to be involved in the BasedOn inheritance for their containing styles. If you want to do that, you'll have to set up a separate inheritance hierarchy for the nested styles:
<Style TargetType="StackPanel" x:Key="MediumNestedStackPanel">
<Setter Property="Orientation" Value="Vertical" />
<Style.Resources>
<Style TargetType="fa:ImageAwesome">
<Setter Property="Height" Value="35" />
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="12" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Foreground" Value="Red"></Setter>
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</Style.Resources>
</Style>
<Style TargetType="Button" x:Key="SquareButtonMediumStyle">
<Setter Property="Margin" Value="5" />
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Style.Resources>
<!--
Implicit stack panel style in the scope of SquareButtonMediumStyle
inherits from MediumNestedStackPanel, adds nothing
-->
<Style
TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}"
/>
</Style.Resources>
</Style>
<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonSmallStyle">
<Setter Property="Width" Value="55" />
<Setter Property="Height" Value="55" />
<Style.Resources>
<!--
Implicit stack panel style in the scope of SquareButtonMediumStyle
inherits from MediumNestedStackPanel, adds stuff
-->
<Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
<Style.Resources>
<Style TargetType="fa:ImageAwesome" BasedOn="{StaticResource {x:Type fa:ImageAwesome}}">
<Setter Property="Height" Value="20" />
</Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="FontSize" Value="10" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonLargeStyle">
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Style.Resources>
<Style TargetType="StackPanel" BasedOn="{StaticResource MediumNestedStackPanel}">
<Style.Resources>
<Style TargetType="fa:ImageAwesome" BasedOn="{StaticResource {x:Type fa:ImageAwesome}}">
<Setter Property="Height" Value="60" />
<Setter Property="Margin" Value="5" />
</Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="FontSize" Value="14" />
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
Instead of defining an implicit TextBlock style inside the Button style(s), you should set the FontSize, Foreground, ... properties of the Button element itself:
<Style TargetType="Button" x:Key="SquareButtonMediumStyle">
<Setter Property="Margin" Value="5" />
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Setter Property="FontSize" Value="12" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="Foreground" Value="Red"></Setter>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
<Style.Resources>
<Style TargetType="StackPanel">
<Setter Property="Orientation" Value="Vertical" />
</Style>
</Style.Resources>
</Style>
<Style BasedOn="{StaticResource SquareButtonMediumStyle}" TargetType="Button" x:Key="SquareButtonLargeStyle">
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Setter Property="FontSize" Value="14" />
</Style>
Your current approach of using implicit styles for the TextBlocks won't work as you have already discovered. Please refer to the following link for more information about why:
Wpf, style is not being applied
[Using .NET Framework 4.5.1]
I have the following resource set in one of my WPF Windows:
<Window.Resources>
<Style TargetType="{x:Type FrameworkElement}" x:Key="baseStyle">
<Setter Property="Margin" Value="5"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type FrameworkElement}" x:Key="basePlusEnabled" BasedOn="{StaticResource baseStyle}">
<Setter Property="IsEnabled" Value="{Binding TestIsRunning, Mode=OneWay}"/>
</Style>
<Style TargetType="RadioButton" BasedOn="{StaticResource basePlusEnabled}">
<Setter Property="Padding" Value="4,-5,0,0"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Foreground" Value="{Binding TestIsRunning,
Converter={StaticResource testIsRunningForegroundConverter}, Mode=OneWay}"/>
</Style>
</Window.Resources>
However, the Padding style is not being applied to the RadioButtons in the window. (The other properties in the style are getting applied.) If I explicitly specify the Padding in each RadioButton, then it works. What am I missing here?
EDIT:
Sample RadioButton instance:
<RadioButton Grid.Column="4" Content="Iowa" GroupName="Facility"
IsChecked="{Binding IowaFacilityChecked1, UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}"/>
change TargetType="{x:Type FrameworkElement}" to TargetType="{x:Type RadioButton}"
I have a <ResourceDictionary> containing this:
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="..\..\Fonts\#Roboto"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
This works fine.
Now I've added another style:
<Style x:Key="MyText" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
However, after changing my <TextBlock> to <TextBlock Style="{StaticResource MyText}"/> - only the styles within the 2nd style block are picked up. E.g. the FontFamily, FontSize and TextWrapping are now ignored.
How can I have a default for a TextBlock, and then add to it? I don't want to add an x:Key to the 'default' style as this is in use throughout the system already.
I think you just need to base your keyed style on the type. See example below.
Note the BasedOn="{StaticResource {x:Type TextBlock}}"
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="Green" />
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
<Style x:Key="MyText" TargetType="TextBlock">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
<Style x:Key="MyAppendedStyles" TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock Text="Hello" />
<TextBlock Style="{StaticResource MyText}" Text="Style Key" />
<TextBlock Style="{StaticResource MyAppendedStyles}" Text="Style Key" />
</StackPanel>
When the user enters info I want all the controls to look and act the same way, as a result I have done the following.
The label and textbox controls are in a stackpanel as:
<StackPanel Style="{StaticResource ResourceKey=myInput}" HorizontalAlignment="Left">
<Label Content="Label" Name="label1" />
<TextBox Name="textBox1" ></TextBox>
</StackPanel>
the style "myInput" is:
<Style x:Key="myInput" TargetType="{x:Type StackPanel}">
<Style.Resources>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="FontSize" Value="12" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="5,-5,2,2"></Setter>
<Setter Property="Height" Value="23"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Style.Triggers>
<Trigger Property="IsFocused" Value="true">
<Setter Property="Background" Value="Blue" >
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
Now every time that I apply that style to a stackpanel that has a label and a textbox the background of the textbox changes to blue when it receives focus.
How could I set the label's fontweight to bold also when that event fires? I will like to do this with xaml.
Use a DataTrigger on your Label which looks to see if the keyboard focus is inside of the parent StackPanel that contains both objects
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="FontSize" Value="12" />
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding IsKeyboardFocusWithin,
RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}}">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>