Part 13: Styling Tiles in the LongListSelector
In the previous lesson, we made a lot of progress in wiring up a new data model to the MainPage.xaml and now we need to focus on the layout of the DataTemplate in our LongListSelector—we'll want to tweak each instance of the SoundData so that they resemble tiles instead of rows. So, if we compare our drawings with the current state of the app's UI, the layout is not quite right. We'll remedy that in this lesson.
- We'll modify the LongListSelector to utilize the Grid LayoutMode.
- We'll completely re-work the layout of each DataTemplate so that it more closely matches the layout of a tile.
- Since we need five or six PivotItems, each with their own LongListSelector, it doesn't make sense to keep defining the tile layouts, so we'll abstract them into a centralized template that can be used by all the LongListSelectors on our MainPage.xaml.
1. Change the LongListSelector's LayoutMode to Grid
The LongListSelector control sports a LayoutMode property. It accepts an enumeration of either List (which is the default) or Grid. By setting the LayoutMode to Grid, and setting a cell size in terms of width and height, we can quickly change the appearance of the LongListSelector.
By adding lines 49 and 50, the LongListSelector now looks like this:
... where each instance of the DataTemplate looks like a tile.
2. Modify the DataTemplate to create the layout we need
Next, we need to modify what's INSIDE the DataTemplate to match our desired layout. I'll highlight and delete everything inside of the DataTemplate:
... and then I'll start over with a Grid control with a single cell. Inside the Grid, I'll use a TextBlock for the name of the sound at the bottom of the tile. I'll wrap a StackPanel around it so that I can set its vertical position within the Grid cell later. So, I add the following code inside of the DataTemplate:
In line 55, notice the Background which I set to the built-in PhoneAccentBrush resource.
That code produces this result:
I want to move the TextBlock's position to the bottom and add some padding. I make the following additions:
I set the VerticalAlignment of the StackPanel to "Button", and set margins on the left and bottom sides of the TextBlock. That produces the following:
So far, so good.
Next, I want to add that play button graphic that I sketched in my mockup. To do that, I'll use the Assets\AppBar\plan.png icon we added to the project in a previous lesson.
I'll add an inner grid, set its vertical alignment to the top, and its horizontal alignment to the right. The play.png is just an arrow, and I want there to be a circle around it. I guess I could re-work the image, but there's a simple solution in XAML ... I'll just add an Ellipse control around the image.
- Add a Grid and set it so that it is small (40 x 40) and anchored to the upper right-hand corner of the tile (via VerticalAlignment and HorizontalAlignment). I also add a small margin to the top and right sides.
- Use an Image control to load the arrow head image (i.e., the play.png file)
- Add an Ellipse around the arrow head image. I use a built-in brush for the ellipse ... can you think of why this might be a problem and how I might solve this? Give it some thought. I'm going to leave it as is for now.
These changes make each tile look close to what I had originally envisioned. Now we need to apply this to the other PivotItem's DataTemplates.
3. Adding the DataTemplate's design to the Page's Resources so that we can re-use it
In the previous lesson, we saw the behavior of the XAML design ... if we put our mouse cursor in a different PivotItem, that PivotItem's DataTemplate appears in the XAML designer view.
Instead of copying and pasting the DataTemplate we created a moment ago into each of the 5 or 6 PivotItems we'll need in the MainPage.xaml, I have a better idea. Let's define the DataTemplate as a page-level resource.
In lines 17 and 19 I've defined a Resources section for the page. I'll merely cut and paste the DataTemplate we created a moment ago here, and then reference it in each PivotItem where we need it.
After I cut and paste the DataTemplate into its new home as a page-level Resource, I add a Key attribute. This Key will allow me to reference my DataTemplate from the rest of the page when I need it.
Now, I just need to reference the Key, SoundTileDataTemplate, in my LongListSelector's ItemTemplate property like so:
... and I'll repeat that process for the second PivotItem:
... and something interesting happens. When I look at the XAML designer, I can see two tiles butted up right next to each other:
Why had I not noticed this before? Because the first PivotItem, Animals, only had one SoundData object associated with it. Clearly we'll need to remedy this because it doesn't look right, and as a result it may confuse the user. They may not see distinct tiles but rather one long bar of red or whatever PhoneAccentBrush color they chose.
To remedy this, I add a margin to the bottom and right of each Grid that defines the boundaries of each DataItem tile:
... and that seems to provide the visual separation that I wanted:
The last task is to create PivotItems for each of the other DataGroups I'll support in my app, including Taunts, Warnings and Custom Sounds. I merely copy and paste one of my existing PivotItems three times like so:
Now, I've warned you about the dangers of copying and pasting code before. There's a chance you'll forget to modify the one little bit of data that makes each pasted item different. So, pay attention to the details ... make sure you're modifying each pasted item in two spots ...
- Change the PivotItem.Header binding to the correct SoundGroup name, and ...
- Change each LongListSelector.ItemSource binding to the correct SoundGroup as well
To recap, the big take away from this lesson was how to style the LongListSelector by changing the LayoutMode from List to Grid, and setting the tile sizes. We also learned how we can take things like DataTemplates and defining them at a higher level for ease of re-use. We also learn how to use an Image control and add simple shapes like Ellipses to enhance the visual design. When you build apps, you need to spend a lot of time tweaking the visual appearance and have an eye for detail.