With the release of Windows 8.1 Update 1, Windows Phone 8.1, and Visual Studio 2013 Update 2, developers can now choose a different modern project type, the Windows Universal App. But with the Universal App comes three orientations, two platforms, and several new design considerations.
The Windows Universal App has three core orientations: Landscape, Portrait, and Narrow (sometimes called Minimal). Landscape is simply described as width greater than height, Portrait is simply described as height greater than width, and Narrow (or Minimal) is explicitly 320 pixels wide and is optional.
In the image above, we see the brown area indicating where the landscape experience appears on both Windows and Phone. The blue area indicates where Portrait appears on both Windows and Phone. And, the green area indicates where Narrow (or minimal) appears only on Windows.
What do you ask a designer to design?
Your first option would be to ask for three designs: portrait, landscape, and narrow (optional). But you will most likely ask for five: landscape-Windows, landscape-Phone, portrait-Windows, portrait-Phone, and Narrow. Why? Not because the controls don’t morph between platforms. They do. But when your goal is a pixel-perfect modern app, it’s the only way to handle it properly.
So what do you share?
With Universal Apps, Visual Studio now supports a shared project type that allows your Windows and Phone projects to share their code. But when it comes to sharing XAML, you would only share XAML you design and intend for both platforms. So, what do XAML do you share?
XAML – it’s difficult to find a truly cross-platform bit of XAML. Perhaps your about page, perhaps your login page. But as long as you are designing your phone experience for the Phone, that might be it. Remember, you can force this; we’re just discussing what’s most realistic.
ASSETS – it’s unlikely you will share your assets as Windows and Phone have different scaling factors. You put put all Windows and all Phone assets in one Shared folder, but it would difficult to explain why that’s good. Some assets, of course, might be shared, but it will represent a minority.
VIEWMODELS – the viewmodels you create for your Phone will be smaller than for Windows, if for no other reason then the added functionality fit onto a tablet. Do you want to bring tablet viewmodels into memory for your Phone app? It’s also common practice to put viewmodels in a PCL for testability.
STRINGS – you may have considered your localized strings. And though many aspects of your app will share common translation, it’s also true that the delta in the UI will mean your strings will not perfectly match. I suppose you could share the superset of strings, but again your phone app suffers the cost.
Every app will be different. If you look at many of the sample apps, you will see you can share a considerable percentage of XAML. But in practice, and in light of a pixel-perfect design, you might find the shared project is for shared logic, not shared user interface. Again, every app is different.
Of course, the shared project is amazing. It allows you to put logic and common assets in a single place. When you are creating a single Universal App, this is valuable and brings together considerable synergy. The problem only arises when developers start to think they want to share everything. It’s not practical.
Here are some real strategies to make shared projects share even more code:
1. Sub-Class. You can have a minimal implementation in your shared project that exists, then, in both Phone and Windows. To extend that implementation into a specific platform, just subclass it in the head project.
2. Partial-Class. C# introduced partial classes several versions back – it allows a single class to be defined in more than one physical file. Having a partial implementation in the shared project and the other partial specific to the platform in the head project is a very reasonable solution.
3. Conditional-compilation-directives. This is the #IF WINDOWS_PHONE_APP directive that tells the compiler to ignore bits of code when the platform is not in context. Sometimes this is a great solution. Typically it isn’t. Why? Because directives are considerably difficult to read/scan by developers.
4. User Controls. Why not create platform-specific UI in user controls that reside in the head project and then are referenced by a container XAML in the shared project? Sometimes this is a pretty neat strategy. Typically, it’s just added complexity without any valuable gain.
If I had to choose one of those four, I would choose partials.
Best of luck!