Category Archives: PRISM

Change the colour of the status bar on Android (in Xamarin Forms)

In your Android project, values folder styles.xml file you’ll find something like

<style name="MainTheme" parent="MainTheme.Base">
   <!-- -->
</style>

and/or

<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
   <!-- -->
</style>

Use the following element and attribute in the MainTheme.Base if that exists or the MainTheme (it will depend on the template you used at to whether one or both of these exist)

<!-- Top status bar area on Android -->
<item name="android:statusBarColor">#FF0C1436</item> 

You may wish to also change the colour of the bar background at the top of the NavigationPage (if you’re using the NavigationPage such as with Prism) by adding the following to the App.xaml

<Application.Resources>
  <ResourceDictionary>
    <Style TargetType="NavigationPage">
      <Setter Property="BarBackgroundColor" Value="Color.Red"/>
      <Setter Property="BarTextColor" Value="Color.White"/>
    </Style>
  </ResourceDictionary>
</Application.Resources>

in non-Prism you can change the Primary colour, for example again in App.xaml

<Application.Resources>
  <ResourceDictionary>
    <Color x:Key="Primary">#FF3399FF</Color>
  </ResourceDictionary>
</Application.Resources>

Creating a Prism.DryIoc.Forms application from scratch

I must have created my last Prism.DryIoc.Forms application using a project template but this time created a standard Xamarin.Forms application and then realised I wanted/meant to use DryIoc.

So here’s the steps to turn my “standard” Xamarin.Forms application into a Prism.DryIoc.Forms application.

  • Add the Prism.DryIoc.Forms nuget package to your application
  • Delete the MainPage.xaml files generated by Xamarin.Forms
  • Change the App.xaml to use PrismApplication i.e.
    <?xml version="1.0" encoding="utf-8" ?>
    <prism:PrismApplication 
       xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:prism="clr-namespace:Prism.DryIoc;assembly=Prism.DryIoc.Forms"
       x:Class="MyDemo.App">
        <Application.Resources>
    
        </Application.Resources>
    </prism:PrismApplication>
    
  • Change the App.xaml.cs to derive from PrismApplication, for example
    public partial class App : PrismApplication
    
  • Remove/replace the App constructor with the following
    public App() :
       this(null) { }
    
    public App(IPlatformInitializer initializer) :
       base(initializer) { }
    
  • Now override the OnInitialized method and put the IntitializeComponent call within this, i.e.
    protected override async void OnInitialized()
    {
       InitializeComponent();
    }
    
  • Add folders to the solution named ViewModels and Views
  • Within the Views folder add a MainPage.xaml Xamarin.Forms ContentPage (or page type as required)
  • To register our MainPage and the NavigationPage go back to the App.xaml.cs and add the following method
    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
       containerRegistry.RegisterForNavigation<NavigationPage>();
       containerRegistry.RegisterForNavigation<MainPage>();
    }
    
  • Finally, in the App.xaml.cs within the OnIntialized method we’ll navigate to the new page. As the NavigateAsync returns a Task, we can await it so we’ll add async to the OnInitialized method – here’s what that will look like
    protected override async void OnInitialized()
    {
       InitializeComponent();
    
       await NavigationService.NavigateAsync("NavigationPage/MainPage");
    }
    

Now place any further page’s within the Views folder and add to the RegisterTypes method (if required) and add any view models to the ViewModels folder deriving from BindableBase (if you want to use the Prism MVVM base class).

Adventures in UWP – Prism (more Unity than Prism)

