Skip to content

Jeff Wilcox
Syndicate content
Silverlight, rich client apps and web development
Updated: 5 hours 33 min ago

Displaying static maps on the Windows Phone for performance and scenario wins

Wed, 02/01/2012 - 02:36

One of the nice visuals of 4th & Mayor is the animation and display of a simple area map whenever you view a place in the app.

Unfortunately, most map controls, such as the Bing Maps control included with the platform, are highly sophisticated: they let you have a bunch of pushpins, gather information about bounding boxes, etc. This awesome feature set can have a negative effect on performance.

2/1/2012 Update: Thanks to Tim Heuer, who just provided a pull request that adds an OpenStreetMap provider, MapQuest provider, offers the ability to add an authentication key optionally as a property on the control, and to specify the type of maps. I’ve updated NuGet to 1.1 with these contributions, thanks!

My static map control is simple but nice because it’s an easy replacement, can be used in Panorama/Pivots, and overall still has a great, high-speed experience that your users will enjoy.

SampleMap
A sample static Bing Map from 4th & Mayor: touching the map takes you to an interactive map view page allow for directions, panning, etc.

ā€œJeffWilcox.Mapsā€ Component

I’ve refactored one of the libraries used in my app to be general enough for others to use: it offers simple static map code in the form of a ā€œStaticMapā€ control: just drop it into your XAML page and you’re mostly good to go.

The MapCenter property takes a GeoCoordinate, either data bind it or set the property as the page is navigated to.

Over time I’ll consider adding more of the functionality I’ve had to the library, including the interactive libraries.

Get the library

I’m using my favorite pair of deployment places for this library: GitHub for source, NuGet for binaries.

NuGet

The library is JeffWilcox.Maps

Source on GitHub

Fork the repo, wp-maps

Offering an interactive experience

To optimize the maps experience, I instead decided to use the static map REST APIs from Bing Maps for my mobile application: this lets me perform a HTTP request, grab the image, and data bind it into my display.

I then place it inside a borderless, retemplated Button control, so that touching the map takes you to a new page: an experience where I can show the real Bing Maps control, your current position, as well as the location of the place you are trying to go. By moving this to a separate assembly, I get great performance wins: the Bing Maps control and other code needed to offer the rich interactive experience is delay loaded and only there when needed.

Properties on the control

These properties are on the initial version of the control:

Foreground is supported and used for the implicit, centered point: it’s Black by default to match the Windows Phone’s ā€œMapsā€ app, but I find that using {StaticResource PhoneAccentBrush} looks great in my opinion.

MapCenter takes a GeoCoordinate, this is a key property.

ZoomLevel sets the zoom level (default of 15 I think) for the map. 1 effectively shows a bunch of the world, and 21 shows street level sizes. The zoom levels for Goog and Bing are pretty similar.

MapCenterVisibility defaults to Visible, and if you decide you don’t want the center point to be on the view, just set this to Collapsed.

IsSensorCoordinate should be data bound, some APIs (like Google’s) require that the API call identify whether it’s a position from a sensor, or a database. In my case, sensor is used for any GeoCoordinateWatcher/LocationService code, while I set it to False for data from the Foursquare venues database where I get info about a place.

Provider sets the static map provider to use.

The height and width are automatically identified by the system, but many APIs limit the width and height to small numbers (typically <= 640 pixels in any direction), FYI.

Bing Maps API Key

If you’re using Bing Maps, you’ll need a Bing Maps API key and to make sure that your app is compliant with the requirements of its terms and conditions. This is the same key you use with the Bing Maps control.

For this first version you have to set the API key as a string resource inside your App.xaml file.

Here’s how you would go about this: add the namespace and set the string – I’ve put a comment where your key should go in App.xaml:

