Windows/Phone 8.1: Prism for the Windows Runtime (Universal)

An early drop of the Prism framework for Windows Runtime apps that supports “Universal” apps has gone onto the CodePlex site as flagged by Blaine on his blog last week.

I’ve talked about Prism for WinRT a few times (the last screencast video being only a few blog posts ago here) and I’m very keen to see the start of “Universal” support so that a developer that wants to use Prism can have a consistent framework to support them on both Windows and Phone.

I pulled down the bits from CodePlex and opened them up inside of Visual Studio – there’s 3 folders in the zip file that I pulled down;

image

and I wandered into that Converged folder and opened up the bits. In order to get them to build (as advised on the website) I also brought down the two NuGet packages;

  • Prism.Mvvm.1.1.0.nupkg
  • Prism.PubSubEvents.1.1.0.nupkg

and dropped them into a local NuGet feed folder (via the Tools->NuGet Package Manager->Package Manager Settings dialog) and then I could get things to build.

There are quite a few projects within that solution;

image

the WebServices project and the Tests projects all probably speak for themselves. There are 3 projects building up Microsoft.Practises.Prism.StoreApps – i.e. the bits specifically supporting Windows/Phone Store apps;

image

but the majority of the code builds into the Portable class library (red below) and only a single class resides in the StoreApps.Phone and StoreApps.Windows projects (blue below);

image

It’s an important class though as it provides the base class for your “App” class and that MvvmAppBase.cs file is actually linked from the Windows project into the Phone project – i.e. it’s the same source file with a little bit of conditional compilation in it where Windows/Phone have differences over;

  1. Standard support for settings (Windows has this, Phone does not)
  2. Hardware back button (Phone has this, Windows does not)

and so there’s really very little difference between the two platforms here and what looks like 3 big projects is almost 1 project with one class which needs some minor conditional compilation.

That said, this would mean that there isn’t one MvvmAppBase class in one library for your code to reference and derive its App class from. There are 2 – one for Windows and one for Phone and they build out into two separate libraries which would work well if you’re consuming that MvvmAppBase class from a piece of code that lives in a Shared project but might make life a bit more difficult if you wanted for some reason to have your App class built into a single library.

That’s all of the framework code.

The rest of the code is the “AdventureWorks Shopper” reference application with an implementation here for both Windows and Phone. In previous deliveries of Prism, the implementation was only for Windows so it’s great to see this arrive on Windows Phone.

Again, it looks like there are 2 libraries here supporting the UI logic of the app;

image

but if you look at the UILogic.Windows project above, you’ll notice that it only has one additional ViewModel within it – that’s the ViewModel for supporting Search on Windows 8.1. The rest of the code is portable across Windows/Phone 8.1 and that includes quite a lot of pieces here – across those folders Models, Repositories, Services, ViewModels above there must be 80+ classes all shared between Windows/Phone.

The AdventureWorks app sits on top of this library and it is now packaged as a Windows project, a Phone project and a Shared project;

image

If you dig into that, you’ll spot that pretty much all the code is in the Shared folder as indicated below;

image

whereas the Windows/Phone specific projects have some specific bitmaps and then, as the underlying logic project suggested, a specific handling of a search user control;

image

That results in more shared code between these 2 apps than I would have maybe expected and perhaps one reason why that’s possible here is the use of the DataTemplates.xaml file in the individual Windows/Phone projects here.

The App.xaml file which is in the Shared project is being used to merge in the platform-specific variant of DataTemplates.xaml into the app’s resources;

image

and so the Prism guys have used that as a way of having different DataTemplates with the same names across Windows/Phone to account for different sizes and styles of templated items.

Because there’s a lot of shared (design time and run time) views in the Shared project, it’s possible to edit those views at design time in both “Windows mode”;

image

and “Phone mode”;

image

with design-time data supporting those two different views (although I’m not 100% sure about the presence of the back button on that HubPage in the Phone screenshot above and I don’t think it appears at runtime so maybe there’s some tweak missing there).

Taking a quick tour around at runtime the initial screen looks to offer similar functionality on both types of device;

image

1

although there are differences at the moment in that on the Phone;

  1. I’m not sure how to search.
  2. I lose the semantic zoom (to be expected, that’s not really something you do on the Phone).
  3. I lose the navigation bar functionality that allows me to jump straight to “Home” and “Shopping Cart”.

Navigating into a particular group seems pretty equivalent;

image

2