Prism is a well used framework in WPF and it’s also available in UWP. So let’s try it out. We’re going to start by looking at switching the default generated (blank) UWP application into one which uses Prism or more specifically Unity and Prism’s navigation functionality.

  • Create a Blank UWP application
  • From Nuget install the package Prism.Unity (I’m using v6.3.0)
  • Edit App.xaml.cs and change the base class from Application to PrismUnityApplication (yes we’ll use Unity for this test), don’t forget to add using Prism.Unity.Windows;
  • Remove all generated code from App.xaml.cs except for the constructor
  • Open App.xaml and change it from using Application to PrismApplication, for example
    <windows:PrismUnityApplication
        x:Class="MathsTest.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:MathsTest"
        xmlns:windows="using:Prism.Unity.Windows"
        RequestedTheme="Light">
    
    </windows:PrismUnityApplication>
    
  • Add the following bare bones method (yes it’s not handling possible startup states etc. as I wanted to reduce this code to the minimum)
    protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
    {
       NavigationService.Navigate("Main", null);
       return Task.FromResult(true);
    }
    
  • By default the UWP project will have created a MainPage.xaml but Prism’s navigation code expects this to be in a Views folder, so create a Views folder in your solution and move MainPage.xaml into this Views folder.

    If you see an exception along the lines of “The page name does not have an associated type in namespace, Parameter name: pageToken” then you’ve probably not got a view with the correct name within the Views folder. Don’t forget to update the XAML and the xaml.cs files to include Views in the name space, i.e. TestApp.Views.MainPage

At this point we have UWP running from Prism.

View/ViewModel resolver

In my first post on using Prism and Xamarin Forms Prism and Xamarin Forms I stated that you needed to follow the convention of views being located in a .Views. namespace and view models being located in a .ViewModels. namespace.

In fact this is not quite true. What happens is, if the ViewModelLocator.AutowireViewModel in the view is set to true, only then does Prism attempt to wire up a view model to a view and in fact the first thing it does is to look at whether the programmer has actually registered a view to a view model factory method. Only if this returns null (i.e. no factory has been supplied for a view) does it attempt the convention based approach.

Registering your View/ViewModel mapping

We can see how to register our view models with the following code snippet (this should be in your App.cs)

protected override void ConfigureViewModelLocator()
{
   base.ConfigureViewModelLocator();

   ViewModelLocationProvider.Register("XamarinTest.Views.MainPage", () => new MainPageViewModel());
}

As you can see in the above code, you need to ensure the full namespace and type name for the view, and yes it’s a magic string which is not great.

Convention based approach

Okay, so assuming no view/view model mapping has been registered for the view, we’ll now look at the convention based approach used in prism. So by default the convention based approach expects the views to be in a Views namespace and the view models to be in a ViewModels namespace, but this can be changed to suit your needs.

For example, some prefer to keep views and view models for a specific set of functionality together within the same folder or namespace as it saves jumping around a project look for each part of the specific functionality. Or maybe you find other was to layout your view/view model files which you prefer. You can assign your on Func to the ViewModelLocationProvider’s static method SetDefaultViewTypeToViewModelTypeResolver to achieve you own view model mapping.

Let’s take a look

// override this method in your App.cs file 
protected override void ConfigureViewModelLocator()
{
   base.ConfigureViewModelLocator();

   ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(AlternateResolver);
}

Next let’s write a simple implementation of a resolver which looks for matching ViewModels by simply expecting them to be in the same namespace etc. as the view

// add this method to your App.cs
private static Type AlternateResolver(Type type)
{
   var viewName = type.FullName;
   if (String.IsNullOrEmpty(viewName))
      return null;

   var viewModel = viewName + "ViewModel";

   return Type.GetType(viewModel);
}

Note: I had intended to create an assembly lookup method that would search the assembly for matching types but limitation in what we get as part of the PCL and/or Xamarin appears to have scuppered that idea, so in the above code we simply append ViewModel to the view name. Obviously if you name your views with the View suffix, such as MainPageView, then this code is rather simplistic and will expect the view model to be named MainPageViewViewModel, I’ll leave it to the reader to amend the method as required.

Prism and Xamarin Forms

Here’s the steps for getting Prism and Xamarin Forms up and running together. For this I’m using Visual Studio 2015. Refer to a previous post on how to get a Xamarin Forms application up and running in Visual Studio 2015 if you need to.

