Blend Bits 25–Templating Part 3

Another important part of templating contols in Blend is the ability to go from the control parts to the control quite quickly.

This works incredibly quickly for something like a Button – let’s say that I wanted an irregularly shaped button. If I just go ahead and draw a Path like this one;

image

then there’s a difference between this Path being inside a regular Button as the content using the regular template for a Button as in;

image

and the Path itself actually being a Button in the sense of getting rid of all the additional Chrome that we’ve got here and just leaving the Path. I can quickly achieve the latter by right mousing on the Path and using;

image

and Blend will ask me what I’m trying to do;

image

and the usual questions about where to put the resulting style that I’m going to end up creating here and once I’ve made those selections it will make me a new style for a Button and drop me into the template editor for the template within that style and it’ll drop my content (the Path) into that template.

It also drops in a ContentPresenter here which I can just remove if I don’t want it;

image

and that would leave me with a template for a Button which displays and hit-tests around this “hard-coded” star polygon and I’ve very quickly gone from drawing a shape on the artboard to making a new control template.

As an aside, it’s more likely here that what I’d really want is to leave the ContentPresenter where it is and get rid of the Polygon so that I’ve then made a Button style which can display arbitrary content without any chrome. Every time I then use this Button template I can drop the right content (e.g. the polygon) into it.

Buttons are simple though, let’s say that it’s a more complex control like a ScrollBar that I’m trying to redefine. Blend itself has nice looking scrollbars;

image

that I might want to reproduce.

This does require a little knowledge of how the ScrollBar is made up but, nonetheless, I can quickly draw out a Grid onto the artboard that has 5 columns in it as in;

image

I can set the Background to some colour;

image

and then add a triangle shape into the first and the last column, setting the height to a value of 16 and letting the width figure itself out and telling the grid columns to automatically size themself to the content ( and not forgetting to get rid of any minimum size value on those columns );

image

Now, I can add a “thumb” rectangle into the middle of the grid, once again telling that column to auto size itself;

image

and, lastly, I can add rectangles into the remaining 2 columns;

image

It’s not immediately obvious what these rectangles are for but the ScrollBar control has an expectation around particular parts being present when it is redefined and these 2 rectangles will play a part.

I’ve left all columns set to auto-size except column 3 which is set to claim any remaining space ( star-sized ).

With that quickly sketched out, I can right mouse on the grid and hit “make into control”;

image

which gives me a choice around what kind of control I’m trying to make;

image

and the usual Blend choice around whether this is an implicit/explicit style and where to put the resulting style from a resource perspective. If I make my choices then I’m left editing my new template;

image

which already has my UI pieces within it. I can go and open up the Parts panel and see what parts there are for a ScrollBar;

image

I’ve only drawn one half of a ScrollBar template because it has 2 separate (very similar) sections for a vertical ScrollBar and a horizontal ScrollBar but I can now start to turn my UI elements into recognised parts of the ScrollBar;

image

Now, the thing to know about this is that I have a Path depicting a triangle here but what the ScrollBar is expecting as this part of its control is a RepeatButton.

Consequently, Blend raises a UI for me which tries to bridge the gap between what I have ( Path ) and what I need ( RepeatButton ). I could avoid this by simply replacing my Path with a RepeatButton which contained the Path and then Blend wouldn’t try and help me bridge the gap.

In this instance, what I chose to do is to insert a RepeatButton, set its template to {x:Null} and then drop my Path inside of it.

I repeated that process with the triangle in the 4th column of my Grid and then identified these 2 RepeatButtons as the HorizontalSmallDecrease and HorizontalSmallIncrease parts of my ScrollBar as in;

image

It’s a similar story for the HorizontalLargeIncrease and HorizontalLargeDecrease parts of the ScrollBar template and so I followed the same procedure for those ( my 2 rectangles living in columns 1 and 3 ) leaving;

image

All that’s left is to select the remaining Rectangle and make it into the “HorizontalThumb” of my ScrollBar’s template. Once again, Blend notices that we need a Thumb but we have a Rectangle and so offers to re-template the Thumb for me;

image

and this time I go along with it and allow Blend to make a template for the Thumb for me;

image

which I just change a little with respect to margins and strokes and then come out of editing that template to take a look how my ScrollBar is coming along;

image

I also marked up the Grid as being the HorizontalRoot of the ScrollBar and with that I’ve got a redefined ScrollBar that looks a bit more like the ones in use in Blend.

I can test it out by adding a big image to my project and then dropping it into a ScrollViewer on my artboard and telling that ScrollViewer to scroll horizontally (i.e. setting HorizontalScrollBarVisibility to Auto rather than Disabled ).

I can then edit the ScrollViewer’s template;

image

and within there go ahead and change the horizontal ScrollBar such that it uses my new template;

image

and then I’ve got my new ScrollBar template in use;

image

and I can run and test it “live” in the application where it looks to work fine.

