Welcome to my seventh beginner's tutorial for Expression Blend and Silverlight. This time, we will be looking at Styling the Generated Content of a ListBox via Additional Templates, and I will do my best to guide you through this.
Again, before commencing this tutorial, I recommend that you read my previous CodeProject tutorials. I am writing them as a series, and as such, this tutorial will presume prior knowledge.
What have we covered so far?
In the last part of this tutorial, we discussed Control Template and how this effectively makes up the Border/Framework/Stage of a
ListBox. We Styled these elements (mainly the
ScrollViewers) to suit the
ListBox's intended use/surroundings, whatever they may be... I have no idea either, so I threw a frame around the application to give it some context. But if we look back at the previous tutorial, we can see this just highlights that the Content of the
TreeView are not really matching the new
The yellow Folders icon in the
TreeView doesn't really fit the colour scheme, nor does the blue hyperlink text in the
ListBox. Also, when the application is run, we have pale blue MouseOver States for the files and folders. As well as a rectangular selection area on the
ListBox that spills outside of the bordered panel that frames/holds it (the
ScrollContentPresenter). Now, absolutely nothing in the Control Template of the
ListBox will have any bearing or affect on the problems/issues I have just raised. The reason for this is because the Control Template has nothing to do with the Generated Content of a
TreeView (or any other
Control). All it does, is set the Stage (Framework/Border) of the
Control and hold the
ScrollContentPresenter, which is the portal to the imaginary world of Generated Content. I call it imaginary, because without any Content, it's all invisible! So thank whoever you may pray to for Sample Data, as it truly is wonderful for designing UI on Generated Content. Alternatively, you can have a word with your developer, who can create a specific Design time sample data source, like defwebserver has here.
Quick overview of Additional Templates
Let us have a look at the Additional Templates of a
ListBox and try to get our head around what each one does.
Basically, we have three extra Templates that control and manipulate the Generated Content that appears in the
ScrollContentPresenter. Each has a different job or goal in presenting and formatting the Generated Content and Data. Below is a simplistic UI Designer oriented diagram of the Template relationships.
Simplistic ListBox Template diagram - Intended for designers, not programmers!
Items Panel Template
What we basically have is the Item Template and Item Container Style Template within the Items Panel Template. Even though the Item Panel is the third in the list of available Templates, it is "sort of" the parent of the other two Templates, as it defines how they will Layout as a whole. This could be as a
StackPanel (default), a
WrapPanel, or maybe a
DockPanel. Basically, anything that inherits from the
Panel class. You can also specify a
Grid or maybe a
Canvas, but there is little point, as each instance of the Item Template will just appear on top of one another...
At the risk of repeating myself: the Items Panel Template is the
Panel that the
ListBox uses to layout the Generated Items that are defined in the Item Template. By default, this is a StackPanel, but this can be changed depending on your data and requirements.
The most light reason to edit the Items Panel Template is to change the orientation of the
Horizontal. Or possibly, make it a
WrapPanel, but be warned, this can cause issues with selection navigation. (I'm waiting for a friend (Jason Young) to blog his solution to this issue, so will update when available!)
This is where we arrange the different elements that make up an instance of the Generated Content. This could be something like an
Image, with a
Title, an accompanying
CheckBox, etc... You name it, it could possibly be one of the elements that could be laid out in the Item Template.
In our application, defwebserver has setup an
Image and a
HyperlinkButton in a Horizontal
This example is probably as basic as it gets really, and there is nothing stopping us doing a lot more, which we will cover later in this article.
Item Container Style Template
This is easily the most interesting of the three available Templates, and where all the magic happens. As this is where we entertain and interact with the user to produce visually appealing animations and effects!
The default setting for this Template is shown in the image above. And along with some Rectangles for various visual States, we have a
ContentPresenter that gets its input for the Item Template. Notice that next to the "Return Scope" icon, this Template is actually called "ListBoxItem Template", and in the screen grab for the Item Template section above this, next to the "Return Scope" icon. It is actually called the "ContentPresenter Template". Ignore the "SilverlightFileTemplate", as defwebserver created this name when he edited a copy of the original Template. So you could say that the arrangement of the Templates as shown in the diagram earlier should be more like the diagram below:
No matter how you want to look at it, we are most likely to be interested in the Item Template to layout our Generated Content, and the Item Container Style Template to interact with this Generated Content. We manipulate the Item Container Style Template using the Visual States Manager (VSM), and as the image below shows, we have more State Groups than we have covered before, when dealing with buttons...
The obvious addition is a State Group called "
LayoutStates" which, as you would expect, can be used to control the elements within this Template during their
Unloaded States. Not so obvious is the addition of Effects in Blend 4, which allows for some funky transitions between States in a State Group.
Another thing to consider with the Item Container Style Template is that it has an associated Style applied to it, and this is different to the ListBox Control Template Style.
ListBoxItem can have a different Style applied to it, while still using the same surrounding
ListBox. So rather than having a whole new
ListBox with different Generated Content interaction, colours, and styles, it is possible to just pass the
ListBox a new
ListBoxItem Style to change the interaction, colours, and Template elements..
So those are the three Additional Templates of a
ListBox as an overview, and if this is the first time you are looking at these, it may be a little confusing. So the best thing to remember is that these Templates are not really equal, that you may have presumed it by their listing in the Additional Templates. They are basically nested within one another, but in the reverse order as shown in the list of Additional Templates.
Basically, follow the Content Presenter, all the way from the
ScrollContentPresenter of the
ScrollViewer in the ListBox Control Template into the Items Panel Template (which is also known as the ItemsPresenter Template). This then leads to the Content Presenter of the
ItemContainerStyle, which gets its Generated Content from the Item Template. So if we look at our diagram again, we should look from the centre outwards, to get our heads around how the Generated Content is Presented and Styled.
Also, the purple sections of the diagram signifies where Styles are placed within the
ListBox control. Please appreciate once again that this is a simplistic "Designer" oriented view of the Additional Templates.
Let's get stuck in!
To make a start at editing some Additional Templates, I will take over from defwebserver's Drag and Drop File Manager article, using this as a starting point to format the Generated Content via the Additional Templates.
To keep things interesting because I was getting bored of it, and to free up more "real estate", I've changed the look of the application again. So it has a thinner frame, collapsed rivets (not removed), and a new blue colour scheme.
I have also Styled the
GridSplitter with a few rivets, and integrated it with the
PictureFrameControl. And the ones of you with eagle eyes will have noticed I've Styled the
TreeView a little with new expanders and folder icons. Which I have only done so not to detract from the application while we work on the
So download the updated application from here and we can make a start!
Items Panel Template
Let's look at this Template first, as it is the least interesting of the three, and in a lot of cases will probably not need any editing at all. Select the
ListBox, and choose Edit Additional Templates > Edit Layout of Items > Create Empty.
Call the Template something like "
ListBoxItemsPanelTemplate" and hit OK.
Now if we look in Objects and Timeline, we can see that this is an ItemsPresenter Template, and as I said earlier, this Template controls/defines the layout of the area set by the
ScrollContentPresenter in the Control Template.
As the image above shows, all we have in the Items Panel Template is a
StackPanel whose default orientation is
So select the
StackPanel and change the
HorizontalAlignment from "
Vertical" to "
Horizontal", as shown in the image below.
This should change the
ListBox in the Artboard so that only the first Generated Item is visible in the
ListBox. The other Generated Items are now to the right of this first Item, as one long stream. Which is great for maybe a Ticker Tape application, where items scroll from right to left, or left to right, but not really right for this application. The other really cool thing about the Items Panel Template is the ability to change the Layout Style to a
WrapPanel. Which I won't do here, as it deserves more than a quick explanation, and if you are unsure about what a
WrapPanel can do, check out this video from Microsoft Mix10.
Now change the
HorizontalAlignment back to "
Vertical", and come out of the Items Panel Template.
(And in the words of Officer Barbrady (South Park) "Move along people, there's nothing to see here")
As that is pretty much it for the Items Panel Template!
To break with the order, I discussed the Templates in the Overview section. We will look at the Item Template before we address the Item Container Style Template. If you have been paying attention and taking onboard what I have said so far about Templates, you should realise that in order to Style the Generated Content in the Item Container Style Template, we first should format the Generated Content in the Item Template.
defwebserver has given us some Generated Content in this application, but to properly demonstrate what we can do in the Item Template, I would like a little more Sample Data to play with, which I have already setup in the downloaded project.
So go to the Data tab, select "Collection", and drag this onto the
ListBox in the Artboard.
This should change the Sample Data for the
ListBox, to hopefully the same as the image below.
We now have a lot more Generated Content, but currently it is a mess and jumbled up.
So select the
ListBox and choose Edit Additional Templates > Edit Generated Items > Edit Current.
This will take us into the Item Template, which shows all the Sample Data within a
Now to make things a bit clearer, rename the items as shown in the image below.
(The Sample Data has been imported in the same order it appears in the Data tab.)
The first thing I want to do is change the
Horizontal and change the general Layout of these items, so that they Stack left to right.
In the Artboard, you should hopefully now see a
CheckBox, with an
Image to the right of it and some
Text to the right of the image.
Now in Objects & Timeline, drag the image above the
CheckBox to change the order they are displayed in the
With the Image still selected, change the size to 32 for both the
Height to reduce the size of the image.
Now select both the
ItemTitle elements, right click and choose Group Into > StackPanel.
Drag the new
StackPanel above the "Buy"
CheckBox in Objects & Timeline, to change the ordering of the parent
Expand the child
StackPanel, select the
ItemTitle, and drag it above the
ItemDescription element to change the ordering of this
StackPanel directly above the
ItemTitle, change the
Vertical, and set a
Margin of 4 for the left side only.
(Ensure that the
Height of the
StackPanel are set to
Now select the
ItemTitle, change the
Font to Bold and the size to 7 pt.
So we now have a Horizontal "parent"
StackPanel with elements laid out left to right. And in the middle of these Horizontal elements, we have a Vertical
StackPanel with one element laid out below another. Hopefully, you are starting to see what is going on in this Template, and have noticed that as we edit the top Item Template, all the instances of the Item Template displayed below automatically update with our edits to the Item Template. You should also be appreciating how useful a
StackPanel can be with regards to Layout, and I will now do a little more to demonstrate this. We still have three elements that are not visible in the Item Template, as they are to the right of the
StackPanel containing the
TitleDescription text, and hence off the end of the screen. So we need to format the
TitleDescription text so that it will Wrap and take up less Horizontal space. But I also want the
ItemTitle text length to be uninterrupted and to flow across (above) all of the other following elements (independent of the
So select the
ItemDescription element and choose Group Into > StackPanel, and set the
ItemDescription again, change the Font size to 7 pt, and in Advanced Properties, change
TextWrapping to "
Now change the
Width of the
ItemDescription element to 140, and ensure the parent
Width is set to
Auto. Select the
StockTitle elements together, and choose Group Into > StackPanel.
Orientation is set to
Vertical, and rearrange the order to
Next, drag the latest
StackPanel inside of the
StackPanel above it in Objects and Timeline so that it is directly below the
ItemDescription, as shown in the image below.
Height of the newest
StackPanel are set to
Auto, and the
Margins are set to 0).
StockTitle element, change the Font size to 7 pt, and make the text Bold. Now change the
StockQuantity Font to 7 pt and make the text Italic. This should result in something like the image below when the application is run:
(I have changed my
ItemTitle text to 9 pt to show clearly that it flows over and across the child
StackPanel, within it, and below it.)
Hopefully, I have demonstrated the Item Template enough for you to see this Template is all about Layout. As well as the flexibility of the
StackPanel within the Item Template. Obviously, we could space out and format our items further using Margins, and grouping elements into Grids. But I will leave you to play with this further... (Edit the current elements, add some more elements, and format all of these as you see fit.) I, however, need to move on to the Item Container Style Template!
But before we start on the Item Container Style Template, I want to discard all the changes we have made so far. These were just for demonstration purposes, and not part of the ongoing application that defwebserver and myself are developing.
So reload the original unedited project and once again go to the Item Template of the
Now in Assets, find the "
PageIcon" that I have "quickly" created, and insert a copy of the
PageIcon into the
Set the size of the
PageIcon to 14 pixels in
Width, and 16 pixels in
Height. In Objects and Timeline, rename it to "
PageIcon" and drag it to the top of the
StackPanel list, above the
In the Artboard, we should now have two "Page" icons.
The blue one I have created is more suited to our project. As well as editable, to change colour along with our project. So delete the second white
PageIcon, as this is no longer needed. On the remaining
PageIcon, set a
Margin of 4 on the
Left side to space it away from the edge of the
ListBox. Now select the
HyperlinkButton, and also set a
Margin of 4 on the
Left side, to space it away from the
PageIcon. Change the foreground colour of the
Black, to make it match the text colour of the
HyperlinkButton can be edited further if needed, via its own Template and Style.)
Now we just need to set some free space above the list of items in the
ListBox, so select the
StackPanel and set a
Margin of 9 to the
Top. But because we are applying this
Margin to the Item Template, this
Margin is applied to every
Item, spacing them all out.
We cannot set a
Margin for just one
Item in the Item Template, everything we do here will apply to every item. So instead, change the Top Margin to 0 and the Bottom Margin to 1 (to give each
Item a little spacing and to match the
TreeView item spacing).
Now go to the ListBox Control Template, select the [ItemsPresenter] and set a Top Margin of 8.
That should hopefully space the Top of the items as a whole, and not each individual item.
Item Container Style Template
This is the Template I have been looking forward to discussing, and partly why I have left it until last. But before we get to the more advanced and interesting parts of this Template, we need to do some basic formatting for the MouseOver and Selected States.
So select the
ListBox and choose Edit Additional Templates > Edit Generated Item Container > Edit Current.
(Or Edit a Copy of the Template if you choose).
In Objects and Timeline, select the
Now go to VSM, select the MouseOver State and change the element Opacity to 100%.
In the Artboard, the first item should now have a pale blue background, as shown in the image below:
Go back to the Base State and select the Eye symbol next to the MouseOver State.
(This will allow us to edit the
fillColor element, without setting any Keyframes.)
Change both the X and Y Radius for the
Rectangle to 5, to round the corners of the
Rectangle. Change the Left and Right Margins to 3, and the Top Margin to 1. Now run the application, and during the MouseOver State, the selected item should look like the image below:
Back in Blend, select the MouseOver State and set the element
Opacity back to 35%. Now select the
fillColor2 element, and in the Base State, click on the Eye symbol next to the Selected State.
As we did before, change both the X and Y Radius for the
fillColor2 Rectangle to 5, and change the Left and Right Margins to 3, and the Top Margin to 1. Repeat the same process for the
FocusVisualElement, applying a Radius to the corners, and setting Margins for the sides.
Getting silly with the Item Container Style Template
Now for the fun part of applying, some silly "over the top" effects to our
ListBox. Most of these are obviously not really practical for a real application, and the thing to remember when using Effects & Animations is that they are to enhance your application, not to distract from the message or purpose of your application! They may appear fun and entertaining the first few times, but this will soon turn to frustration and annoyance for the user. So don't get carried away...
However, I will go completely "over the top" here, just to demonstrate what can be done!!!
Let's look at the MouseOver State first, or rather the State Group called "
CommonStates". Any Effect we apply here will apply to all the States in this State Group.
Applying an Effect for the MouseOver State will apply to the Normal and Disabled States as well. But rather than discussing this, let's go ahead and see this in action...
Click on the Effects icon "fx" and choose Ripple. (Or any other Effect you fancy!)
Set a Duration for the Effect of say 1 second, and run your application to see the results.
When we MouseOver the
ListBox items, we get a Ripple Effect. And we also get the same Effect when the
ListBox items return to their Normal State (MouseOff).
Try out different Effects for yourself, adjust the Duration to suit, as well as play with different EasingFunctions.
Next, let us look at the SelectionStates and specifically the Selected State.
Choose an Effect that takes your fancy, and set a Duration for this Effect. I've chosen Slide In (LeftToRight), as this will show up easily in a screenshot!
Run your application, and use the arrow keys to change the Selected item.
See how this affects the Selected State, as well as the Unselected State. This may not be desirable, as you may not want the Slide In to occur on the unselected item. And we can control this, by adding a Transition to the Selected State.
By adding a Transition from Selected State > All Other States, we can apply a completely different Effect when an item is Unselected.
So just to demonstrate, I have added a new "Blinds" Effect for this Transition, with a Duration of 1 second.
Now when we Unselect an item (MouseOff), instead of the Slide In Effect, we get a Blinds Effect, as shown in the image below:
We can obviously do this in All the State Groups, so an Effect can be tailored to your exact needs.
(Or have no Effect at all in a Transition, if the Duration is set to 0).
Finally, in this section, I want to look at the LayoutStates for the Loading of the
Select the BeforeLoaded Transition, set a Duration of 1 second, and an EasingFunction of Bounce Out.
Now, ensuring you have the root grid selected, in the Transform section, set a Translation of 250 on the X axis.
Now run the application, and hopefully during loading, the
ListBox items flow in from the right and bounces off the left side of the
(Hit Refresh or F5 to reload and show the animation again.)
There is no point showing a screenshot, so download the finished project if you are not working through the tutorial!
That concludes my "over the top" explanation of Additional Templates. Back to defwebserver! Please vote to invalidate the 3 star voters who don't have the stones to leave comments on how I can improve my articles/tutorials!!!