Note: I’m using the Unity container hence I’ll be demonstrating the code using Prism.Unity.Forms, there is support for alternate IoC containers such as NInject, Mef and Autofac. Prism.Unity.Forms will automatically include Prism.Core and Prism.Forms.

  • Create a Cross-Platform, Blank App (Xamarin.Forms Portable)
  • Using NuGet, install Prism.Unity.Forms (at the time of writing – you’ll need to click on the Include prerelease option), I’ve installed v6.2.0-pe5
  • For each of the projects you’ve created you’ll now need to go to each References section and add the Prism.Unity.Forms package from NuGet
  • Prism has a convention based approach to loading view model’s, so let’s create the two folders, Views and ViewModels off of the Portable project – in fact it’s the namespace that matters, so the expectation is for views to be in the Views namespace and likewise the view models should be in the ViewModels namespace.
  • Now add a MainPage.xaml file to the Views folder, so in the Portable project right mouse click, select Add | New Item and then from Cross-Platform select Forms Xaml Page, I’ve named mine MainPage
  • In the MainPage.xaml file you’ll see the Label is bound to a MainText property, so let’s now create a MainPageViewModel.cs file in the ViewModels folder to act as our view model for this page (the default convention is for the view model for a view to be named after the view with the suffix ViewModel, i.e. MyView by default maps to MyViewModel).
  • To allow Prism to auto wire up view models we need to add the following to the XAML file (to the ContentPage)
    xmlns:mvvm="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
    mvvm:ViewModelLocator.AutowireViewModel="True"
    
  • Derive the view model from BindableBase and implement the following code to simply get things up and running
    public class MainPageViewModel : BindableBase
    {
       public string MainText { get; } = "Hello Prism World";
    }
    

    You’ll need to add using Prism.Mvvm; to resolve the BindableBase object.

  • Remove all the code from the App constructor as the MainPage will be supplied by Prism going forward.
  • Derive your App from PrismApplication instead of Application and implement the abstract methods as below
    public class App : PrismApplication
    {
       // add these methods
       protected override void OnInitialized()
       {
          NavigationService.NavigateAsync("MainPage");
       }
    
       protected override void RegisterTypes()
       {
          Container.RegisterTypeForNavigation<MainPage>();
       }
    }
    

    You’ll need to add using Prism.Unity; to resolve PrismApplication.

    OnInitialized will automatically navigate to the “MainPage” view, the magic string maps to the type name MainPage as I’m sure you can see. But in the RegisterTypeForNavigation we can change this string mapping if preferred.

Composing a Prism UI using regions

Monolithic application are (or should be) a thing of the past. We want to create applications which are composable from various parts, preferably with a loose coupling to allow them to be added to or reconfigured with minimal effort.

There are various composable libraries for WPF, for this post I’m going to concentrate on Prism. Prism uses regions to allow us to partition your application by creating areas within a view for each UI element. These areas are known as regions.

Assuming we have a minimal Prism application as per my post Initial steps to setup a Prism application, then let’s begin by creating a “MainRegion” a region/view which takes up the whole of the Shell window.

  • In the Shell.xaml, add the name space
    xmlns:cal="http://www.codeplex.com/prism"
    
  • Replace any content you have in the shell with the following
    <ItemsControl cal:RegionManager.RegionName="MainRegion" />
    

    here we’ve created an ItemsControl and given it a region name of “MainRegion”. An ItemsControl allows us to display multiple items, equally we could have used a ContentControl for a single item.

  • We’re going to create a new class library for our view(s), so add a class library project to your solution, mine’s named Module1
  • To keep our views together create a View folder within the project
  • Add a WPF UserControl (mine’s named MyView) to the View folder, mine has a TextBlock within it, thus
    <TextBlock Text="My View" />   
    

    just to give us something to see when the view is loaded.

  • Add a class. I’ve named it Module1Module and add the following code
    public class Module1Module : IModule
    {
       private readonly IRegionViewRegistry regionViewRegistry;
    
       public Module1Module(IRegionViewRegistry registry)
       {
          regionViewRegistry = registry;   
       }
    
       public void Initialize()
       {
          regionViewRegistry.RegisterViewWithRegion("MainRegion", 
                   typeof(Views.MyView));
       }
    }
    

    Here we’re setting up an IModule implementation which associates a view with a region name.

  • Reference the class library project in the shell project

Using Unity

  • Now with our Unity bootstrapper, we need to add the module to the module catalog, as per the following
    protected override void ConfigureModuleCatalog()
    {
       base.ConfigureModuleCatalog();
       ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
       moduleCatalog.AddModule(typeof(Module1.Module1Module));
    }
    