although I wouldn’t expect the Phone to be displaying that back button Smile and product details is also similar;

image

3

and both platforms have the “Pin to Start” functionality although I think the Phone loses the FlipView that Windows is using to allow easy navigation to the next product and I’d argue (from a position of weakness as I’m no designer) that both layouts could be improved here.

The Shopping Cart view looks to be the same on both devices;

image

4

although I’d argue that the mechanism for selecting an item and then having an option to edit the quantity or remove the item feels more natural to me on Windows than on Phone where I’m not sure this metaphor is quite so common;

5

Ultimately though, this is an initial drop rather than a release so it’s great to see the Prism guys working away at Universal app support and it’s great to see them getting bits out early and the Adventure Works shopper is a great thing to have as a reference for an app developer to be able to take a look around, see how things were done in the reference implementation and apply similar techniques to their own applications.

I’m going to have a stab at updating the demo that I showed in this session to be more “Universal” and I’ll post back to the blog if I have success in getting that to work.

In the meantime, if you’re using these kinds of techniques then grab those early Prism bits and provide feedback to the team – they’re very keen to hear from you.

Windows 8.1 Apps: Updated Prism for Windows Runtime Session

I found a screencast version of the talk that I did at TechDays in Holland last month and thought I’d share that here as it is arguably a better quality than the one I referenced from the blog post last month;

When I posted the previous session, I got asked for the source code for the little demo app that I built up and so I’ve just run through my own demo to re-create that and that’s available;

Source Code for Small Demo In Session

Enjoy.

Windows 8.1 Store Apps, Prism and Visual Studio Templates

In writing a post last week about the availability of the Prism framework (and guidance) for Windows 8.1 Store Apps, I talked a lot about how a blank app with Prism might compare with a blank app using the standard Visual Studio templates.

Whilst writing that article, I was thinking that it’d be “kind of nice” if the Prism guys shipped a template or two for Visual Studio to make that whole piece of work involved in “getting started” on a new app as easy as it is to just use the File->New Project option in Visual Studio.

The Prism team don’t ship templates themselves but they mentioned that Dave over here does have a set of templates and Dave also commented on my post and included a link to his post about the templates (thanks Dave!);

Prism Templates (on Dave’s blog)

I thought I’d download these from the Visual Studio Gallery and see what it was like to get started.

As Dave’s post explains, this adds two new project templates into Visual Studio;

image

and I thought I’d experiment with the “Prism App” template to compare using it with what I did in my previous blog post because, naturally, the other template brings in the whole topic of Inversion of Control and a specific IoC container (Unity) which may or may not be the direction that you want to go in.

Creating a new project means that I don’t need to go out and explicitly reference the Prism libraries because they are already present;

image

and looking at my App class, it’s already been derived from the Prism MvvmAppBase class and that class has just a little bit of code in it;

  sealed partial class App : MvvmAppBase
  {
    public App()
    {
      this.InitializeComponent();
    }

    protected override Task OnLaunchApplication(LaunchActivatedEventArgs args)
    {
      NavigationService.Navigate("Main", null);
      return Task.FromResult<object>(null);
    }

    protected override void OnInitialize(IActivatedEventArgs args)
    {
      ViewModelLocator.Register(typeof(MainPage).ToString(), 
        () => new MainPageViewModel(NavigationService));
    }
  }

Much like I did in my previous post this just makes sure that when the app is launched it navigates to the “Main” page and the OnInitialize override says that the MainPage should be provided with an instance of the MainPageViewModel which is constructed with the INavigationService that is owned by the App.

In line with Prism’s convention, my “Main” page is a class called MainPage.xaml in a sub-namespace called Views and it’s already in the project;

image

and the template has done the right thing to ensure that this page is derived from Prism’s VisualStateAwarePage which means that the page picks up some abilities around determining visual state and also around navigation. The XAML that the template uses also specifies that the framework should automatically work out the right ViewModel to provide the DataContext to the page (done via the ViewModelLocator.AutoWireViewModel property).

The other thing that the page template does is to add in a little piece of XAML to define a page with a grid containing a header section and a content section. In the header section is a title and a “go back” button which is wired to the GoBackCommand that the VisualStateAwarePage provides.

