Visually Located

XAML and GIS

Working with location in an ArcGIS Runtime map app

This is the forth blog in a series of posts reviewing the new ArcGIS Runtime (beta) mapping SDK. The new SDK will be a great companion for any Windows developer wanting to add map functionality to their apps. In part 3, we looked at the MapView control within the SDK. One of the dependency properties that I left off in that post is the LocationDisplay property. This post will go into that property extensively. Working with location is probably my favorite part of the new ArcGIS Runtime mapping SDK because it is just so damn simple. In most mapping SDKs (eg: Nokia, Bing) you must do the work of hooking up to location changes, and updating the map. In the ArcGIS Runtime mapping SDK, it’s handled for you if you opt in for this functionality. Start off by downloading the sample application (if you have not done so already).

The LocationDisplay property of the MapView provides access to the LocationDisplay class. This class provides access to all the properties that make working with location in the SDK pure awesomesauce. Turning on location tracking, and the display of location on the map is as simple as setting IsEnabled to true! Let me say that again, setting one property to true, enabled GPS location within your app, places a symbol on the map indicating the current location, tracks location changes, and updates the symbol when location changes. Let’s take a look at the xaml needed to make this happen. Open up the xaml of any of the pages in the app. I’ll open the ArcGISTiledLayerPage.

<esri:MapView Grid.Row="1">
    <esri:MapView.Map>
        <esri:Map>
            <layers:ArcGISTiledMapServiceLayer ServiceUri="http://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer"/>
        </esri:Map>
    </esri:MapView.Map>
    <esri:MapView.LocationDisplay>
        <location:LocationDisplay IsEnabled="True"/>
    </esri:MapView.LocationDisplay>
</esri:MapView>

Enable the Location capability in your app (open Package.appxmanifest, Capabilities tab) and start the application. Select the map that you edited and it will prompt you to use location,

image

Allow location, and you’ll see your location on the map!

image

Unfortunately our location not centered on the map. If you want to track location, and center the map on the user, you’ll want to change the AutoPanMode. The AutoPanMode enumeration is a little confusing because the default value of the enum is Off, despite having a member named Default. I agree that you do not want the default value to center the map, but the wording is confusing. I’d like to see those change to Default, and On rather than Off and Default.

<location:LocationDisplay IsEnabled="True" AutoPanMode="Default" />

With our enum set to Default, the map now centers on the device! The location will update when you move and the map will re-center as well!

image

The AutoPanMode has two other values that make working with location even more awesome! Setting AutoPanMode to Navigation will change the map Rotation so that the top of the map faces the direction the user is facing. This is great for building routing apps where you want the road or path the user is driving, walking on to always face the direction the user is moving. This value will keep the map centered horizontally, but will show the location toward the bottom of the screen.

image

Setting AutoPanMode to CompassNavigation will always orient the map north. With these two AutoPanMode values of the LocationDisplay, you don’t even need to worry about the Rotation property from the last blog! How awesome is that?

image

Changing the symbology of the location marker is very simple. You can change the look of the CourseSymbol, HeadingSymbol (no doc link) or the DefaultSymbol. The CourseSymbol defines a symbol to use while location is actively changing. Great when using AutoPanMode.Navigation. The HeadingSymbol defines a symbol to be used when using AutoPanMode.CompassNavigation. And the DefaultSymbol defines the symbol to use when location is not changing.

<esri:MapView.LocationDisplay>
    <location:LocationDisplay IsEnabled="True" AutoPanMode="Default">
        <location:LocationDisplay.DefaultSymbol>
            <symbols:SimpleMarkerSymbol Style="Diamond"/>
        </location:LocationDisplay.DefaultSymbol>
    </location:LocationDisplay>
</esri:MapView.LocationDisplay>
image

 

