Visually Located

XAML and GIS

Extending your app theme into the SystemTray

I have seen a lot of apps recently in which the developers think about the theme of their app. They have nice colors, either in text, or background or both.

Sidebar: I recently read in an MSDN blog that “Backgrounds are discouraged. They are allowed for brand reasons and to support contrast. Instead, use any accent colors on the text foreground”. I personally like when apps do this rather than just the plain white or black text/background offered by default. This makes the app stand out from the rest. Heck, even Microsoft has violated this rule with their bing apps. I have a dark theme for my phone, yet the bing apps seem to favor a white background.

One area I notice where people are not applying their theme is in the system tray. They spend a lot of time and effort theming their pages, yet neglect this area. This is actually not surprising as the system tray is easy to overlook when creating your apps. It is placed in by default, it’s very small (32 pixels), and when using the emulator it’s hard to distinguish the tray from the emulator. Forgetting to theme this part of your app results in the following.

theme

Notice the black bar at the top?

How can you fix this? There are a couple ways to add your theme to the system tray.

  • Change the BackgroundColor of the SystemTray
  • Change the Opactiy of the SystemTray
Change the BackgroundColor of the SystemTray

The simplest way to extend your theme into the system tray is to change the BackgroundColor.

<phone:PhoneApplicationPage
    ...
    shell:SystemTray.IsVisible="True"
    shell:SystemTray.BackgroundColor="DarkGreen">

Let’s take a look at what happens to your app style when changing the color.

theme2

Notice anything off? Let me zoom in a little.

image

Notice the black line between the tray and the page content? This happens if you set the background through the PhoneApplicationFrame, or through the page content. If you are setting the background from the frame there is no way to remove the black line. If you set the background color from the page content, then you can remove the black line by shifting your page content up by one pixel.

<phone:PhoneApplicationPage
...
shell:SystemTray.IsVisible="True"
shell:SystemTray.BackgroundColor="DarkGreen">
 
<Grid x:Name="LayoutRoot" Background="DarkGreen" Margin="0,-1,0,0">
Unfortunately this means that you have to set the background for every page, rather than once in the frame.
Change the opacity of the SystemTray

A second option is to change the Opacity of the SystemTray. Opacity behaves very differently for the phone shell controls (eg: SystemTray, ApplicationBar) than it does for XAML controls. In XAML, opacity defines if an item should have some transparency (ie: Change the alpha channel). In Shell controls, opacity also defines the transparency but it is quite different. Setting a value less than one does not cause the content of the tray to become opaque. Instead it changes opacity of the background color.

Changing the opacity also allows controls to move into the space of the tray. Think of opacity on shell items like a grid with two rows.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="32"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
</Grid>

When opacity is set to “1” (the default), the tray and the page content fill only one row each.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="32"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <SystemTray Grid.Row="0"/>
    <PhoneApplicationPage Grid.Row="1"/>
</Grid>

When opacity is less than one, the page content is allowed to be in both rows.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="32"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <SystemTray Grid.Row="0"/>
    <PhoneApplicationPage Grid.RowSpan="2"/>
</Grid>

This causes your entire page to shift up! Shifting your content up means that your page is not quite aligned anymore.

image

To fix this, we’ll need to take into account whether the background for the page was set through the PhoneApplicationFrame, or through the page content. With either approach, we will add a top margin of 32. Which approach is used determines where we place the margin.

If you set the background of the PhoneApplicationFrame, you can safely add a margin to the first child of your pages. The background of the frame will fill the entire phone screen while your page content is shifted down slightly.

<Grid x:Name="LayoutRoot" Margin="0,32,0,0">
    <!-- Title-->
    <!-- Content -->
</Grid>

If you set the background of your page, you will want to add another child control to your LayoutRoot grid.

<Grid x:Name="LayoutRoot" Background="DarkGreen">
    <Grid Margin="0,32,0,0">
        <!-- Title-->
        <!-- Content -->
    </Grid>
</Grid>

If your pages have a Panorama with a background set you’ll want to modify the style to ensure that title does overlap the tray. The following image is using the default Panorama App template. The only change was to set visible to true, and opacity to 0.

image

The app has the exact same look without needing to add any margins. This gives the user the benefit of the system tray, without taking space from your app!

Using this approach how do you have a different color for the tray area than you do for the page content? You can accomplishing this by placing grid inside your page that has the background set. With this approach, you’ll need to take into account the margin.

<Grid x:Name="LayoutRoot" Margin="0,32,0,0" >
    <Grid Background="LightGreen" Height="32" VerticalAlignment="Top" Margin="0,-32,0,0"/>
    <!-- Title-->
    <!-- Content -->
</Grid>

image

Conclusion

So which approach do I recommend? Changing the BackgroundColor or the Opacity of the tray? Sorry, but going to answer “it depends”. It depends on how you want your page transitions to function, It depends on whether you want a different color for your tray than for your pages. Pick the solution that works best for you. For either solution I highly recommend setting the background of the PhoneApplicationFrame rather than the background of your page content. Setting the background of the frame allows page transitions to flow without showing the phone background (white or black) between pages.

I do recommend that you show the system tray, especially if your app uses an internet connection. If your app is loading slow, users will wonder if they have a good connection. They will want to tap the tray to see if they have a good cell signal or are connected to WiFi. If you hide the tray, the user has no idea if they are connected without exiting your app. You can always shift up your content closer to the tray in order to show more content. You can also place your app title in the system tray.

NOTE: All of this also applies to the ApplicationBar!

blog comments powered by Disqus