WP to W8: User Interface
|This article is part of a series about my experience porting apps from Windows Phone to Windows 8. Official porting guidance can be found here and don’t forget to follow the Building Windows 8 blog and the Windows 8 App Developer blog for the latest information.
If you are currently working on a Windows 8 app that you’d like reviewed for possible early entry into the marketplace, please contact me.
In this article I want to expand on the information already available about porting user interfaces from Windows Phone to Windows 8. The most important place to start is an article titled Porting Silverlight or WPF XAML/code to a Metro style app on MSDN. It covers slight changes in the Application object, Window object and Navigation system. It also covers more involved changes to the Resource model and to Touch. I’ll talk briefly about touch at the end of this post and I’m dedicating an entire article to resources (hyperlink here when it’s done). If you haven’t done so yet, consider switching over to the official guide and coming back here when you’re done.
One of the biggest adaptations developers needed to make coming from any other platform to Windows Phone was learning to use the Metro design language in an effective way. If you’ve already built a successful Windows Phone app, chances are you’ve already made this change. Still, there are new and unique guidelines for Windows 8 apps that you need to become familiar with. In fact there are guidelines for things you might not have thought about having guidelines for, like drag and drop and edge-based animations.
These guidelines exist to make the Windows 8 experience consistent from application to application, which is important because consistency builds confidence for users. Luckily a good chunk of the work is already done for you simply by leveraging the built-in controls. Even if you’re creating highly customized content or your own controls, WinRT makes it easy to fit in by providing standardized animations and transitions right out of the box.
To learn more about the standardized animations and transitions see Quickstart: Animating your UI. For tons of great Metro guidance see Making great Metro style apps, UX guidelines for Metro style apps and design.windows.com.
Windows 8 of course has all the basic controls you’re used to like Button, CheckBox, ListBox, etc. As you may have heard, though, the namespaces are a little different. For the most part, simply changing references from System.Windows to Windows.UI.Xaml will get most of the basic tags working. But since we’re on the topic of namespaces, it’s important to note that the namespace syntax itself has changed.
Here’s the old syntax:
And here’s the new one:
Not only is the new syntax simpler, but it leaves all of the assembly management to the underlying framework. This change does impact how you create things like strings though, so I highly recommend you read Porting Silverlight or WPF XAML/code to a Metro style app for more details.
You might be surprised to learn that Windows 8 does not include the Panorama or Pivot controls from Windows Phone. Keep in mind those controls were created to deal with small screen real estate, which isn’t much of a problem on Slates and desktop monitors. It’s vitally important to make good use of all the screen real estate available and the new SemanticZoom FlipView and GridView controls can help you accomplish this. Though FlipView could potentially be used to create sliding panels similar to a Panorama, don’t get caught up in trying to port your phone experience as-is. Instead, spend plenty of time playing with Windows 8 applications and understand the new controls. A GridView combined with SemanticZoom can offer a better experience on a larger screen than a Panorama would.
In my opinion, one of the most aesthetically pleasing apps in Marketplace right now is Flixster. Not all of the features from Windows Phone made it into the current demo, and it doesn’t currently use SemanticZoom, but I think it shows a good migration from Panorama to the new Windows 8 style.
M-V-VM, Data and Portability
“Oh no!” you say, “Now that there are new controls all of my UI code has to change!” Not true if you’ve been following the popular M-V-VM pattern. M-V-VM allows you to separate the underlying business logic from what’s displayed on the screen. With M-V-VM there’s a ViewModel that provides data and commands that the View can bind to. If you’ve already done the work to put M-V-VM in place, your XAML will change but the underlying ViewModel may not have to change at all.
There are other interesting tricks you can employ to share code with Windows Phone. For example, Visual Studio 11 has the new Portable Library project which allows you to create DLLs that can be referenced and used in both projects.
If you haven’t been using M-V-VM or if you’d like to learn more about these techniques, be sure to read Improving Maintainability. To learn more about data binding in Windows 8 (including Grouping for GridView and SemanticZoom) see the article Data binding with XAML and the XAML data binding sample.
|NOTE: There’s currently a bug in Consumer Preview with data binding to ObservableCollection<T>. The XAML data binding sample provides a workaround.|
The Windows 8 AppBar feels similar to the Windows Phone Application Bar, but there have been several improvements. One of the improvements I’m quite happy to see is support for data binding. I mentioned commands as part of the M-V-VM pattern above. In the current Windows Phone SDK there’s no way to bind AppBar buttons to M-V-VM commands, but in Windows 8 you can.
Windows 8 will run on a wide range of devices so user interfaces need to scale. Because of this need to scale, vector graphics are preferred for iconography over bitmap images. (WinRT has mechanisms for scaling bitmaps beautifully too, which I’ll talk about below.) With scalability in mind, the Windows team did something I think is very cool: they embedded the most common AppBar icons in a font called Sego UI Symbol. Font scaling works very well for this purpose, and if you drop an AppBarButton onto the art board and change its Scale (Transform panel) you’ll see what I mean.
Unfortunately there isn’t currently an easy way to choose icons from the font using Blend or Visual Studio, but there are a few tricks. First, you can run Character Map and select Sego UI Symbol. Once selected, scroll down to the bottom and you’ll see the icons.
Click the ‘icon’ you want, click Select and then Copy. The ‘icon’ is then placed on the clipboard, ready to be pasted it into any button (or text block) that’s using Sego UI Symbol.
|Tip: To run the Character Map tool, from the start experience just start typing the word “character”. The start experience will automatically switch to ‘All Applications’ mode and begin filtering the list on what you type.|
Now to make things a little easier on developers, Visual Studio includes a file in every project called StandardStyles.xaml. This file has within it a number of predefined button styles that are setup to use these icons. Blend allows you to drag these styles out from the asset panel to automatically create a button with the style already applied. So, for example, if we wanted to create a help button we could drag out the following:
It turns out that Sego UI Symbol includes around 150 icons, but StandardStyles.xaml currently shipping with Visual Studio only includes styles for 29. You can either edit the style and use the Character Map trick above, or you can download an Updated StandardStyles from Tim Heuer. His awesome blog post XAML AppBar Button Styles for Windows 8 covers this topic and using these styles in even more depth.
150 icons is great, but what if you don’t find the icon you’re looking for? Don’t worry because there are several other really great options remaining. One of my favorites is the awesome Metro Studio package by Syncfusion.
This package includes over 600 Metro style icons and gives you unprecedented control over their presentation. You can change the background type (none, square, outlined circle, filled circle), the padding, the background color, icon color and even the size. You can export the customized icon as .png, but even better you can copy the customized icon as a scalable XAML ready to be pasted into your applications resource dictionary. How much does this incredibly cool package cost? $0.00. Yup, free. Just drop ‘em a note to say thanks on Twitter, Facebook or Google+.
Okay, so that’s 750+ icons. But what if you still can’t find what you’re looking for? Well, there are plenty of other icon packs (just search for Metro Icons) and you can always create exactly what you need using Expression Design, Adobe Illustrator or my new favorite InkScape.
InkScape is free, open source, and can save as scalable XAML natively.
Windows 8 supports a wide range of devices with varying resolutions and DPIs (dots per inch). This is different from Windows Phone which today supports only one resolution. Those who have written apps for Android might know what a challenge this can be, but fear not! Once again WinRT does most of the heavy lifting for you.
First, Windows 8 supports ViewBox, just like Windows Phone, which is great for games and fixed-layout interfaces. On the other hand, GridView and Grid are great tools for creating flexible layouts. Something you might not expect is that even in flow layouts, Windows automatically increases the scale of some UI elements as the DPI goes up. This automatic scaling makes sure that items like buttons and sliders are just as easy to grab with your finger at 260 DPI as they are at 130. This scaling, however, does not happen continuously across the full range of DPIs. Scaling only happens at certain thresholds. This is because apps still use bitmap images and bitmaps don’t tend to look great when they’re scaled to arbitrary sizes.
from the Building Windows 8 blog post Scaling to different screens
The scaling thresholds are set at 140% and 180% of the baseline resolution 1366 x 768. When these thresholds are reached, vector graphics inside ‘auto-scale’ elements are automatically scaled too. But what about bitmap images? Well, the WinRT resource system is smart and it will look for higher resolution images (based on a naming convention) to be automatically swapped in when the scale changes. The key takeaway, for me at least, is to design at 1366 x 768 and use the Platform tab in Blend and the Simulator to test designs at all resolutions and DPIs. At the very high end of the scale, it’s probably also prudent to consider modifying layout or swapping in different Data Templates to make the best use of the space.
More than anything I highly recommend the excellent article Scaling to different screens on the Building Windows 8 blog. It covers everything I covered here in far greater detail and it gives an inside peek at the factors that lead to this design. I really did find it fascinating. Guidelines for scaling to pixel density and Guidelines for scaling to screens are two other excellent references that cover naming conventions, fixed and flex layouts as well as general “Do’s” and “Don’ts”.
Windows Phone developers are used to having the entire screen available for their app. Even system dialogs like phone calls and toasts appear on top of the application and don’t change available real estate. A Windows Phone developer today can design a user interface at 480 x 800 and expect it will work across all Windows Phones (though Microsoft has always reserved the right to add additional resolutions at some point).
In addition to supporting a much broader range of screen sizes and resolutions, Windows 8 applications are also required to support two new view states: “Snapped” and “Filled”.
In the screenshot above, Cut the Rope is running “Filled” and Music is running “Snapped”. These two new states are what allow two normally full-screen applications to run side-by-side and share the screen.
It’s very important to point out here that the Music app looks quite different in Snapped mode then it does in full screen. The rows of album art and the large track bar have been replaced with a small and concise listing of tracks. This fairly radical change allows the Music app to remain highly useful even with small amount of space it has. It’s no surprise that users will expect this type of behavior from your apps too.
If all this sounds daunting, you’re not alone. When I first read about the Filled and Snapped states my head was filled with visions of user controls, Xaml hacking and showing and hiding things in code. Thankfully, I couldn’t have been further from the truth.
Many Windows Phone apps today support landscape since we basically get it for free. Some of the more advanced apps are even using the Visual State Manager to switch to a customized layout that looks better in landscape mode. This same trick can be used for “Snapped” and “Filled”, and the Visual Studio templates help you do exactly that out of the box.
|Note: An introduction to the Visual State Manager is outside the scope of this article, but if you’ve never used or seen it before I recommend you check out the article and accompanying video Creating Control Skins with Visual State Manager on Christian Schormans blog.|
Whenever you create a new project, Visual Studio automatically adds a file under the Common folder called LayoutAwarePage.cs. LayoutAwarePage inherits from Page and adds four new visual states to itself:
As you can see, the visual states correspond to the four possible view states that your app can be in at any given time. Using the Visual State Manager you can show, hide or change virtually any property of any element on the art board and those changes will only be applied when your app is running in that state.
For example, let’s take a look at GroupedItemsPage (part of the ‘Grid Application’ template included with Visual Studio). Here GroupedItemsPage is in the FullScreenLandscape state (click for larger view):
And here it is in Snapped state:
This works because the page actually has both a GridView and a ListView on it at all times. When the Visual State changes, one control is hidden and the other is shown (accomplished by changing the Visibility property).
I’d like to pause and point out that in the ‘Snapped’ screenshot above, the app still looks like its filling the whole screen. That’s because the Visual State Manager and the Platform tab aren’t currently wired together in Blend. In other words, telling Blend that you want to see what the page will look like when viewed Snapped on a 10” slate doesn’t automatically trigger the Visual State Manager to switch to the Snapped state. (Remember, this is automatic switching is handled at runtime by LayoutAwarePage which Blend knows nothing about). So, to properly preview your designs in Blend you should set the correct View on the Platform tab:
and set the corresponding State on the States tab. When they’re both in sync, the art board should show what you’d expect to see at runtime on that device (assuming you’ve got design-time data).
I dedicated the second post in this series to a step-by-step example of using this technique. See View States using Visual State Manager. And for more info see Designing flexible layouts and Guidelines for snapped and fill views. These pages provide additional guidance on scaling your interface to fit and be useful in Snapped view.
The on-screen keyboard is an integral part of Windows 8 and there’s little doubt that external key devices (i.e. remote controls) will continue to grow in popularity as well. With that in mind, all Windows 8 key events return a VirtualKey enumeration rather than a literal keyboard scan code.
If your Windows Phone app somehow uses scan codes, either update it to use the new enumeration (best) or check the KeyEventArgs.KeyStatus.ScanCode property to see if the virtual key has a mapping to the original scan code.
For more information see Plan for accessibility.
Windows 8 is designed to be “touch first”, but it’s also designed to work exceptionally well with a mouse and stylus. To make supporting all three pointing ‘devices’ as easy as possible for developers, mouse-specific events were replaced with new unified Pointer events like PointerEntered and PointerPressed.
Something else I found really interesting is that individual pointer events can be enabled and disabled per-element. On Windows Phone you can “hide” any element from all touch events by setting IsHitTestVisible=false. On Windows 8 you can hide it from specific events by setting properties like IsRightTapEnabled.
For more information see Responding to user interaction.
Well, that’s it for the User Interface article (whew!) Be sure to bookmark the series and check back soon for more articles on porting Windows Phone apps to Windows 8!