This is an alternative way of viewing template creation. Rather than starting out in the template editor, you start by drawing out the UI elements and then you use “make into control” to take those parts into the template editor.

For some templated controls like the ScrollBar here it’s important that they can identify certain elements in your replacement UI. The ScrollBar needs to be able to size things properly and so it needs to be able to identify the Thumb and so on and this is where Blend helps out with the Parts tab by making it easy for you to specify which of your UI elements make up that particular part of the control that you’re templating.

In terms of this ScrollBar, I’d need to go back and add the template for the vertical orientation and I’d also perhaps want to change some of the brushes that I’m using such that rather than being hard-wired into the template they, instead, relied on template binding to pick up brushes that the user wants to use when they come to define their ScrollBar instances…

Blend Bits 24–Templating Part 2

The previous post took a simple Checkbox and played with its template a little but we see quite a few more templates if we wander into a control like a ListBox.

Dropping a ListBox onto the artboard and then setting up some data that it can bind to ( using the sample data feature that I talked about here ) takes about a minute or so;

image

then there’s a bunch of templates to think about here.

Items Panel Template

One of those templates is the one that’s being used for the panel that makes up the ListBox.

Blend makes that easily accessible via the “Additional Templates” menu;

image

and by default this gives me a StackPanel which is why the ListBox lays out items the way that it does – i.e. stacked up vertically one under the other. Maybe I want a WrapPanel for my ListBox so I change the layout container here;

image

and then if I come out of editing that template;

image

then that’s not very nice;

image

as I’d really not like that ScrollBar to think that it has the responsibility of making my WrapPanel content scroll off to the right of the ListBox so I can fix that with;

image

and a quick resize makes that a little more attractive;

image

and that’s the role of the items panel template.

The Item Template

Another template that’s in play is the one that’s displaying the data on a per-item basis and Blend made one of those when I dragged my sample data to the ListBox so it’s given me a little bit of a head-start here.

Getting to the template is pretty easy;

image

and then Blend lets you edit this kind of template ( a DataTemplate ) in-place in the ListBox rather than re-focusing the environment around the content of the template itself. That is;

image

and I can edit that to my heart’s content playing with the visuals in anyway that I want setting up a few backgrounds, fonts, effects and so on;

image

and so that’s the ItemTemplate and the editing experience is pretty rich.

Item Container Style

What the heck is the item container style? If you were to run our UI as it stands and point a tool like Silverlight Spy at it then you’d see something unexpected ( unless you’ve been here before in which case, go read something else Smile );

image

ListBoxItem eh? Where the heck did that come from? I seem to remember my ItemTemplate containing a Grid but not a ListBoxItem. Also, in using the ListBox I see that I get a funny blue selection rectangle which I don’t remember creating;

image

who’s responsible for this travesty? Winking smile It’s the Item Container Style. Here’s how Blend surfaces it;

image

and if I wander into editing that style then Blend does an interesting thing in that it lets me create a style;

image

but it drops me into editing a template for a ListBoxItem

image

and if I go back “up” the hierarchy to the style;

image

then I see that I’m actually editing;

image

an ItemContainerStyle and it’s this style that sets a Template property that Blend (rightly) figured out was what I actually wanted to edit. Heading back into that template;

image

I can see that the ListBoxItemTemplate wraps a few extra pieces around whatever DataTemplate I choose as my ItemTemplate;

image

and it does this to provide somewhere to indicate selection, focus etc. and I can see that from the States panel;

image

so that’s another template that comes into play when working with a ListBox and I’ve mostly ended up editing it when I want to change that blue rectangle.

The ListBox Template Itself

As you’d expect, the ListBox has a template itself. I must admit that I don’t find myself editing it anything like as often as the previous 3 but, for completeness, you can always open it up;

image

and that gives you;

image

and then if you really want to start getting funky you can make the leap from editing one template to editing the templates of the controls that live within the template. For example, there’s a ScrollViewer here that we might want to re-template;

image

which gives us a view;

image

and that contains 2 ScrollBars which have templates so we might edit one of those which gives us…

image

and it can all start to get a little “deep”;

image

but the concept is the same one so long as the tool can deal with the hierarchy Smile

Looking at those ScrollBar templates, there’s a little plus-mark that indicates that a particular element forms a recognised part of the ScrollBar and a feature of Silverlight’s control model is this idea that a templated control may need to know which element in the template is meant to play which role or part.

Blend supports this via the Parts panel which I’ll put into another post…

Blend Bits 23–Templating Part 1

One of the real strengths of Expression Blend is in its deep understanding of control templates. Visual Studio doesn’t really go near control templates and so you really need Blend unless you’re a pure consumer of someone else’s templated controls.

Control templates are a complex concept in themselves and so editing them can be a bit mind-bending for the first time. If you’ve not encountered the idea of templates then perhaps the simplest thing to do is to wander into Blend and make a new project.

image

and then drop a simple control onto the artboard. A Checkbox is a prime example and a Button would be another. I’ll go with Checkbox.