The awesomeness doesn't stop there. What happens when you need to test, or demo location functionalioty? Should you start walking outside? Enventually, sure. But the LocationDisplay also allows you to set a LocationProvider that should be used. This simple interface allows you to define when location changes, when the device orientation is changed, or the speed of travel has changed (or all of them at once). Many times you want to test location, but you are at your desktop. Plugging in a quick little ILocationProvider allows you to do your testing.

Note: Location works great on all three platforms, but compass orientation only works for Windows Store and Windows Phone apps because they have built in APIs for compass.

These features should compel you to use the ArcGIS Runtime SDK for your next mapping app. In the next post I’ll cover map pins within the SDK.

Working with the MapView control in the ArcGIS Runtime

This is the third in a series of posts covering the new ArcGIS Runtime SDK. In part 2, I discussed the basic mapping layers within the ArcGIS Runtime. Now that we know how to add a map and layers to your app, let’s see what we can do with the map! As I mentioned in the first post, the new ArcGIS Runtime has a MapView, rather than a Map that you put in your app. The MapView has a Map property that must be set, but all of the functionality lies in the MapView. We’ll start out with some of the key dependency properties. We’ll then look at the map events, and finish with the few methods.

Dependncy Properties

The new MapView control has 11 dependency properties (with one additional attached dependency property). In this blog we’ll focus on seven of them. Not to worry about the other four. One we have already covered (Map), one will be covered in the next blog and two more when discussing GIS focused work. In this blog I’ll cover the following dependency properties.

MapGrid

The MapGrid is a new addition from the older .NET SDKs. I must say that this one is really cool. This allows you to display a map grid on the map. If you want to build an app with map, and not a GIS focused app, you may be wondering why this is useful. You could create your own MapGrid and have them be borders in a map. Maybe you are creating a multi-player game with a map. Each player has different zones they are responsible for.

The SDK comes with four map grids. The LatLonMapGrid shows latitude and, longitude on the map. The MgrsMapGrid displays the Military Grid Reference System. The UsngMapGrid shows the United States National Grid reference system. Finally, the UtmMapGrid shows the Universal Transverse Mercator coordinate system.

<esri:MapView>
    <esri:MapView.Map>
        <esri:Map>
            <layers:ArcGISTiledMapServiceLayer ServiceUri="http://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer"/>
        </esri:Map>
    </esri:MapView.Map>
    <esri:MapView.MapGrid>
        <esri:LatLonMapGrid/>
    </esri:MapView.MapGrid>
</esri:MapView>
MaximumExtent

The MaximumExtent property allows you to control how far out the map should be allowed to zoom. This property only controls zoom, it does not allow you to restrict where the user can pan the map. This property must be set using the spatial reference that the map uses. It would be great if you could specify an extent using lat/lon but have a map with a coordinate system of Web Mercator. The following example sets the maximum extent of the map to be the lat/lon borders of Colorado.

<esri:MapView>
    <esri:MapView.Map>
        <esri:Map>
            <layers:ArcGISTiledMapServiceLayer ServiceUri="http://services.arcgisonline.com/arcgis/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
        </esri:Map>
    </esri:MapView.Map>
    <esri:MapView.MaximumExtent>
        <geom:Envelope YMax="41.0014594" YMin="37.9358477" XMin="-111.09373110000001" XMax="-101.893834999999970000">
            <geom:Envelope.SpatialReference>
                <geom:SpatialReference Wkid="4326"/>
            </geom:Envelope.SpatialReference>
        </geom:Envelope>
    </esri:MapView.MaximumExtent>
</esri:MapView>
Min and MaxScale

The MinScale and the MaxScale properties control how far out or in, respectively, the map is allowed to zoom. A MaxScale of 1,000 will allow the map to be zoomed in to about a neighborhood level. A value of 10,000 no closer than a town, and 100,000 about the Denver metro area. The MinScale works the same way, but allowing the map to be zoomed out. When using the MinScale, ensure the map has an initial extent set so the user is not lost in the ocean.

From the documentation

