I was recently working on a Windows Phone 7 application where one of the goals was to be very true to the Metro design guidelines. Like many applications we were using the trusty ListBox to show items with titles and subtitles, which all works pretty smoothly until that title starts wrapping. Then it quickly becomes apparent how much work is need to adjust the Silverlight templates to match the PSD Design Templates.
We did get very close to parity with the design templates and I thought I’d share the process for those interested in matching the native layout of the — List View double line.
Obtain the PSD Design Templates
If you don’t have them already download the Design Templates for Windows Phone 7. After extracting the files open the enclosed PDF which will act as a guide to the contents of the many large PSD files. Each files focuses on design and layout of different native WP7 components, not all components have a directly related Silverlight control, but its pretty simple to find something similar.
For a full walkthrough of the Design Templates check out this video screencast on the .toolbox site.
Locate the Target Layout
Open the “ListView_PSD.psd” file and you’ll see six different templates for the List view. The target is the view in the center of the top row — Double Line.
In order to create a lightweight image to use for comparison, I quickly grabbed and flattened the target.
- Expand the “DoubleLine_Wrapped” layer group
- Toggle the “Redline copy 5” layer into view
- Crop and save.
Matching the Layout in Silverlight
Now the goal is just to create the matching XAML and templates which can be reused within real applications. Thankfully Expression Blend has a project template that gets us more than halfway there.
- Open Expression Blend (free with Windows Phone Dev Tools)
- Create a new “Windows Phone Databound Application” project and name it “ListviewDoubleLine”
And right away, MainPage is loaded with a ListBox which includes some runtime and designtime data and a similiar data. The image to the right is an overlay of our target and current layout.
Change the Data to Match the Target
In order to use the target as a guide it will be much easier if the text is the same.
- For design-time values edit the SampleData/MainViewModelSampleData.xaml file
- For run-time values edit the ViewModels/MainViewModel.cs file
- In each file change the LineOne and LineTwo properties of the first six items to match the values used in the target
To avoid all the typing, you can download the edited files here.
Update the Header
Even though our focus is the ListBox, layout starts at the top of the page so we need to get that right first.
- ApplicationTitle – move to 17pt font size from 15pt
- TitlePanel – one less pixel in margin left and top (12,17 to 11,16)
- PageTitle – three less pixels in margin left and top (9,-7 to 6,-10)
Now other than the tracking of -10 on the PageTitle we’re set. Unfortunately adjusting font tracking in Silverlight 4 is not possible, but it is planned for Silverlight 5!
Update the ListBox
Now that the header is looking good its time to address the list items. We’ll do this first by adjusting the position of the ListBox which acts the origin for all items.
- MainListBox – three less pixels in margin left and two less pixels in margin top (0,0 to -3,-2)
The first list item looks good now, other than the aforementioned tracking issue.
Update the ListBox ItemTemplate
Although the text is now lining up properly for the first and second items, you may notice that the subtitle of the second item is breaking when it shouldn’t.
The StackPanel used as the container element for the ItemTemplate is not wide enough, although looking at the default width of 432 it matches the redlines in the target.
480 device width minus 24 pixels on each side equals 432, so where’s the disconnect? Its in the default styling of the title text box and in the visual vs hit target. Setting the background of the StackPanel to red highlights the answer. The StackPanel is 9 pixels away from the edge and not 24 as it appears to be.
We need to increase the width to account for this, as well as address the TextBlock spacing for the subtitle
- StackPanel – increase width from 432 to 459
- – decrease margin bottom from 17 to 1
- – set the MinHeight to 94
- LineTwo TextBlock – decrease the margin right from 12 to 0
- – change TextWrapping to NoWrap.
Matching the LineHeight for Text Wrapping
And now for the final feat and the most advanced bit of trickery, adjusting the template to accommodate for the wrapping behavior. In Silverlight we do have control over Line Height but you must first change the lesser known LineStackingStartegy property.
- LineOne TextBlock – set LineStackingStrategy to BlockLineHeight
- – LineHeight to 43
- – set Margin explicitly to 12,9,12,0 replacing the inherited 12, 0, 12, 0
- StackingPanel – remove MinHeight setting
- LineTwo TextBlock – increase margin top from -6 to -3
- – increase margin bottom from 0 to 17
To explain the previous steps, after setting the LineStackingStrategy for the title, we found a height that matched the target and then adjusted the margins accordingly. Then realizing that the MinHeight value is not going to work for the wrapped title items we shifted to adding a margin bottom to the subtitle.
Although it takes a little extra fine-tuning you can see that it is possible to get pretty close to the Metro design templates for your WP7 apps.
The one big thing missing is font tracking, but that will show up in Silverlight 5 as a Character Spacing property on text controls. Since the upcoming WP7 “Mango” release will bring the phoen up to Silverlight 4, I’m guessing I’ll revisit this post summer 2012 around when Silverlight 5 makes it to the phone. Then we can finally rest and reproduce a perfect match.
Until then, this little project is going on the shelf.
You can download the final source code here.