image

and then wander into its control template – i.e. the visuals that represent the control’s look and feel. The ways in which you can edit the template are numerous but I think they all involve the same 2 menus which I’ve almost managed to show on this screenshot below;

image

"Edit a Copy” or “Create Empty”?

The CheckBox already has a control template and so we have a choice as to whether we want to start from that template or whether we’re brave enough to start from a blank sheet of paper. If you’re in “exploratory” mode then it’s wise to start from the existing template but it’s interesting to note that the 2 options lead you to 2 slightly different dialogs – this is Edit a Copy;

image

and this is Create Empty…

image

Now, both of these are going to ultimately create a ControlTemplate that targets a CheckBox.

By the way, if you’re not so familiar with styles or resources in Blend, then these posts might help;

You might expect that the former would create a style that simply sets the Template property but it doesn’t, it creates a copy of the default style for the CheckBox which includes more than just the value of the Template property, it includes a bunch of other properties like Foreground and so on.

Blend then drops you into a place where you are editing the Template property of that Style as the breadcrumb bar indicates here;

image

The latter “Create Empty…” option creates an empty control template and you would then be editing that template directly as the breadcrumb indicates here;

image

it’s a subtle difference and not one that’s too important for this particular post.

If you go with the “Edit a Copy” option for the moment and that drops you into “template editing mode” which is a fairly subtle thing to spot inside of Blend but we can spot it from the objects/timeline panel and the breadcrumb control;

image

the other parts of the environment that come into play are the states and parts panels. I don’t think a Checkbox has any parts defined but on the states panel you can see the various states that a CheckBox defines;

image

and you can see how that corresponds to changing property values for the various UI elements that are part of the template. Working with these states is pretty much the same experience as I talked about in “States/Groups and Transitions” – you define various property values for the various UI elements in their various states and you also define transitions between them.

Because transitioning to these states involve animations that make changes to properties on UI elements defined in the makeup of the control, if I was to select all the items in the template;

image

and hit delete then Blend would realise that the animations that were powering those state transitions no longer make sense and would say so;

image

Hitting CTRL-Z to put those UI elements (and the transitions) back for a moment, it’s “interesting” to look at a couple of elements in the template as it stands.

Template Binding

There’s a Rectangle called “Background” which really defines the border for the control;

image

and there’s an interesting question about what brushes this border should be using. I don’t (usually) want to build a template which forces all Checkboxes to be red or green or blue. I want the user of the Checkbox to be able to define their border colour when they use the control even if I have changed the control’s template. Consequently, the Rectangle here is careful about how it sets up brushes;

image

You can see that the Stroke property of the Rectangle is using a brush which makes use of TemplateBinding in order to pick up whatever brush the user specifies as the BorderBrush when they come to define their particular instances of the Checkbox control.

This is really smart as it makes for much more re-usable templated controls – we get to make use of a property that will be specified when the user of our control drops it onto their artboard in their UI.

Content Presenters

The other interesting thing about the CheckBox is that it’s one of Silverlight’s controls that can display arbitrary content. That is, it doesn’t just display Text, it displays anything dropped into its Content property.

How does that work? By making use of a control called a ContentPresenter and you can see that in the standard template;

image

and if you take a look at its properties, you’ll find that it too has a property called Content and that one is set up to use TemplateBinding in order that it picks up the value of Content from the actual use of the Checkbox control;

image

So you set the property CheckBox.Content and underneath this is really setting the property ContentPresenter.Content and the “right things happen”.

Why not replace this template for our Checkbox?

Replacing the Template

In order to replace the template, we can just delete most of what’s already there to leave an empty Grid;

image

and then I could perhaps add controls to make up one of those “slider style” Checkboxes that you see on OS X user interfaces so perhaps something like;

image

and this is just a Grid that contains a sub-grid and a ContentPresenter that has been set up to;

  1. Live in a grid row which is auto-sized to the content.
  2. Template Bind its Content property to the Content of the CheckBox.
  3. Template Binding its VerticalContentAlignment and HorizontalContentAlignment properties to those of the Checkbox.

The other grid row contains a Grid which has been split into 3 columns and just contains 2 rectangles which draw their colours by template binding to colours on the CheckBox again and then there are state transitions set up to move the “thumb” when the Checkbox is checked;

image

this is simply changing the Grid.Column property of the rectangle from 0 to 2 and it makes use of the Fluid Layout feature of Blend 4 to make this animate ( see this other post ).

There’s also a focusRectangle in the control which is invisible unless the control has the focus. I should also add UI elements for enabled/disabled and so on.

However, I’ve got a modified control and if I wander out of template editing mode;

image

then I can make use of it by just changing the brushes used for Foreground/Background and adding some content like this TextBlock below;

image

and with a bit more work it could become a fairly re-usable template.

But we’ve only encountered one template here so perhaps a “more complex” example would be a ListBox so we’ll see how Blend deals with that and I’ll drop it into a follow on post…