In Silverlight 4 it's possible to use implicit styling - and that is amazing! But what if I want to apply a style to all of my Buttons, CheckBoxes and RadioButtons (all inheriting from ButtonBase)? I can't set TargetType on the Style to ButtonBase - that doesn't work. Do I need to create a style to each of the 3 control types?
http://www.silverlightshow.net/items/Implicit-Styles-in-Silverlight-4.aspx
Try this
xamlgeek,
The following implicit styles work well for me. I first create some name/keyed styles, using common BasedOn styles whereever possible. Then I simply create the implicit styles BasedOn those named/keyed styles...
<Style x:Key="BaseStyle" TargetType="Control">
<Setter Property="FontFamily" Value="{StaticResource FontFamily}" />
<Setter Property="FontSize" Value="{StaticResource FontSize}" />
<Setter Property="Foreground" Value="{StaticResource FontBrush}" />
</Style>
<Style x:Key="BaseStyleCentered" TargetType="Control" BasedOn="{StaticResource BaseStyle}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style x:Key="CommonCheckBox" TargetType="CheckBox" BasedOn="{StaticResource BaseStyleCentered}">
<Setter Property="Cursor" Value="Hand" />
</Style>
<Style x:Key="CommonRadioButton" TargetType="RadioButton" BasedOn="{StaticResource BaseStyleCentered}">
<Setter Property="Cursor" Value="Hand" />
</Style>
<Style x:Key="CommonButton" TargetType="Button" BasedOn="{StaticResource BaseStyleCentered}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Padding" Value="10,0,10,0" />
<Setter Property="MinWidth" Value="{StaticResource ButtonWidth}" />
<Setter Property="MinHeight" Value="{StaticResource ButtonHeight}" />
</Style>
<Style TargetType="CheckBox" BasedOn="{StaticResource CommonCheckBox}">
</Style>
<Style TargetType="RadioButton" BasedOn="{StaticResource CommonRadioButton}">
</Style>
<Style TargetType="Button" BasedOn="{StaticResource CommonButton}">
</Style>
Good luck,
Jim
YinYangMe, YinYangMoney and FaceToFaceSoftware
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'm trying to factorize some styles with common properties.
So I'm using style inheritance but seems like it's not fully implemented.
Say I have these two styles:
<Style TargetType="ProgressBar">
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Margin" Value="10"></Setter>
</Style>
<Style TargetType="Rectangle">
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Margin" Value="10"></Setter>
</Style>
Here is my first try:
<Style x:Key="BaseStyle" TargetType="FrameworkElement">
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Margin" Value="10"></Setter>
</Style>
<Style BasedOn="{StaticResource BaseStyle}" TargetType="ProgressBar"></Style>
<Style BasedOn="{StaticResource BaseStyle}" TargetType="Rectangle"></Style>
It's running but the Visual Studio designer is not happy and it displays this error:
Can only base on a Style with target type that is base type of this style's target type.
AFAIK if I trust MSDN both ProgressBar and Rectangle should inherit from FrameworkElement.
Here is the full code:
<StackPanel>
<StackPanel.Resources>
<!--<Style TargetType="ProgressBar">
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Margin" Value="10"></Setter>
</Style>
<Style TargetType="Rectangle">
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Margin" Value="10"></Setter>
</Style>-->
<Style x:Key="BaseStyle" TargetType="FrameworkElement">
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Margin" Value="10"></Setter>
</Style>
<Style BasedOn="{StaticResource BaseStyle}" TargetType="ProgressBar"></Style>
<Style BasedOn="{StaticResource BaseStyle}" TargetType="Rectangle"></Style>
</StackPanel.Resources>
<ProgressBar Value="50"></ProgressBar>
<ProgressBar IsIndeterminate="True"></ProgressBar>
<Rectangle Width="100" Fill="BlueViolet"></Rectangle>
</StackPanel>
Note that the exact same code is working fine with WPF both in the designer and at runtime.
Is this a VS bug or a WinRT limitation?
Am I doing something wrong?
The default wpf MenuItem (on Menu) is constructed out of controls approx. like this:
grid; outer-rectangle; bg-rectangle; inner-rectangle; dockpanel; popup.
The dockpanel in turn consists of:
contentpresenter[icon]; path; contentpresenter[text]
The contentpresenter[text] consists of a TextBlock control.
What I want to achieve is to define a Style, as simple as possible, to change the VerticalAlignment property of this TextBlock, but only for the TextBlock in MenuItem, not in general.
<Style x:Key ="TextBlockCenterStyle" TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="MenuItem">
<Setter Property="FontSize" Value="11" />
<Setter Property="ItemContainerStyle" Value="TextBlockCenterStyle" />
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Style.Resources>
</Style>
I tried Style.Resources and ItemContainerStyle.
Cannot get it to work. ItemContainerStyle throws TargetInvocationException (from NullReferenceException) at run-time.
When it is possible it should be a general solution, something like FindChildControl?!
Did you try ItemContainerStyle?
Something like:
<MenuItem ItemContainerStyle = {StaticResource MyItemContainerStyle}../>
Then the MyItemContainerStyle have your
<Style x:Key ="MyItemContainerStyle" TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
=============== answer after EDIT ======================
try this:
<Style TargetType="MenuItem">
<Setter Property="FontSize" Value="11" />
<Setter Property="ItemContainerStyle" Value="{StaticResource TextBlockCenterStyle}" />
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Style.Resources>
</Style>
How can I have a WPF style that has no target type ( one that can be applied to all objects) ?
<Style x:Key="Basic" TargetType="???">
<Setter Property="FontFamily" Value="Tahoma"/>
<Setter Property="FontSize" Value="12"/>
</Style>
I want to base all other styles on this "basic" style.
Regards,
MadSeb
Append "Control." to the beginning of the Property, and remove the TargetType. Then, in the styles that derive from it, use BasedOn with a StaticResource pointing at the base Style.
<Style x:Key="basicStyle">
<Setter Property="Control.FontFamily" Value="Tahoma" />
<Setter Property="Control.FontSize" Value="12" />
</Style>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource basicStyle}">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource basicStyle}">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource basicStyle}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="2,4" />
</Style>
Is it possible to override styles in other styles. My best description will be some non working code:
<Style x:Key="SpecialFont" TargetType="Label">
<Setter Property="Foreground" Value="Red" />
<Setter Property="FontSize" Value="28" />
</Style>
<Style TargetType="GroupBox">
<Setter Property="GroupBox.Resources">
<Setter.Value>
<Style x:Key="SpecialFont" TargetType="Label">
<Setter Property="FontSize" Value="74" />
</Style>
</Setter.Value>
</Setter>
</Style>
The idea is that I will define a style to my "special text", the font which by default is red and have a size at 28, but if the label is placed in a groupbox it should have the size at 74, but maintain the red color. How is this possible? I would prefer to have to same style-key in my xaml, and not create a style based on another, e.g. SpecialFontBig based on SpecialFont.
Edit:
Okay... Another explanation.
I want result like this:
<Style x:Key="BaseFont" TargetType="Label">
<Setter Property="Foreground" Value="White" />
</Style>
<Style x:Key="Font1" TargetType="Label" BasedOn="{StaticResource BaseFont}">
<Setter Property="FontSize" Value="10" />
</Style>
<Style x:Key="Font2" TargetType="Label" BasedOn="{StaticResource BaseFont}">
<Setter Property="FontSize" Value="20" />
</Style>
<Style x:Key="Font3" TargetType="Label" BasedOn="{StaticResource BaseFont}">
<Setter Property="FontSize" Value="30" />
</Style>
<Style x:Key="Font1Red" TargetType="Label" BasedOn="{StaticResource Font1}">
<Setter Property="Foreground" Value="Red" />
</Style>
<Style x:Key="Font2Red" TargetType="Label" BasedOn="{StaticResource Font2}">
<Setter Property="Foreground" Value="Red" />
</Style>
<Style x:Key="Font3Red" TargetType="Label" BasedOn="{StaticResource Font3}">
<Setter Property="Foreground" Value="Red" />
</Style>
Where FontX is used outside my groupboxes, and FontXRed is used inside them. Is it possible to overrule this foreground, without making a lot of FontXRed styles? For example something like:
<Style x:Key="BaseFont" TargetType="Label">
# IF INSIDE A GROUPBOX
<Setter Property="Foreground" Value="Red" />
# ELSE
<Setter Property="Foreground" Value="White" />
</Style>
Styles can be based on other styles -> http://msdn.microsoft.com/en-us/library/system.windows.style.basedon.aspx
<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>
I have created a new GroupBox, which solved my problem okay:
class MyGroupBox : GroupBox
{
public MyGroupBox()
{
var newForegroundSetter = new Setter(ForegroundProperty, Brushes.Black);
var stylesToUpdate = new List<string>
{
"TextBlockShared",
"SmallFontTextBlock",
"MediumFontTextBlock",
"LargeFontTextBlock",
"FontControlShared",
"SmallFontControl",
"SmallFontHeaderControl",
"MediumFontControl",
"MediumFontHeaderControl",
"LargeFontControl",
"LargeFontHeaderControl",
"SmallButton",
"MediumButton",
"LargeButton",
};
foreach (var styleKey in stylesToUpdate)
{
var existingStyle = FindResource(styleKey) as Style;
if (existingStyle == null) continue;
var newStyle = new Style(existingStyle.TargetType, existingStyle);
newStyle.Setters.Add(newForegroundSetter);
Resources.Add(styleKey, newStyle);
}
}
}
In case someone stumbles upon this, here is the trick that usually works for me.
Basically, I define a style inside another styles resources. I usually base the inner style on a key-referenced style to use it in other places, but you could place a plain simple style in there as well.
<Style x:Key="SpecialFont" TargetType="Label">
<Setter Property="Foreground" Value="Red" />
<Setter Property="FontSize" Value="28" />
</Style>
<Style TargetType="GroupBox">
<Style.Resources>
<Style TargetType="Label"
BasedOn="{StaticResource SpecialFont}" />
</Style.Resources>
</Style>