Click here to Skip to main content
15,860,972 members
Articles / Desktop Programming / WPF

ListBox Styling (Part 3 - Additional Templates) in Expression Blend and Silverlight

Rate me:
Please Sign up or sign in to vote.
5.00/5 (38 votes)
6 May 2010CPOL20 min read 127.4K   5.2K   48   22
Explanation and examples of Additional Templates and Generated Content of a ListBox. Covering Layout, Transitions, and Animation.

Introduction

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.

Image 1

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 ListBox and TreeView are not really matching the new Style.

Image 2

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 ListBox, 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.

Image 3

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.

Image 4

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 StackPanel from Vertical to 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!)

Item Template

This is where we arrange the different elements that make up an instance of the Generated Content. This could be something like an Icon/Image, with a Title, an accompanying Description, a 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 StackPanel.

Image 5

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!

Image 6

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:

imgDa.jpg

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...

Image 8

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 Loaded and 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.

Image 9

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.

Image 10

Therefore, a 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..

Overview summary

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.

Image 11

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.

Dc.jpg

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.

Image 13

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 ListBox.

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.

Image 14

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.

Image 15

As the image above shows, all we have in the Items Panel Template is a StackPanel whose default orientation is Vertical.

So select the StackPanel and change the HorizontalAlignment from "Vertical" to "Horizontal", as shown in the image below.

Image 16

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 StackPanel's 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!

Item 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.

Image 17

This should change the Sample Data for the ListBox, to hopefully the same as the image below.

Image 18

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.

Image 19

This will take us into the Item Template, which shows all the Sample Data within a StackPanel.

Image 20

Now to make things a bit clearer, rename the items as shown in the image below.

Image 21

(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 StackPanel Orientation to Horizontal and change the general Layout of these items, so that they Stack left to right.

Image 22

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.

Image 23

Now in Objects & Timeline, drag the image above the CheckBox to change the order they are displayed in the StackPanel.

Image 24

With the Image still selected, change the size to 32 for both the Width and Height to reduce the size of the image.

Now select both the ItemDescription and ItemTitle elements, right click and choose Group Into > StackPanel.

Image 25

Drag the new StackPanel above the "Buy" CheckBox in Objects & Timeline, to change the ordering of the parent StackPanel.

Expand the child StackPanel, select the ItemTitle, and drag it above the ItemDescription element to change the ordering of this StackPanel.

Image 26

Select the StackPanel directly above the ItemTitle, change the Orientation to Vertical, and set a Margin of 4 for the left side only.

(Ensure that the Width and Height of the StackPanel are set to Auto).

Now select the ItemTitle, change the Font to Bold and the size to 7 pt.

Image 27

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 ItemDescription text).

So select the ItemDescription element and choose Group Into > StackPanel, and set the StackPanel Orientation to Horizontal.

Select ItemDescription again, change the Font size to 7 pt, and in Advanced Properties, change TextWrapping to "Wrap".

Image 28

Now change the Width of the ItemDescription element to 140, and ensure the parent StackPanel Width is set to Auto. Select the Buy, StockQuantity, and StockTitle elements together, and choose Group Into > StackPanel.

Ensure the StackPanel's Orientation is set to Vertical, and rearrange the order to StockTitle, StockQuantity, and Buy.

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.

Image 29

(Ensure the Width and Height of the newest StackPanel are set to Auto, and the Margins are set to 0).

Select the 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:

Image 30