A scale is usually referred to as 1:X, where X is the scale specified here. This value is the relative scale to the real world, where on inch on the screen is X inches in the real world. Note that this is only an approximation and is dependent on the map's projection that can add some distortion, as well as the system's reported DPI setting which doesn't necessarily match the actual DPI of the screen.

Rotation

The Rotation property allows you to… you guessed it, rotate the map. This is really useful when you want to orientate the map with the compass on the device or allow for a manual rotation of the map using an orientation control within the app.

ShowMagnifierOnTapAndHold

ShowMagnifierOnTapAndHold allows a magnifier to appear when you tap and hold the map. This property only works when using a finger to tap a touch device. I’ve been told the intent of this property is to better aid editing work flows. This property could be used for much more and make a mapping experience a lot better.

WrapAround

This is a handy property that allows to specify if the map can be continually panned east or west and have the map continue. Think of the WrapAround property as the ability a globe to spin continuously.

Events

The MapView control has four events that you’ll want to familiarize yourself with. The ExtextChanged event notifies you when the map is zoomed or panned. The MapView has three other events for touch or click manipulation. These events are MapViewDoubleTapped, MapViewHolding, and MapViewTapped.

Methods

The MapView has two utility methods and methods to zoom and center the map. Use the LocationToScreen and ScreenToLocation methods to convert between map points to screen points. These methods are handy within events. The MapView four methods for zooming and 15 methods for centering the map! Three methods are synchronous and 12 are asynchronous. To be fair, there are two methods, SetView  with two overloads and SetViewAsync with 11 overloads. Working with map APIs, you usually have one, at most two ways of centering a map. Oddly enough, the MapView does not have a MapCenter dependency property to center the map with binding.

I’ll continue the next post discussing location within an ArcGIS Runtime map app.

Working with Basic Mapping Layers in the ArcGIS Runtime Map

This is a second in a series of posts covering the new ArcGIS Runtime (beta). In the last post we walked through creating a simple map app. In this post we’ll start to cover the different layers your map can have. A Layer can be map images like what you would see in Google or Bing Maps. Or a Layer can represent the physical location of items. Layers can be toggled on and off through the IsVisible property. You can also adjust the transparency of a layer with the Opacity property.

The ArcGIS Runtime SDK comes with 12 different types of map layers that you can use in your app! Some of these I’ll cover in detail in this blog, some I’ll just barely cover, and some will have whole blogs dedicated to them. I like to group the layers into two basic categories. The layers for “basic mapping” and layers for “GIS users”. I consider basic mapping to be any app in the store that uses a map in any way. Some examples would be Four Square, or Disney Expedition.  Layers for GIS users are needed for the types of applications that I write for Schneider Electric. Applications that have a heavy workflow around GIS data or using Esri services need “GIS Layers”. Most of the apps that you write should be fine with the Basic Mapping layers.

This blog post will cover the Basic Mapping layers. Another post will cover the GIS User layers

Basic Mapping

ArcGISTiledMapServiceLayer

Of all the “ArcGIS” layers, this is the only one that makes it into the Basic Mapping section. All of the layers prefixed with ArcGIS work specifically with ArcGIS Server services. They know what URIs to go to for map images for an area or other information about the content of the layers. The ArcGISTiledMapServiceLayer makes it into the Basic Mapping category because Esri offers many great up-to-date tiled maps for free. That’s right, you can use any of the MapServer services located at http://services.arcgisonline.com/ArcGIS/rest/services. If we ignore the folders (which contain even more services), Esri offers 12 tiled services.

image_thumb

All of these services use either a standard WGS84 projection or a Web Mercator projection.

UPDATE: I was told that all of the WGS84 services have been deprecated in favor of the Web Mercator services. So you should not use the ESRI_Imagery_World_2D service. Instead use the World_Imagery service.