<Application
    x:Class="StaticMapSample.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:core="clr-namespace:System;assembly=mscorlib">

    <!--Application Resources-->
    <Application.Resources>
        <core:String x:Key="BingMapsKey"><!-- Place your Bing Maps API key here--></core:String>
    </Application.Resources>

    <Application.ApplicationLifetimeObjects>
        <!--Required object that handles lifetime events for the application-->
        <shell:PhoneApplicationService
            Launching="Application_Launching" Closing="Application_Closing"
            Activated="Application_Activated" Deactivated="Application_Deactivated"/>
    </Application.ApplicationLifetimeObjects>

</Application>

I haven’t decided if this is better or worse than just exposing an API key property for you to bind or set on the page, but I really like just having one central place in an app to put the key.

Static map providers

The initial implementation has a simple enum for chosing between two provider choices, Bing Maps and Google Maps. I’ve decided to include Google Maps because it turns out that in some parts of the world, Google Maps are much better, and I’ve had hundreds of app users ask for a setting to instead use Google Maps. There are slightly different requirements for its API, such as exposing an ā€œopen in web browserā€ function so that the user could decide to open the same map view in the browser on the phone.

Just set the Provider property on the StaticMap to either Bing or Google. The default is Bing, as it should be!

Here’s a screenshot of the sample app I’ve included in the GitHub repo (though if you use it, remember to put your Bing Maps API key inside of the App.xaml file first!) – it has both Bing and Google Maps, and the application bar is hooked up to events to open the Maps app on the phone or to open the browser with the appropriate map page. Take a look.

SampleApp

On the right, the expanded app bar: your app may need to expose the ā€œopen in browserā€ option to comply with the terms and conditions that you interpret on the maps API of your choice. Also, the ā€œopen in maps appā€ is a nice function to provide users who want to open the location in the main OS’s Maps app.

Design note: flush maps

One design technique that I use in my app, as does the ā€œLocal Scoutā€ app in Mango, is having a ā€œflushā€ map experience: the map extends to the edge of the phone, instead of the standard spacing with margins from the edges of the phone.

This visual effect looks great, and can in general be created by setting the Margin of the control to ā€œ-12,0,-12,0ā€.

Hope this helps.

Categories: Blogs

Windows Phone apps, built out of ā€œthe 3 P’sā€: Panoramas, Pivots, and Pages

Mon, 01/30/2012 - 05:46

I can’t post a new component or library every day, but I can point you at other great blogs and folks on Twitter that would be super useful to app devs and teams building on the Microsoft stack.

This afternoon I read another of Arturo Toledo’s amazing series on Windows Phone Design – and it’s a simple but important point: apps are not just a choice between a Page, a Panorama, or a Pivot: many apps have aspects of all of these. The Music+Videos hub on the phone is built of all 3, and your app can pull that off, too: just understand the ideal content and purposes of these different types of core experiences.

31 Weeks of Windows Phone Metro Design | #5 Choosing between Panoramas, Pivots and/or Pages
Arturo Toledo
Senior User Experience Designer – Windows Phone Team at Microsoft

ScreenVSContentType
I ā€œborrowedā€ this image from Arturo’s post.

He’s had other great posts in the past, too, and expect great content to come.

Do follow Arturo: @arturot, Blog here, RSS

Categories: Blogs

PhoneThemeManager: allow your app to have the Light, Dark, or Inverted theme with 1 line of code

Thu, 01/26/2012 - 05:43

I’ve just pushed a small library that I created this evening to the world and wanted to share details on the short project in this post. (NuGet assembly, NuGet source, project on GitHub)

One of the most common feature requests that I receive for 4th & Mayor is a setting in the app to force it to always use the ā€œLightā€ theme, overriding the dark/light theme that the user’s set for their theme.

Having a light background is a nice contrasting design look for the phone, and the Mail application always does this. I personally always submit mostly light theme screen shots for my applications to the Windows Phone Marketplace, it just looks better and nice to me – but I rarely use all-light themed apps other than Mail.

In preparing for the next update of my app, v3.3, I’ve coded up this capability and I’m sharing it ahead of time.

Technical Overview