<prism:VisualStateAwarePage
    x:Name="pageRoot"
    x:Class="PrismApp1.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PrismApp1.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:prism="using:Microsoft.Practices.Prism.StoreApps"
    mc:Ignorable="d"
    prism:ViewModelLocator.AutoWireViewModel="True">

    <prism:VisualStateAwarePage.Resources>
        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">MainPage</x:String>
    </prism:VisualStateAwarePage.Resources>

    <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ChildrenTransitions>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Grid.ChildrenTransitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Back button and page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton" 
                    AutomationProperties.Name="Back"
                    AutomationProperties.AutomationId="BackButton"
                    AutomationProperties.ItemType="Navigation Button"
				    Command="{Binding GoBackCommand, ElementName=pageRoot}"
					IsEnabled="{Binding CanGoBack, ElementName=pageRoot}"
				    Margin="39,59,39,0" 
                    Style="{StaticResource NavigationBackButtonNormalStyle}"
                    VerticalAlignment="Top" />
            <TextBlock x:Name="pageTitle" 
					   Grid.Column="1" 
                       IsHitTestVisible="false" 
					   Margin="0,0,30,40"
					   Style="{StaticResource HeaderTextBlockStyle}" 
			           Text="{StaticResource AppName}" 
					   TextWrapping="NoWrap" 
					   VerticalAlignment="Bottom" />
        </Grid>
    </Grid>
</prism:VisualStateAwarePage>

There’s no code in the code-behind for this page and then the template has also created that ViewModels folder and dropped a class called MainPageViewModel into it. That class looks like;

using Microsoft.Practices.Prism.StoreApps;
using Microsoft.Practices.Prism.StoreApps.Interfaces;

namespace PrismApp1.ViewModels
{
    public class MainPageViewModel : ViewModel
    {
        private INavigationService _navigationService;

        public MainPageViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;
        }
    }
}

so there’s really nothing to that at the moment.

From that starting point, creating the same “Hello World” style app that I had in my previous post is trivial. I can simply add some data property onto that ViewModel;

  public class MainPageViewModel : ViewModel
  {
    private INavigationService _navigationService;

    public MainPageViewModel(INavigationService navigationService)
    {
      _navigationService = navigationService;
    }

    public string ThePieceOfData
    {
      get
      {
        return (this._thePieceOfData);
      }
      set
      {
        base.SetProperty(ref this._thePieceOfData, value);
      }
    }
    string _thePieceOfData;
  }

and then I can bind to it from the UI;

    <Viewbox Grid.Row="1" MaxWidth="288">
      <TextBox Header="Enter Some Data"
               Text="{Binding ThePieceOfData,Mode=TwoWay}" />
    </Viewbox>

and if I wanted that piece of data to survive Windows’ suspend/terminate/re-launch cycle I can simply annotate it;

image

and that all works quite nicely and because this is a VisualStateAwarePage I can leave (or override) the base class implementation of DetermineVisualState which takes a width and height and returns a state name that can be used to change the UI into a particular visual state via the Visual State Manager. So, if I pop into Blend and define some really obvious UI changes for states called DefaultLayout, PortraitLayout, MinimalLayout as below;

image

then moving the UI into a portrait size drives that state transition as below;

image

In terms of the new item templates that David’s work installs – on the “Add Item” dialog in Visual Studio I get;

image

  • The Model item simply adds a class derived from ValidatableBindableBase which essentially overrides the SetProperty base class method to perform validation as property values change and collect them up in an Errors dictionary. The validation performed (all detailed in the docs) is based on the ValidationAttribute types from System.ComponentModel and the mechanism here to me feels very similar to that based around IDataErrorInfo/INotifyDataErrorInfo which I think came into Silverlight at version 4.
  • The Page View item adds another page to the project in the same way as the initial page is added to the project.
  • The View Model item adds another view model to the project in the same way as the initial view model is added to the project.
  • The Pub Sub Event item adds a class derived from Prism’s PubSubEvent<object> class for loosely coupled eventing – this is kind of a topic in its own right and I talked a bit about it here and the official docs on it are here.
  • The UserControl View item – I’m not so sure about. I couldn’t see a difference here between this item and a standard UserControl item template so I’d have to come back to this one.

I think these templates are a great helper for someone wanting to just get started with Windows Store apps – it’s clear where responsibility lies and there’s not tonnes of complex code in the projects but the framework has a tonne of flexibility for you to start to take control over how things are being done and altering some of the conventions as/when you feel comfortable with doing that.

For me, I’m going to have a think around whether I’d use these templates for demos in the future rather than just starting with Visual Studio’s blank projects – it feels like it would make life easier.