Skip to content

Part 1: Create Solution

steve600 edited this page Sep 26, 2015 · 13 revisions

Prism is a framework for building loosely coupled, maintainable and testable XAML applications in WPF. Prism provides an implementation of a collection of design patterns that are helpful in writing well structured and maintainable XAML applications, including MVVM, dependency injection, commands, EventAggregator, and others. Prism 6 is fully open source and the GitHub-Repository can be found here: https://github.com/PrismLibrary/Prism. MahApps.Metro is a toolkit for creating metro-style WPF applications. It contains a lot of styles and templates for all common controls (like Button, Checkbox, Tabcontrol, ...). It's also full open source and the repository can be found here: https://github.com/MahApps/MahApps.Metro

The sample shows the combination of these two great libraries. In the first step we will create a basic Prism application and in the second step we will integrate the MahApps.Metro styles.

Create basic Prism application

To create a Prism application the following tasks has to be performed:

  1. Create a solution with a shell project. In this task, you create the initial Visual Studio solution and add a WPF Application project that is the basis of solutions built using Prism Library. This project is known as the shell project.
  2. Set up the shell window. In this task, you set up a window, the shell window, to host different user interface (UI) components in a decoupled way. The components normally came from the different modules that we will create later.
  3. Set up the application's bootstrapper. In this task, you set up code that initializes the application. This is the main entry point for a PRISM based application

So let's start with the creation of the solution:

First, a standard WPF Application via Visual Studio is created. This looks as follows:

Standard WPF-Application with Visual Studio

In Prism applications the startup project or main project (the executable file) is often referred as Shell. The Shell project is the host application in which the individual modules are loaded. This Project defines the main Window of the application. This so named shell window is the top-level window of the application. This window is a place to host different UI components that exposes a way for itself to be dynamically populated by others (Prism-Modules), and it may also contain common UI elements, such as menus and toolbars. The shell window sets the overall appearance of the application.

The main logic of the application is then outsourced to the individual modules. Modules are self-contained functional blocks that implement specific functions (for example the user Management or profile management, etc.). The several modules contain the required views, data objects and services, etc. to meet to the designated tasks. A typical PRISM application consists normally of several modules, which then contain the business logic. The Shell project itself contains no specific business logic. Furthermore, the shell provides one or more regions which will be used by the modules for displaying the views. More on this later. One of the first steps is to reorganize the Project structure. Rename the created poject to "Projectname.Name" and move it to the newly create solution Folder "Shell" (this is not a must - I think it's tidier). After that the project structure looks like this:

Project-Structure

After that the necessary project references can be added. For this sample application, the following DLLs are required (all available via NuGet)

  • Prism.dll (via NuGet)
  • Prism.Wpf.dll (via NuGet)
  • Prism.Unity.Wpf.dll (via NuGet)
  • Microsoft.Practices.ServiceLocation.dll (via NuGet)
  • Microsoft.Practices.Unity.dll (via NuGet)

Initialization of a Prism-Application

The bootstrapper is a class that is responsible for the initialization of an application built using the Prism Library. The Prism-Library includes default abstract Bootstrapper base classes that can be specialized for use with any DI-container. Many of the methods on the bootstrapper classes are virtual methods so you can override these methods as appropriate in your own custom bootstrapper implementation. These are the basic stages of the bootstrapping process (picture is taken from here: https://msdn.microsoft.com/en-us/library/gg430868(v=pandp.40).aspx):

Basic Bootstrapping-Process

For this example Unity is used as DependencyInjection container and therefore the UnityBootstrapper base class is used for the Bootstrapper. However Prism supports some other DI-Containers and also provides base classes for the following DI-Containers.

To create a bootstrapper based on Unity proceed as follows:

  1. Create a new class Bootstrapper in the Shell-Project
  2. Add the following using-Statements
using Prism.Unity;
using Microsoft.Practices.Unity;
  1. Change the signature of the class as follows
public class Bootstrapper : UnityBootstrapper
{
}
  1. Override the CreateShell method (within this method the main window of the application is created):
protected override DependencyObject CreateShell()
{
    return Container.Resolve<Window>();
}
  1. Override InitializeShell method:
protected override void InitializeShell()
{
    base.InitializeShell();

    Application.Current.MainWindow = (Window)this.Shell;
    Application.Current.MainWindow.Show();
}
  1. Now create an instance of the Bootstrapper. Override the OnStartup method within the App.xaml.cs file:
protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    Bootstrapper bootstrapper = new Bootstrapper();
    bootstrapper.Run();
}
  1. Remove the StartupUri attribute from the App.xaml file. Since we will manually create the main window of the application within the bootstrapper this attribute is not longer needed. After that App.xaml looks like this:
<Application x:Class="PrismMahAppsSample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:PrismMahAppsSample">
    <Application.Resources>
         
    </Application.Resources>
</Application>

These are the basic steps for creating a Prism application. Now you should be able to compile and run the application with the default style. The main window should look like this:

MainWindow with default style

Use MahApps.Metro Style

To use MahApps.Metro we have to install the necessary packages. This can easily be be done with the NuGet package manager. You can mark the "include prerelease" checkbox in order to get the most current version of MahApps.Metro:

NuGet package manager MahApps.Metro

After installing MahApps.Metro change the MainWindow.xaml as follows:

  • add the following namespace: xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
  • change <Window ... tag to <metro:MetroWindow ...

Now the MainWindow.xaml should look like this:

<metro:MetroWindow x:Class="PrismMahAppsSample.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PrismMahAppsSample"
        xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
        GlowBrush="{DynamicResource AccentColorBrush}"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        
    </Grid>
</metro:MetroWindow>

Now change the base class of the MainWindow as follows:

// using statements...
using MahApps.Metro.Controls

public partial class MainWindow : MetroWindow
{
  // ...
}

All of MahApp.Metro's resources are contained within separate resource dictionaries. In order for most of the controls to adopt the MahApps.Metro theme, you will need to add the following ResourceDictionaries to your App.xaml:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
      <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>

Now the MainWindow should have the Metro-Styling:

Metro-Window