In 7.0 there were a few ways to do theme overriding, sometimes through a few silly platform bugs that we left in there – but it’s actually not an easy thing to do, and many people end up overriding every single style in their app to get the effect that they are going for.

This helper library is designed for altering the entire application’s running instance, not for providing per-page theme overriding.

In researching possible ways to solve this, I did come across this page on windowsphonegeek that talks about ways to merge in styles or to programmatically override resources that are brushes.

I decided to create a system to walk through the known values and names for all the core theme resources of colors, brushes, plus the light/dark theme visibility and opacity properties.

In your app, you simply call `ThemeManager.ToLightTheme()`, `ThemeManager.ToDarkTheme()`, `ThemeManager.InvertTheme`, to force this. You need to have this call happen inside your App.xaml.cs file, in the constructor, after the Initialize calls.

You cannot change or call this more than once, so if you offer a setting for users to ā€œForce Lightā€, use a MessageBox to inform them that their setting will be used the next time they start the app. You will have to read their setting right away when they start up the app. Once styles start applying the values, you could start to get inconsistent results.

The code walks and updates the Color instances, then walks the Brush resources and sets their Colors to be the original Color instances, just in case.

I have placed the ThemeManager class within the Microsoft.Phone.Controls namespace for this to be easy to add to your App.xaml.cs file.

You should have an App constructor like this:

/// <summary>
/// Constructor for the Application object.
/// </summary>
public App()
{
    // Global handler for uncaught exceptions.
    UnhandledException += Application_UnhandledException;

    // Standard Silverlight initialization
    InitializeComponent();

    // Phone-specific initialization
    InitializePhoneApplication();

    ThemeManager.ToLightTheme();

    // Other code that might be here already...
}
What’s themed

By default this is what happens:

  • The resources for foreground, background, all the contrast/chrome/etc. colors and brushes are updated
  • The light and dark theme visibility and opacity resources are updated
  • The background brush of the Frame is set explicitly to the color (may have a negative performance impact!)
  • The System Tray whenever a page navigation completes
  • The ApplicationBar of a page if set immediately

I’ve added a simple OverrideOptions enum (static) to the ThemeManager that can be used to disable the auto-behaviors I’ve added.

Newing up AppBars

If you have code in your app like ā€œvar ab = new ApplicationBarā€, beware that that application bar will take on the system’s actual theme colors by default, and not the overridden light/dark coloring that happens with the app.

If you need to new up an ApplicationBar, you should use the convenience method of `ThemeManager.CreateApplicationBar()` or use the extension method on app bar that I added, `MatchOverriddenTheme`, to set the color values.

What’s not themed

Unfortunately this cannot theme MessageBox at all.

Talking about fill rate performance

I’ve designed the system so that resources are only overridden when needed.

If your app uses ToLightTheme to force the light theme, and the user is running the Light theme already, nothing happens – it’s a no-op.

Although updating resources has no negative effect really on the app’s performance, the trouble is setting the Background color of the phone application’s frame.

The frame is always present and may add a fill count of 1.0 to every single page in your app.

Anything above a fill rate of 2-3 is not a good thing, so you may notice a degraded experience. Might want to inform your users of that when providing the option to force the light theme, for example.

A note about your battery

Many Windows Phones use AMOLED or similar technology where bright colors, such as the background color used in the Light theme, will use a lot of power. Please respect your users and realize that long-running apps probably should not force the Light option.

Consider only making such a ā€œForce Light Themeā€ option as a setting that users opt-in to, as opposed to always overriding the theme.

About custom themes

When I designed this library, I thought about offering a ton of capability in it for using ā€œbrandingā€ colors, modifying the accent brush, etc., but instead decided to tackle just one thing. So the name ThemeManager is a little overkill maybe, but it’s where we are for now.

Get the bits

NuGet Binary

The binary is super easy to use. With NuGet just add the PhoneThemeManager package reference.

NuGet Source File

