I "re-themed" Button by putting a style with TargetType (but no x:key) in a ResourceDictionary and telling other developers to merge it. Now, if they want to further style the control, they need to use BasedOn.
Is there a way I could have themed Button without requiring consumers to used BasedOn?
Does anyone know how to set the default font (color, in this case) across an entire Silverlight Application?
It's a rather large legacy application so I don't think I can take advantage of themes. I've created styles etc but don't fancy doing this across the whole app, and them maintaining them etc..
I don't have much Silverlight/Xaml experience so please detail your answer like I'm stupid!
Thanks
If you wrap your entire application with a ContentControl and specify its Foreground, all controls inherit the Foreground color. If one of your resource file specify the Foreground for any of your child controls, the Foreground should flow down to all of them... :(
Another solution is to use implicit style like in Silverlight toolkit theme files. You can see one resource for the font color and this color is applied on each UI controls via implicit style.
Theme.xaml
<SolidColorBrush x:Key="TextBrush" Color="#FF152937" />
...
<Style TargetType="Button">
<Setter Property="Foreground" Value="{StaticResource TextBrush}" />
So if your resources files override Foreground properties, you have to change that like in Theme.xaml toolkit file. Create a unique Foreground Brush and apply with implicit style on each control.
If someone has a better solution ???
I am relatively new to the WPF scene, and am having a problem understanding how styles are reused amongst controls.
My example situation is this, I'm making a control that needs a Toggle button. I want this ToggleButton to look like the 'expand' Button on a TreeViewItem. How would apply the TreeViewItem's button style to my own button?
From my searching I have a feeling that it isn't possible without copying XAML, but I can't justify to myself why anyone would make a UI framework that limited.
Thanks in advance.
I'm not sure there's a way of retrieving the default style/template from something and applying it to another control in XAML, although you may be able to to it in code. Although that would pose the problem that you just want to get the button part of the template and it's easier (not to mention cleaner) just to write a new style rather than hacking around to get just that part of the template.
The problem with restyling buttons is that when pressed they will go back to their default pressed appearance, same for when they are hovered. What you want to do is change the ControlTemplate of the button.
When I was starting out in WPF I found this tutorial
to be quite a useful introduction to the process.
I'd recommend getting a copy of ShowMeTheTemplate to give you access to most of the default templates for controls as that will save a lot of the basic work and give you an insight into how the controls work.
When you've created your control template (or any style/template for that matter), you can store it in a resource dictionary and apply it to controls by referencing it from the relevant property using the StaticResource markup extension.
Example:
(In a resource dictionary, for example App.Resources):
<Style x:Key="myStyle" TargetType="Button">
<Setter Property="Width" Value="70" />
</Style>
Used in a button:
<Button Style="{StaticResource myStyle}" />
Hope this helps get you started.
I want to make 2 different styles for the ToolBar control: One is based on black buttons and one on silver buttons. But I can't figure out how to apply my button styles to its own toolbar styles. The following only allows one style for the buttons:
<Style x:Key="{x:Static ToolBar.ButtonStyleKey}"
BasedOn="{StaticResource BlackButtonStyle}"
TargetType="{x:Type Button}"/>
Not sure if this will work or not... I'm assuming you only want one style at a time (if you had two tool bars and wanted each to be different you need two different styles with two different keys)...
that said, when you want to change the style from black to silver, can you get get your resource in code, and set the BasedOn property of that style to your SilverButtonStyle resource?
In Expression Blend you can create a font-size of say 18 and then create a "font-size resource".
Coming at this from HTML/CSS, I cannot think of when I would want to make a style for a "font-size" and one for a "font-style" and one for a "font-weight". Instead I want to make a font called "CompanyHeader" and have 10 different attributes set in it, e.g. font-weight, font-style, font-size, color,etc.
Why is this different in Expression Blend, XAML, what is the sense of making a style/resource for each attribute?
this graphic shows how you can click on a little button on each attribute to change it into a resource:
alt text http://tanguay.info/web/external/blendStyles.png
I have no experience with Blend, but styles in XAML can include more than one attribute, more then that, since unlike css you can only apply one style to an element you can't combine multiple one-attribute styles.
Here is an example for a style that set multiple properties:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="MyStyle" TargetType="{x:Type Label}">
<Setter Property="Width" Value="125"/>
<Setter Property="Height" Value="25"/>
<Setter Property="Background" Value="Red"/>
</Style>
</Page.Resources>
<Label Style="{StaticResource MyStyle}"/>
</Page>
Note that if I wanted to break the style into 3 smaller styles each setting one property I couldn't use them because the Label's Style property can only accept one style.
I think they likely allow for the creation of single resources for FontFamily, FontWeight, etc. to allow them to be used across many styles in the application. By placing a single property in a resource you can effect all styles using that resource at once. If you weren't using a resource but were attempting to use a consistent FontFamily across your whole application (or a portion of it) then you had to go through each style one at a time in order to update it.
In order to make a style with multiple properties in blend you can do the following:
Select the control you wish to style (the control's type will be used as the TargetType for the style)
From the menu select Object->Edit Style->Create Empty
Enter the Key you would like to assign to the style (this is the name that you will use to reference the style)
Go to the properties tab and begin to apply the look/feel that you want for that style
It allows you to reuse the font details at am more granular level than having to define all elements of the font definition. You might have several styles that all inherit from the same font-size definition. Your designer can then change the font-size and all the styles that use it then automatically have an updated appearance.
Each instance of a font will use its own resources, doesn't matter if multiple such defenitions refer to same font.
Using same font in two different styles will end-up with two instances of the font (when the styles are applied). Instade, you can defined the font as a style of its own and use the style with-in other styles. In this case, once runtime instance of the font resource is used by both styles.
If you have very complex resource dictionaries (say for example you are creating a theme), it is a good idea to define geanular assets (like a specific color brush or font) as independent resource (or named style) and use them in other complex styles to conserve system resources.
On your question on Blend, it simpley enforces this best practice.
This is possible by creating a helper class to use and wrap your styles. CompoundStyle mentioned here shows how to do it. There are multiple ways, but the easiest is to do the following:
<TextBlock Text="Test"
local:CompoundStyle.StyleKeys="headerStyle,textForMessageStyle,centeredStyle"/>
The blog post talks about Win8 and Windows Phone, but the same code works for WPF as well (minus the Utilies class which is not needed)
Hope that helps.