Using MEF

  • Now with our MEF bootstrapper, we need to add the module to the module catalog, as per the following
    protected override void ConfigureAggregateCatalog()
    {
       base.ConfigureAggregateCatalog();
       AggregateCatalog.Catalogs.Add(new AssemblyCatalog(GetType().Assembly));
       AggregateCatalog.Catalogs.Add(new AssemblyCatalog(
               typeof(Module1.Module1Module).Assembly));
    }
    
  • In our view, we need to mark the class with the ExportAttribute, thus
    [Export]
    public partial class MyView : UserControl
    {
       public MyView()
       {
          InitializeComponent();
       }
    }
    
  • Now we need to change the module code to the following
    [ModuleExport(typeof(Module1Module), 
       InitializationMode=InitializationMode.WhenAvailable)]
    public class Module1Module : IModule
    {
       private readonly IRegionViewRegistry regionViewRegistry;
    
       [ImportingConstructor]
       public Module1Module(IRegionViewRegistry registry)
       {
          regionViewRegistry = registry;
       }
    
       public void Initialize()
       {
          regionViewRegistry.RegisterViewWithRegion("MainRegion", 
               typeof(Views.MyView));
       }
    }
    

Obviously in this sample we created a single region and embedded a single view, but we can easily create multiple named regions to truly “compose” our application from multiple views.

Initial steps to setup a Prism application

I haven’t touched Prism in a while as I’ve been using Caliburn.Micro a lot, but decided to reaquaint myself with PRISM recently, so this give me the oppurtunity to create some posts on the basics of PRISM.

Creating the bare bones application

  • Create a new WPF Application
  • Open App.xaml and delete the StartupUri=”MainWindow.xaml” code as we’ll be creating the “shell” window in code
  • Either delete MainWindlow.xaml and then add a new WPF Window or rename the MainWindow to Shell (by convention the main window of the application is named Shell)
  • Add the following code to the XAML, inside the Shell’s grid (just so we have something to view when the application start’s up)
    <TextBlock Text="Shell Application" />
    
  • Using NuGet Install the PRISM package (mine’s version 5.0.0)
  • Create a new class named Bootstrapper, the contents depend upon the IoC container we want to use (discussed below). For now, change the Bootstrapper code to look like this, which is shared by both standard Prism IoC containers.
    public class Bootstrapper
    {
       protected override void InitializeShell()
       {
          base.InitializeShell();
          App.Current.MainWindow = (Window)Shell;
          App.Current.MainWindow.Show();
       }
    
       protected override DependencyObject CreateShell()
       {
          return null;
       }
    }
    

    Obviously we’ve not got a base class at this point so this will not compile, but these two methods are overidden for both Unity and Mef implementation.

  • Finally, for the shared code, open App.xaml.cs and add the following
    protected override void OnStartup(StartupEventArgs e)
    {
       base.OnStartup(e);
    
       Bootstrapper bootstrapper = new Bootstrapper();
       bootstrapper.Run();
    }
    

Okay, at this point we’ve got the basics in place but we need to create the bootstrapper which is used to create the shell via the IoC container, whether that be Unity, Mef or any other container setup to work with PRISM.

Using Unity

The Unity container requires the least work to get up and running.

  • Using NuGet add the package Prism.UnityExtensions (mine’s version 5.0.1) to the solution
  • Change the Bootstrapper code to derive from UnityBoostrapper
  • Change the CreateShell code to look like the following
    protected override DependencyObject CreateShell()
    {
       return Container.TryResolve<Shell>();
    }
    

Using MEF

Using MEF requires a little more work than Unity.

  • Using NuGet add the package Prism.MEFExtensions (mine’s version 5.0.0) to the solution
  • Change the Bootstrapper code to derive from MefBoostrapper
  • Add a reference to System.ComponentModel.Composition
  • Change the CreateShell code to look like the following
    protected override DependencyObject CreateShell()
    {
       return Container.GetExportedValue<Shell>();
    }
    
  • We now need to add our assembly to the MEF catalog, so add the following to the Bootstrapper class
    protected override void ConfigureAggregateCatalog()
    {
       base.ConfigureAggregateCatalog();
       AggregateCatalog.Catalogs.Add(new AssemblyCatalog(GetType().Assembly));
    }
    
  • Finally, we need to mark to Shell with the ExportAttribute so that MEF can locate it via Container.GetExportedValue. So open Shell.xaml.cs and place Export able the class thus
    [Export]
    public partial class Shell : Window
    {
        // code
    }