Instead of adding yet another assembly to your project, just add the single source file (or add it to your existing shared library, etc.) by using the PhoneThemeManager.Source package.

GitHub Repo

Fork and enjoy https://github.com/jeffwilcox/wp-thememanager

Hope this helps.

Categories: Blogs

Please ship your next Windows Phone app with GZip: speed requests 50-80%

Mon, 01/23/2012 - 03:04

Please ship your next Windows Phone app or app update using this awesome GZipWebClient library by Morten Nielsen (NuGet, blog post, source) – it’s been out there since August and we should all be using this now for HTTP-heavy apps!

The next update of my app is in the works and performance is significantly improved by this library. I used both generation 1 and gen 2 devices to gather a ton of data and am loving the results. Can’t wait to submit the update to the marketplace. I’ve been seeing requests speed up 50%-80%, it’s amazing – but I should note, these are unofficial numbers, I’m just grabbing these from my app that is JSON-heavy.

GZipChart

Some sample data: a large set of averaged requests of a very large JSON request to the Foursquare web services used in my app, 4th & Mayor for Windows Phone 7.5.

These numbers aren’t official or anything like that, just what I was observing using my 3G data connection here in Seattle or home WiFi. Also interesting are the fastest times for the content – I often found that once a data connection was open, I would get as low as 100ms for some GZip requests. Just amazing.

One of the awesome modern web server features that nearly every browser happily supports today is Gzip compression of its output. Text and JSON beautifully compress, often by more than half, resulting in quick content downloads. It’s a simple and awesome way to improve the performance and responsiveness of your applications.

This isn’t a new technology, but unfortunately it isn’t just a default, built-in option for you to use in your Windows Phone apps, and you can expect that competing apps on other platforms (and even on Windows Phone) will be using Gzip to improve the performance. Hopefully we fix this in the future.

Frankly it isn’t a default in most mobile platforms, either, and you need to opt-in. However, some, like iOS, seem to automatically deflate incoming streams as long as you opt-in by setting the content encoding headers; in an iOS app, you just addValue ā€œgzipā€ forHTTPHeaderField before your request and you’re good from there. Android is similar but you do need to check for gzip in responses and manually new up a deflating stream with GZipInputStream.

HTTP Gzip and Windows Phone apps

So Morten Nielsen created a wrapping WebClient library over 6 months ago and through a few iterations has made it great.

So now it’s super easy to get this perf win. To make this work:

  • Add the library to your project via NuGet [SharpGIS.GZipWebClient]
  • Replace your WebClient code to use GZipWebClient instead – yes, just rename! (GZipWebClient is in Morten’s `SharpGIS` namespace)
  • Test and ship your app!

Now I’m not considering the server-side, but if you’re rolling your own web services, you might need to do some work to make sure that you’ll serve GZip content when the capability is ready on the client. Check with the documentation for your server-side app platform, cloud provider or web server technology.