(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 ListBox.

Now in Assets, find the "PageIcon" that I have "quickly" created, and insert a copy of the PageIcon into the StackPanel.

Image 31

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 Image and HyperlinkButton.

Image 32

In the Artboard, we should now have two "Page" icons.

Image 33

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 HyperlinkButton to Black, to make it match the text colour of the TreeView items.

Image 34

(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.

Image 35

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.

Image 36

That should hopefully space the Top of the items as a whole, and not each individual item.

Image 37

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.

Image 38

(Or Edit a Copy of the Template if you choose).

In Objects and Timeline, select the fillColor element.

Image 39

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:

Image 40

Go back to the Base State and select the Eye symbol next to the MouseOver State.

Image 41

(This will allow us to edit the fillColor element, without setting any Keyframes.)

Change both the X and Y Radius for the fillColor 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:

Image 42

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.

Image 43

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.

Image 44

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!)

Image 45

Set a Duration for the Effect of say 1 second, and run your application to see the results.

Image 46

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.

Image 47

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!

Image 48

Run your application, and use the arrow keys to change the Selected item.

Image 49

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.

Image 50

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.

Image 51

Now when we Unselect an item (MouseOff), instead of the Slide In Effect, we get a Blinds Effect, as shown in the image below:

Image 52

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 ListBox items.

Image 53

Select the BeforeLoaded Transition, set a Duration of 1 second, and an EasingFunction of Bounce Out.

Image 54

Now, ensuring you have the root grid selected, in the Transform section, set a Translation of 250 on the X axis.

Image 55

Now run the application, and hopefully during loading, the ListBox items flow in from the right and bounces off the left side of the ListBox.

(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's it

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!!!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
User Interface Analyst
United Kingdom United Kingdom
I've been playing with computers since my first Acorn Electron, & after blowing up a few ZX Spectrums. I moved on to the C64 & Amiga, & eventually reluctantly on to the PC.

I have learnt a wide set of skills during my 38 years of existence, living in the UK, on the sunny south coast.

My main area of expertise is Graphic/Visual Design, Usability & UI Design. I am not a programmer, but am fairly technically minded due to studying Mechanical Engineering at Uni.

I have work both Freelance & for IBM as a Graphic Designer, & am skilled in the usual graphics packages like, PhotoShop, CorelDraw or Illustrator, Premier, Dreamweaver, Flash etc.
But I originally started with Lightwave & 3D animation.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Monjurul Habib14-Dec-12 20:39
professionalMonjurul Habib14-Dec-12 20:39 
GeneralMy vote of 5 Pin
Kanasz Robert19-Jan-12 12:08
professionalKanasz Robert19-Jan-12 12:08 
GeneralListBox with Grid Items Pin
fxad5-Oct-10 6:12
fxad5-Oct-10 6:12 
GeneralRe: ListBox with Grid Items Pin
Alan Beasley13-Oct-10 1:30
Alan Beasley13-Oct-10 1:30 
GeneralRe: ListBox with Grid Items Pin
JPitta5-Feb-11 14:01
JPitta5-Feb-11 14:01 
GeneralGreat Pin
Majid Shahabfar14-May-10 8:56
Majid Shahabfar14-May-10 8:56 
GeneralRe: Great Pin
Alan Beasley14-May-10 23:32
Alan Beasley14-May-10 23:32 
GeneralExcellent Pin
linuxjr7-May-10 9:30
professionallinuxjr7-May-10 9:30 
GeneralRe: Excellent Pin
Alan Beasley7-May-10 9:37
Alan Beasley7-May-10 9:37 
GeneralExcellent article Pin
mike kidder7-May-10 5:58
mike kidder7-May-10 5:58 
GeneralRe: Excellent article Pin
Alan Beasley7-May-10 6:05
Alan Beasley7-May-10 6:05 
GeneralExcellent tutorial Pin
Daniel Vaughan6-May-10 12:11
Daniel Vaughan6-May-10 12:11 
GeneralRe: Excellent tutorial Pin
Alan Beasley6-May-10 23:31
Alan Beasley6-May-10 23:31 
GeneralUtter gibbersish Pin
Sacha Barber6-May-10 4:47
Sacha Barber6-May-10 4:47 
GeneralRe: Utter gibbersish Pin
Alan Beasley6-May-10 5:07
Alan Beasley6-May-10 5:07 
GeneralRe: Utter gibbersish Pin
Sacha Barber6-May-10 5:19
Sacha Barber6-May-10 5:19 
GeneralRe: Utter gibbersish - I agree! - But I gave him a 5 because he mentioned me Pin
defwebserver6-May-10 5:57
defwebserver6-May-10 5:57 
GeneralRe: Utter gibbersish - I agree! - But I gave him a 5 because he mentioned me Pin
Sacha Barber6-May-10 6:29
Sacha Barber6-May-10 6:29 
GeneralRe: Utter gibbersish - I agree! - But I gave him a 5 because he mentioned me Pin
NormDroid7-May-10 2:34
professionalNormDroid7-May-10 2:34 
GeneralRe: Utter gibbersish - I agree! - But I gave him a 5 because he mentioned me Pin
Alan Beasley7-May-10 2:39
Alan Beasley7-May-10 2:39 
GeneralForever... Pin
c24236-May-10 3:42
c24236-May-10 3:42 
GeneralRe: Forever... Pin
Alan Beasley6-May-10 5:09
Alan Beasley6-May-10 5:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.