I’m amazed to find that I got so far into this series of posts around Blend without writing a post about styles. How did that happen?
Let’s rectify that problem here. Styles are simple but powerful. Essentially, they’re just a bunch of property setters grouped together so from a XAML perspective you can have a style that targets (e.g.) a Button and it might look like;
<Style x:Key="myStyle" TargetType="Button"> <Setter Property="FontSize" Value="22" /> <Setter Property="Foreground" Value="Red" /> </Style>
and it’s pretty usual to put styles into resource dictionaries ( for info about resources, see this post ) and our style above comes from a resource dictionary because it has a key of myStyle it will only be applied to Buttton instances that specifically request the style by looking it up using a {StaticResource myStyle} lookup as in;
<Button Style="{StaticResource myStyle}" Content="Hello" />
As you’d expect, a locally set value overrides the style so if you set the FontSize explicitly on the Button then that will override the value of 22 that comes through from the style.
It’s also possible for styles to be implicit in that if they don’t have a Key in a resource dictionary then they are taken to apply to all instances of that particular control type that are affected by their scope. For example if we have;
<Grid x:Name="LayoutRoot" Background="White"> <Grid.Resources> <Style TargetType="Button"> <Setter Property="Foreground" Value="Red" /> <Setter Property="FontSize" Value="22" /> <Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="VerticalAlignment" Value="Top" /> </Style> </Grid.Resources> <Button Content="One" /> <Grid> <Grid.Resources> <Style TargetType="Button"> <Setter Property="Foreground" Value="Blue" /> <Setter Property="HorizontalAlignment" Value="Right" /> <Setter Property="VerticalAlignment" Value="Bottom" /> </Style> </Grid.Resources> <Button Content="Two" /> </Grid> </Grid>
then we get;
and the red button doesn’t mention a style but ends up being red because of the implicit style that affects its scope and the blue button doesn’t mention a style but ends up being blue because of the implicit style that is closer to it in scope. Notice that the blue button does not end up with a large font size because the “inner” implicit style basically replaces the “outer” implicit style rather than combining with it in any way.
Speaking of combinations, the other thing about styles is that they can be derived. That is;
<Grid.Resources> <Style x:Key="GeneralButton" TargetType="Button"> <Setter Property="FontSize" Value="22" /> </Style> <Style TargetType="Button" BasedOn="{StaticResource GeneralButton}"> <Setter Property="Foreground" Value="Red" /> </Style> </Grid.Resources> <Button Content="One" />
this button ends up both having a large font size and a red foreground because it uses an implicit style that has derived itself from a named style.
That’s pretty much it when it comes to styles – how does this show up in Blend? Let’s take a new project and draw a button and then look to edit its style;
and you have a choice as to whether you want to edit a copy of the Button’s existing style or create a new one from scratch. These are quite different things but both present the “where do you want to put the style?” dialog…
and here you’ve got a choice of whether to apply a key or whether to make the style implicit by clicking “Apply to all”. Note that there is no choice to choose a base style from which to derive this style – I’m not sure that Blend has a UI feature to deal with deriving styles.
If you go down the route of copying the existing style then you’ll probably get more than you bargained for as you get a copy of the default style for the control and that includes the control’s template. For a button I get a style that sets the properties;
- Background
- Foreground
- Padding
- BorderThickness
- BorderBrush
- Template
and Template is the big one here because that property setter is changing your button’s entire visual make-up.
If you go down the route of using the “create empty” option then you’ll have an empty style and that’s much easier to deal with if you’re getting used to styling.
Either way, Blend now moves into “Style Editing Mode” which is way too subtle for my liking I really wish the environment would go blue or something to denote that we just changed modes but the subtle hints to watch out for are circled below;
while you are in this mode any property changes that you make are not being made to the Button, they are being made to the Style but it can be pretty easy to wander in and out of this mode without realising and then you get yourself into a bit of a mess so beware to check from time to time whether you are working on style values or local values.
As an example, if we wanted to change the margins on our button then we can go to the layout section of the properties grid;
and change those values down to (say) 48 all around…
then the split-XAML view shows us that we are changing the style;
Now, the trick is that if you come out of style editing mode by clicking in one of two places;
and then maybe you move the button in some fashion;
the thing to remember is that you’ve now set a local Margin value on this button which is overriding the style and if you were to use the advance button to reset those values;
then you are not resetting back to zero values or default values in this case. You are resetting back to the values that come through from the style. Naturally, you can see the Style property itself in the properties window;
I don’t think there’s a lot more around editing of styles in Blend – where complexity creeps in a little bit is that styles are usually stored in resource dictionaries so you need to get your head around resources in Blend and where styles can get a little complicated is where they are being used to set up values for a control’s Template property but that’s one for another post…