I can totally see myself adding this to my core libraries for all future projects. Hope this helps. Thanks Morten for providing this to the community! You can follow Morten on Twitter (@dotMorten) or check out his blog (http://www.sharpgis.net/).

(And on the performance side: the smaller payload means networking rocks and is fast; it is worth noting that GZip adds a small amount of CPU load – hopefully in your background thread – but I haven’t detected anything negative from this yet)

Categories: Blogs

A quick look at MetroRadio: quick spacing, margin, and icon tips for Windows Phone devs

Mon, 01/16/2012 - 07:56

I’ve harped on this one a few times before in my Windows Phone Metro Design Guidelines post for devs. But it’s time for another helping!

Metro Radio is a slick and functional Pandora application for the Windows Phone. Like many apps, there are plenty of small little UX things that could make it even better. I saw the app recently and really like it, but as a stickler on design things, I’d love to make a few small tweaks if I could!

I briefly spoke with the application’s developer, Mustafa Taleb, and obtained his OK to me to write a little post just pointing out a few things. The app really does rock, but it’s also probably a place that in the next update a few visual blemishes could be fixed to yield an even better app.

So I’m going to point out simple things to think about when building out your UI. I have 9 points about simple spacing/design/margin things, and then a quick comment on the icon.

Margin Issues and other easy XAML Fixes

It’s pretty easy to overlook margins while developing applications. Between having controls like TextBlock that expect an associated Style, and most controls like Button that have an integrated margin and touch area, it  can be tough to either notice OR spend the time to fine-tune these things.

I don’t have the source to the app, so I am going to be overlaying yellow lines on top of the marketplace screen shots to help show potential issues with margins.

Text blocks: when to case plus the classic 12px left margin issue when not using styles

So here we have a few basics.

1. Consider all uppercase for the small font app title (very top visual in a page’s default template), unless you have branding or other reasons for that change.

2. Consider all lowercase for the larger page title.

Now these two aren’t hard-and-fast. I’m inconsistent in my apps, too. But I believe that you should be consistent: if you choose one, choose both.

3. Use the PhoneTextNormalStyle or other provided textblock styles OR hard-code at least a 12px left margin for text blocks. That way you align with other default visuals.

In this screen capture I overlaid a yellow block over the 12px space – really all the text should be to the right of that block, not under.

Here’s a super classic login page experience. And actually it is affected by the same issue of not using Style={StaticResource PhoneTextNormalStyle} in those TextBlocks, I’m guessing.

4. 12px issues create jagged forms often.

Recommended fix: Use the styles that are provided. The left of the text and the other controls should be aligned flush, not jagged like in this form.

Again this is because the default Margin of all TextBlocks is 0, but on the phone the styles set a left margin of 12px to allow for flush alignment.

Looking into Pivot specifics

Now on this one, there are just a few simple things when using pivots.

5. Consider lowercase pivot item headers.

It’s consistent with what you’ll find throughout the official phone user interface. This can either be accomplished through hard-coding lowercase in your XAML, using a string converter that goes lowercase with binding, or by doing it on the model/data side of your app.

6. Everything in a Pivot control should usually align left flush.

This page seems to have the actual item content off by 12-to-24 pixels, instead of allowing all things on the left to be flush.

Additionally, the space between the Pivot header and item is off by maybe just 2- or 4- pixels.

Look into spacing and alignment a lot on list pages

This is one of the screen captures of the list results when searching for the text ā€˜today’, one of the marketplace example screen shots. It could use some alignment and cleanup and could probably be cleaned up in a good 10 minutes of XAML hacking

7. Visually check for alignment consistency.

I’ve drawn a yellow line to try and show that many items here are not aligned: images, group headers, the top search controls, etc. This could be fixed in Blend through some movements or just in XAML by slowly adjusting by 2-, 4-, 8-, however many pixels until things are nicely aligned.

8. Try spacing list items by the same value on the top and bottom.

It looks pretty inconsistent when a list item (like the first here) has 2- or 4- pixels on the top, but then what looks to be 18 pixels or so on the bottom.

Instead using a consistent value for the top and bottom will let all items look natural regardless of whether they are first or last.

9. Have space between items and text.

The data template for these results could use some spacing between the album art and the text.

My guess is that this is another example of hard-coding font values instead of using the standard PhoneTextLargeStyle or PhoneTextNormalStyle with a TextBlock. That would add a nice left margin of 12px back into the UI.

And another quick example, this is a list page from the app that has some of the same underlying potential spacing issues:

And now, the best page in the app!

This is the playback experience and page. It rocks. It’s smooth, visually awesome, has good information, and is styled on the in-app Music+Videos UI. If I had to nit-pic, I might want to put 6- or 12- pixels of margin spacing on top between the artist name and song title at the top, but it’s nice.

Marketplace Application Tile

When I looked up Metro Radio using the Web Marketplace, the icon was … hardly there. This might be on purpose, but it’s really not a great branding experience – my guess is this either is a take on, or based on, the regular app icon, which adjusts itself to the accent color of the phone (hence a transparent background color).

Trouble with using the same asset is that the Web Marketplace, the Zune Marketplace, and even in some situations the regular Marketplace app on the phone, don’t do the same replacement with accent colors – so you get a visually difficult to see tile.

On-the-phone

This looks great. It’s important to realize that the different asset sets and sizes are used in different places – whether web marketplace, app, etc., you should always try and submit your best icon forward if you can!

Web Marketplace

Here you can see the hard-to-see tile for the app.

Suggested Fix: Always use a background color (easy if you’re layering in Photoshop or a similar tool) for your actual marketplace submission’s tile.

Zune Marketplace

Same icon issue here.

Hope this is useful. Thanks Mustafa for letting me write this post! And I should note, I’m publishing this without running it by him – he’s completely possible that some of these things were intentional design choices. If so, sorry if I have not agreed with them!

Categories: Blogs

A simple Windows Phone control for reading QR codes

Sun, 01/15/2012 - 02:05

There are great libraries out there written or ported to C# that let us developers rock by standing on the shoulders of giants. Here’s one such project.

A phone developer who’s also an enthusiast of foursquare suggested a feature that I should add in a future release, and provided some sample code based on the zxing barcode library and the Silverlight port of it. I’m working on adding the new feature soon.

In the process I realized it would be a good and quick opportunity to ship such a simple but useful control to the phone development community, so I’ve gone ahead and pushed that control refactoring and implementation to GitHub, check it out: https://github.com/jeffwilcox/wpqr-control 

Special thanks to Michael Osthege (@theCake, blog) for providing the initial contact, sample, and encouragement.

The control is nice:

  • Drop it on the design surface
  • Wire up the ScanComplete event (and optionally the Error event)
  • The control handles all the underlying image manipulation, scanning work, PhotoCamera initialization, etc.

Here’s what a simple sample app looks like in use. The control includes default border thickness and coloring properties that use the accent color and provide a nice visual separator:

ReadingQR

Technically the control will expand to its container size, but I prefer the squared-off 400×400 grid myself.

Building the sample app

All I did to build this app was drop the control into a new Windows Phone app project and wire it up. Here’s how.

References and XMLNS

Add either a project reference (if you cloned the git repo) or build the project and include references to assemblies, both the zxing library plus this control library.

To your XAML page where you’d like to use the control, make sure to include a namespace. Here’s what I used:

xmlns:jwqr="clr-namespace:JeffWilcox.Controls;assembly=JeffWilcox.Controls.QR"
Add the control

I added this XAML to my MainPage’s ContentPanel area:

<jwqr:QRCodeScanner
    ScanComplete="QRCodeScanner_ScanComplete"
    Error="QRCodeScanner_Error"
    Width="400"
    Height="400"/>
Implement code behind

The event handlers are easy enough. In my case, I went for these (just throwing exceptions):

private void QRCodeScanner_ScanComplete(object sender, JeffWilcox.Controls.ScanCompleteEventArgs e)
{
    ApplicationTitle.Text = e.Result;
}

private void QRCodeScanner_Error(object sender, JeffWilcox.Controls.ScanFailureEventArgs e)
{
    throw e.Exception;
}
Run the project on a Windows Phone

Hit F5! When you hover over a QR code, you should see its embedded text appear in place of the application title (top of the page).

Future/Improvements

I’d like to maybe add a sound when the scan is successful, but right now, nothing like that.

Eventually I may package this up as a NuGet package, but I’m not ready to prep the right spec files plus figure out how to properly attribute the sub-libraries at this time. So fork the GitHub version in the meantime! License is Apache 2.0 for both this library as well as the underlying zxing project.

(Looking to display codes? A few years back I briefly talked about the QR code system used by the sweet Starbucks mobile app on the iPhone. I implemented a prototype for Silverlight and Windows Phone that lets you render a QR code on the app’s surface, thanks to a nice QR code library. That post is here.)

Hope this helps.

Categories: Blogs