Using the ArcGISTilesMapServiceLayer in your app is really simple. Click on a link for one of the services that you would like to use in your app. I will pick “World_Street_Map”. Copy the URL of the service from your browser. For me it will be http://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer. This URL will be the ServiceUri for the layer. The following XAML will allow you to use the Layer in your map app.

<esri:MapView>
    <esri:MapView.Map>
        <esri:Map>
            <layers:ArcGISTiledMapServiceLayer 
                   ServiceUri="http://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer"/>
        </esri:Map>
    </esri:MapView.Map>
</esri:MapView>

It’s that easy to start using free maps with the ArcGIS Runtime SDK and the ArcGISTiledMapSerivceLayer!

image

BingLayer

The ArcGIS Runtime comes with out-of-the-box support for Bing map images! The BingLayer requires a key from the Bing maps portal. When working with the BingLayer, you can specify if you want an aerial, aerial with labels, or a road map through the MapStyle property. The default map style is Road. I won’t get into a lot of detail about the Bing maps portal, but keep in mind that you will have to pay for the usage of the map data if requests are over 50,000 in 24 hours. To use the BingLayer in your app, use the following XAML.

<esri:MapView>
    <esri:MapView.Map>
        <esri:Map>
            <layers:BingLayer Key="YOUR-BING-KEY" MapStyle="AerialWithLabels"/>
        </esri:Map>
    </esri:MapView.Map>
</esri:MapView>

Which produces the following map

image

GraphicsLayer

The GraphicsLayer is used to show any “client side” data. Think of it as the place for your map pins. The GraphicsLayer has changed from older versions of the .NET SDKs. In the past you were able to style a Graphic any way you wanted in XAML. The new API does all of it’s rendering in C++. With the rendering that deep, it can’t use XAML. They do provide some nice out of the box ways to draw your symbols. The GraphicsLayer is basically like a ItemsControl. You add items to the Graphics collection much like you would the Items of an ItemsControl. You can also bind the GraphicsSource to an IEnumerable<Graphic> just like you would the ItemsSource of an ItemsControl. Unlike an ItemsControl, the GraphicsLayer cannot accept any object into it’s collection. You can only add Graphic objects.

For this sample we need two layers in our Map. One for a base map and our GraphicsLayer. We’ll add new Graphics to the map whenever you tap or click the map. We’ll also define what we want our “map pin” to look like in the page resources. You can specify how each individual Graphic should look, or define a Render for the GraphicsLayer. For this we’ll specify that every Graphic should render an ‘X’ on the map.

<Page.Resources>
    <symbols:SimpleMarkerSymbol x:Key="GraphicSymbol" Color="#FF0A57FC" Size="12" Style="X" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <esri:MapView MapViewTapped="OnMapViewTapped">
        <esri:MapView.Map>
            <esri:Map>
                <layers:ArcGISTiledMapServiceLayer ServiceUri="http://services.arcgisonline.com/arcgis/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
                <layers:GraphicsLayer>
                    <layers:GraphicsLayer.Renderer>
                        <symbols:SimpleRenderer Symbol="{StaticResource GraphicSymbol}"></symbols:SimpleRenderer>
                    </layers:GraphicsLayer.Renderer>
                </layers:GraphicsLayer>
            </esri:Map>
        </esri:MapView.Map>
    </esri:MapView>
</Grid>

In our code behind we’ll add new graphics to the map in the OnMapViewTapped method.

private void OnMapViewTapped(object sender, MapViewInputEventArgs e)
{
    var mapView = (MapView)sender;
    var graphicsLayer = (GraphicsLayer)mapView.Map.Layers[1];
    graphicsLayer.Graphics.Add(new Graphic(e.Location));
}

The GraphicsLayer requires a lot more information than this overview blog so I have two more blogs that are dedicated to this topic.

image_thumb1

CsvLayer

