TechEd Australia is all wrapped up, and I wanted to let everyone else know about one of the new concepts we’re introducing around application structure. As we’ve previously discussed, Windows Phone 7 applications are composed of pages that exist on a back stack and can be accessed by the user with the hardware Back key.
What we haven’t been so clear on is exactly which parts of an application should be a page and which parts shouldn’t be a page, and lots of folks both internally and externally have been bumping into issues around login screens, infinitely-growing back stacks, and so on. The good news is that we finally have some guidance to share around these issues that should help you to build apps that fit in with the navigation-based user model and still meet all your functional requirements. Not to worry though – this isn’t something entirely new. It’s just a refinement on the page-based model we’ve been talking about all along, but takes into account transient UI, content browsing, and other scenarios. We’ve also tweaked the 1st-party apps to follow this model, whereas in the past there were some inconsistencies there, too.
The basic premise is that the phone (and hence the applications on it) consist of a set of “places.” A place is a “user-recognizable collection of persistent state” (thanks to Alan Bush for that succinct description!) or in layman’s terms it’s a screen that the user visits that contains information, content, or links to other places. Now since a picture is worth a thousand words, let’s take a look at the structure of a typical content-browsing application (click to enlarge):
(I apologise for the muted tone of that image; the Tech-Ed organisers like to use a very bland palette in the slide templates!)
What the picture is showing is a simple app that consists of a Home Screen, an All Widgets list, a Details View for Widgets (which consists of several pivots), a Details View for Gadgets, a Search screen and a Settings screen. The application also has a Splash Screen and a Login screen. The arrows represent transitions between screens, with the special case for Login that several of the screens can show the login screen depending on various situations (returning from tombstoning, cookies timing out, etc.). Note that both the Widgets details page and the Gadget details page have little circular arrows on them, meaning you can transition from one Widget (or Gadget) to another without going to a new screen – this is very much like the way Outlook on the desktop lets you switch to the Previous or Next mail inside the same item window by clicking on the little blue arrows:
(Those lucky folks with Windows Phone 7 prototype devices will recognize this same behaviour in Outlook on the phone, too). This is also how a typical photo viewing application works – once you have drilled down into the album and then into an individual photo, you typically switch to different photos in-place by swiping left or right (or clicking previous / next arrows on the desktop).
You’ll notice that I was very careful to use the word “transition” rather than “navigate” in the description above, because not all the arrows represent navigations – only transitions between different places are navigations. The following transitions don’t represent navigations because they do not switch to different places (and because they’re not navigations, they’re not on the backstack and aren’t automatically reversed by the back key):
So hang on – how did we determine that the Splash Screen and the Login Screen are not places? Well, let’s look at the definition again: a user recognizable collection of persistent state. The splash screen clearly doesn’t contain any state – it’s just smoke and mirrors to make the app launch seem faster than it really is – and the login screen doesn’t really contain any state either; it simply asks you for credentials. The “user recognizable” bit can also help you determine if other parts of your UI should be places or not by asking a couple of simple questions: Would the user explicitly want to visit this screen? Would the user remember they were on this screen, and want to return to it? The splash screen and login screen both fail these tests too; you don’t really want to see either of these screens (they just appear at the appropriate time) and once you’re in the app you don’t particularly remember seeing them or want to return to them. They’re speed bumps that get in the way of the actual content that the user really cares about.
Yet another way to think of it: if you were building a web site and could provide a deep link to a particular screen, would you bother to do so? Again the splash screen and the login screen both fail that test, except of course for those sites that want to force you through an intro movie. (I just wasted about half an hour trying to find the old “skip intro” website – you know, the one that had an endless intro movie that made fun of Flash intros – but couldn’t find it… bonus points to anyone who can link to it in the comments!)
So what to do about these non-place screens and these non-navigational transitions? Well, the splash screen is an easy case because we take care of it for you. It’s never on the backstack so the user can never return to it. As for things like the login screen or other transient UI, the Silverlight Popup control is a great solution for showing content that (partially) covers the screen without doing a full navigation. And of course you can hook up the BackKeyPress event and set e.Cancel to true while the login screen / popup dialog / etc. is visible to enable the familiar “back closes dialogs” behaviour without worrying about navigation.
For places that are used to view multiple pieces of content (Widgets and Gadgets in this case), you can transition between them easily enough without navigating by simply re-binding the controls on your page to a new DataContext, or by loading multiple instances of a UserControl inside of the page, or by any other mechanism that you might like to use for showing new content inside a single page. The mechanism through which the user transitions forwards and backwards through the items is up to you – for example, using “previous” and “next” AppBar buttons – but whatever you do please don’t abuse the Back key for local transitions!
One question that is left up to the reader is whether to save a local history of transitions that occur in a given place so that if the application is tombstoned the user can retrace their steps. I say “local history” because these aren’t navigations and aren’t on the backstack and hence aren’t managed by the normal backstack (and I repeat: whatever you do, don’t override the Back key to unwind the local history of a given place!). For some things, like simple previous / next browsing (e-mails, photos, search results, etc.) all you need to save in your page State is the current index, which along with your NavigationContext should provide all the information you need to traverse the dataset when returning from a tombstoned state. For applications that have a more complex local transition history, such as free-form browsing of linked items (think: Amazon- or IMDB- style application), you may choose to store some of that history in page state but you will probably want to put a reasonable limit on the number of items you store. The key point is that if the user hits the hardware Back key they return to the previous place (eg, category screen, search results list, etc.) and not to the previously-viewed item.
Here’s a handy guide you can use to help figure out what common parts of an application are places and which are not:
Type of screen
Transient part of the startup experience; user cannot navigate to it
A common “home screen” approach for Windows Phone applications
Very common for data-centric apps, parameterised via the query string
A pivot item is a smaller part of the larger pivot page, which is the place of interest
Login dialog or Error dialog
Transient UI triggered by application state; user does not navigate to it directly
Browsing similar content is an “in-place” activity, not a navigation
And a quick summary of how to deal with various types of screens:
Back key behaviour
Automatically goes back or exits the application
Don’t override except in the case of data loss
Automatically remains on backstack
Popup, ChildWindow, etc.
Application should override to cancel the popup
SIP and MessageBox automatically cancel themselves on back
Application should dismiss / cancel popup during navigation
N/A; hosted inside of parent page
Application should save active item as appropriate
One more post on the subject of keeping screens out of the backstack. A common scenario we see is a variation
Nice work on the two nav posts. An example flash intro for you here :)
> anyone who can link to it in the comments
Thanks Mick - I was specifically looking for a site that consisted ONLY of an endless (and very over-the-top) Flash intro page... I though it was skipintro.com but that's not it.
What about the list that is transitioned to for a picker box? Is that considered a navigation? I was playing around with the language picker in system settings and noticed that if I had the language list open and clicked the start button and then clicked back, it would take me back to the region & languages page, not the language list. This would imply the language list is not a page. Is that true?
I can't help but feel that the WP7 team has gone and taken a very simple problem and introduced a lot of complexity. By attempting to automate navigation for the yet unbuilt set of phone applications, you've created a very rigid set of architectural constraints which were completely unnecessary. As a result, as you have pointed out, developers will still have to maintain their own internal history, etc independent of the platform. Furthermore, they now have two sets of histories to deal with, one of which is completely uncontrollable by them. I've heard a lot of WP7 developers complaining about this and other application lifecycle issues. They've been saying that It's reminiscent of the ASP.NET WebForms page lifecycle disaster. It's really sad that Microsoft is so slow to learn from their own mistakes or to involve UI architecture experts from the community who could have steered you towards a simpler and more flexible model. It seams that in your attempt to keep WP7 so secret for so long, you may have actually jeopardized the platform by preventing knowledgeable individuals from having an opportunity to provide feedback and guidance.
Matt: Thanks for the comment. A picker is like a popup and is not a place. I don't see the behaviuor you describe (language popup on the backstack) in the current versions of the phone -- it is entirely possible that earlier versions of the OS had this behaviour, but as I mentioned above we tweaked all the 1st-party apps to use this new pattern as well.
EisenbergEffect: Thanks for spending the time to comment. There's a couple of things that may make this better than it seems. For one, the idea of "places" is just a guideline for you to follow if you want your application to follow the same interaction model as the rest of the phone. There is no requirement to use it - other than some basic rules like "the user must be able to exit the app with the back button" and so forth - although we hope people will consider using it to avoid confusing users. You can build your entire application inside a single page if you like, and deal with different screens of information using the existing framework of your choice. In fact this is how XNA games work -- they don't have the concept of pages at all, and each game manages its individual screens or menus manually. Also this is just the first release of the phone and we are very interested in the community's feedback for making the model more flexible in the future; if you have any suggestions you know where to find me... ;-)
Thanks for the clarification, it is stuff like this that defines how polished a platform actually 'feels' even though it might 'look' polished.
How will inconsistencies like these be handled when submitting an application to the Marketplace?
From a user point of view I would deny anything before it followed this model while as a developer I know how tough deadlines can be on small/startup companies that need every penny. Though I'd still lean toward the user pov.
The marketplace guidelines don't require you to use this specific model, although there are some rules about backing out of the app from the home screen, etc. You can read the guidelines / requirements from developer.windowsphone.com