The CsvLayer is a new addition to the ArcGIS Runtime. This handy layer allows you to use a csv file as the source of data for a map. Suppose you have a file with all of the locations of Starbucks. The CsvLayer allows you to use this file to show locations on a map! This file can be located online, or it can be local file. As of writing this, XAML only allows for an online file through the ServiceUri property. If you have a local file with your app, or would like to allow the user to specify a file, you can use the SetSourceAsyc method. The CsvLayer is a type of GraphicsLayer. So you can use the Graphics or GraphicsSource properties directly, but you shouldn’t need to. Just like with the GraphicsLayer, you define what the Graphics should look like with the Render property.

<Page.Resources>
    <symbols:SimpleMarkerSymbol x:Key="GraphicSymbol" Color="#FF0A57FC" Size="12" Style="X" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <esri:MapView >
        <esri:MapView.Map>
            <esri:Map>
                <layers:ArcGISTiledMapServiceLayer 
                        ServiceUri="http://services.arcgisonline.com/arcgis/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
                <layers:CsvLayer ServiceUri="http://VisuallyLocated.com/samples/starbucks_sample.csv">
                    <layers:CsvLayer.Renderer>
                        <symbols:SimpleRenderer Symbol="{StaticResource GraphicSymbol}"></symbols:SimpleRenderer>
                    </layers:CsvLayer.Renderer>
                </layers:CsvLayer>
            </esri:Map>
        </esri:MapView.Map>
    </esri:MapView>
</Grid>

In the above XAML, I’m have a file with a few locations of Starbucks around the US. Here is what it looks like.

image_thumb2

OpenStreetMapLayer

The OpenStreetMapLayer is also a new addition to the SDK. As you can guess, it displays the Open Street Map data. This is one of those things that “just works”.

<esri:MapView>
    <esri:MapView.Map>
        <esri:Map>
            <layers:OpenStreetMapLayer />
        </esri:Map>
    </esri:MapView.Map>
</esri:MapView>

Here is the app showing Open Street Map data for Colorado.

image_thumb3

You can download a solution demonstrating all five of these layers in a Windows Store and Windows Phone app.

Read part 2: Working with the MapView control in the ArcGIS Runtime

Building a map app with the ArcGIS Runtime Map

This is the first in a series of posts that will go over the new ArcGIS Runtime SDK. This first post will discuss how to get started and create an app that has the ArcGIS Runtime Map. This first step is to download the SDK. The SDK is currently in beta so you will need to sign up for the beta program. It’s important to note that you will not be able to get the SDK from nuget.

Esri packages their installers a little differently than you might be used it. The exe that you download is a zip of the actual installer. Run the ArcGIS_Runtime_SDK_for_DotNet_1022_536.exe (as of writing this the file is missing the exe extension, so you’ll need to add it) and you will be prompted for a location to unpackage the installer.

image

Give it a location, once it completes it will run the actual Setup.exe.

image

image

We’ll be building a Windows Store app with the SDK so you’ll need Visual Studio 2013. The SDK does not support Windows 8 apps, only Windows 8.1 apps. For Windows Phone and WPF you can use Visual Studio 2012. Open up Visual Studio and create a new Windows Store project.

image

The core of the ArcGIS Runtime is built with C++. Because of this, you’ll need to change the platform of the application from Any CPU. Any CPU is a .NET only thing, so we’ll need to specify either x86, x64 or ARM. To change the platform right click on the solution and select Configuration Manager. You may also want to add the platform target dropdown to a toolbar..

image

Make sure that debug and release are set to something other than Any CPU. If you like using the designer, you need to pick x86. When you ship your app, you’ll package it up with x86, x64 and ARMso it will work on any Windows 8.1 device.

image

Next add a reference to the new ArcGIS Runtime assembly. The assembly is under the Windows –> Extensions group.

image

Open the XAML of your MainPage. For this example we’ll create a fully emersive mapping application. We’ll need to add two namespaces to our xaml.

<Page
    x:Class="App1.MainPage"
    ...
    xmlns:esri="using:Esri.ArcGISRuntime.Controls"
    xmlns:layers="using:Esri.ArcGISRuntime.Layers">

If you are using Windows Phone, make sure you define the namespaces properly

<phone:PhoneApplicationPage
    xmlns:esri="clr-namespace:Esri.ArcGISRuntime.Controls;assembly=Esri.ArcGISRuntime"
    xmlns:layers="clr-namespace:Esri.ArcGISRuntime.Layers;assembly=Esri.ArcGISRuntime">

The esri namespace is where the controls live. This is where we will find the new MapView control.  In the past, we have worked with Map control. Now the Map is a property of the MapView. This does seem odd as they have only pulled out the InitialExtent property and the Layers property. The rest of the map functionality still resides on the MapView.

The layers namespace is where we will find the different types of layers we can  to the map. The next post will have more information on the different layers. For this post we’ll use the ArcGISTilesMapServiceLayer using Esri’s free tiled map services.

With the name spaces defined, add the following XAML your page.

<esri:MapView>
    <esri:MapView.Map>
        <esri:Map>
            <layers:ArcGISTiledMapServiceLayer 
                    ServiceUri="http://services.arcgisonline.com/arcgis/rest/services/ESRI_Imagery_World_2D/MapServer"/>
        </esri:Map>
    </esri:MapView.Map>
</esri:MapView>

Run the application and you’ll have a map app! Pan, zoom around. Find your home, have fun!

image

As you can see it is pretty simple to get started with the ArcGIS Runtime SDK. In the next post I’ll cover the different layers in the SDK.

Notice the legal notice in the corner? We are currently using the developer license (or no license) on the SDK. The SDK is still in beta, so you cannot use it in a production app (without asking). When the SDK is final, you can use a basic license for free. This license will get you pretty much everything you need to build an app. I’ll walk through registering for a license when it’s all working properly


You can download this solution that also contains a Windows Phone 8 app as well!

Read Part 2: Working with Basic Mapping Layers in the ArcGIS Runtime 

Getting started with the ArcGIS Runtime (beta) Mapping SDK for .NET

Last Sunday (March 9) Esri announced the public beta release of their mapping SDK for .NET. This new SDK covers Windows Store, Windows Phone, and WPF. Can you believe it? All three platforms, and all using the same API. This is huge news if you develop mapping applications. Personally I find it painful that in Windows Phone 7 you would use the Bing Maps (Silverlight) SDK. In Windows Phone 8 you were encouraged to use the new Nokia Maps SDK, while on Windows Store you had the Bing Maps SDK, but it was a different SDK than the Windows Phone 7 one. So that’s three different SDKs to use. I have no idea who thought this was a sane idea.

Esri has been working hard on this new SDK. During the Devsummit last year (2014), Esri announced the beta of a new SDK that would target Windows Store. At that time, they already had a Windows Phone SDK and a WPF SDK. Both were very similar with a few extras on the WPF side. While working on this new beta for Windows Store, they decided it would be much better to have a new SDK that targeted Phone, Store, and WPF. So for the past year that’s what they have been doing.

Over the coming weeks I’ll be blogging about how you can create mapping apps that use this new SDK. Some of these blogs will have a heavy focus on the GIS person, while others will be targeted to everyday app builders who want a better experience building map apps. These blogs will focus on Windows Store, but can be applied to Windows Phone and WPF as well.

 

Part 1: Building a map app with the ArcGIS Runtime Map
Part 2: Working with Basic Mapping Layers in the ArcGIS Runtime Map
Part 3: Working with the MapView control in the ArcGIS Runtime 
Park 4: Working with location in an ArcGIS Runtime Map app
Part 5: Adding map pins (graphics) to the ArcGIS Runtime Map
Part 6: Customizing map pins (graphics) in the ArcGIS Runtime Map

Part x: Working with the “GIS User” Layers in the ArcGIS Runtime
… More to come.

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!