WPF Application Using Prism

Before reading this article, I will recommend that you read and understand the  below concepts. If you know this information already that is enough to understand this article.
  • WPF
  • MVVM
  • Unity Framework 

Introduction

 
Prism is a framework to build composite applications using WPF + MVVM. When we develop composite applications, they should have:
  • Ability to extend
  • Flexibility
  • Ability to reuse modules which are developed
  • Top quality
  • Ability to test modules independently
Prism framework is strongly recommended to achieve the above-mentioned abilities.
 
We will develop a simple wpf application using PRISM.
 
Below is the design which we are going to implement.
WPF Application Using Prism
 
Here we can see 3 main components:
  • Shell: This is the one, which will act like a showcase to all modules. All modules can be loaded here.
  • BootStrapper : This is the one which connects the modules to Shell.
  • Modules: Modules are those, which can be developed independently. Using MVVM design pattern to build these modules is recommended. 
Now we will start implementing.
 
Create a solution with WPF application project.
 
Prism framework can be installed using nuget command: nuget command: install-package Prism.UnityExtensions -v 4.0.0.0
 
In this delete MainWindow.xaml
 
In App.xaml remove startupuri
 
In App.xaml.cs add the below code, to run the application:
  1. using System.Windows;  
  2.   
  3. namespace Prism.Sample.Demo  
  4. {  
  5.     /// <summary>  
  6.     /// Interaction logic for App.xaml  
  7.     /// </summary>  
  8.     public partial class App : Application  
  9.     {  
  10.         protected override void OnStartup(StartupEventArgs e)  
  11.         {  
  12.             base.OnStartup(e);  
  13.             BootStrapper bootstrapper = new BootStrapper();  
  14.             bootstrapper.Run();  
  15.         }  
  16.     }  
  17. }  
Add a Window with name “PrismShell” 
 
Add the below code in PrismShell.Xaml.cs, in the below code we can see that we added dockpanel and split as 4 regions. FYI we can split any number of regions based on our requirement. For now I will explain with 4 regions called:
  • Ribbon Region
  • Left Region
  • Main Region
  • Bottom Region
  1. <Window x:Class="Prism.Sample.Demo.PrismShell"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  6.         xmlns:prism="http://www.codeplex.com/prism" WindowState="Maximized"  
  7.         mc:Ignorable="d" Title="ShellApp" Height="900" Width="1200">  
  8.     <Grid x:Name="LayoutRoot">  
  9.         <DockPanel LastChildFill="True" HorizontalAlignment="Stretch"  Name="dockPanel" VerticalAlignment="Stretch">  
  10.             <Border BorderBrush="Silver" BorderThickness="1" DockPanel.Dock="Top" >  
  11.                 <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Height="100" HorizontalAlignment="Center" VerticalAlignment="Center">  
  12.                     <ContentControl BorderBrush="Silver" BorderThickness="1" prism:RegionManager.RegionName="RibbonRegion"></ContentControl>  
  13.                 </StackPanel>  
  14.             </Border>  
  15.             <Border BorderBrush="Silver" BorderThickness="1"  DockPanel.Dock="Bottom" >  
  16.                 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" DockPanel.Dock="Bottom" Height="100">  
  17.                     <ContentControl prism:RegionManager.RegionName="BottomRegion"></ContentControl>  
  18.                 </StackPanel>  
  19.             </Border>  
  20.   
  21.             <Border BorderBrush="Silver" BorderThickness="1"  DockPanel.Dock="Left" >  
  22.                 <ScrollViewer>  
  23.                     <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Vertical" DockPanel.Dock="Left" Width="200">  
  24.                         <ContentControl prism:RegionManager.RegionName="LeftRegion"></ContentControl>  
  25.                     </StackPanel>  
  26.                 </ScrollViewer>  
  27.             </Border>  
  28.             <Border BorderBrush="Silver" BorderThickness="1" >  
  29.                 <ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch">  
  30.                     <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">  
  31.                         <ContentControl  prism:RegionManager.RegionName="MainRegion" HorizontalAlignment="Stretch"  
  32.                               VerticalAlignment="Stretch"></ContentControl>  
  33.                     </StackPanel>  
  34.                 </ScrollViewer>  
  35.             </Border>  
  36.         </DockPanel>  
  37.     </Grid>  
  38. </Window>  
Create BootStrapper class and the below code in that class. In the below code we can see that we have used unity framework to resolve dependency issues and we have overridden 2 methods.
  • InitializeModules : To Load PrismShell and display.
  • ConfigureModuleCatalog: We will load modules which we want to display through PrismShell
  1. using Microsoft.Practices.Prism.Modularity;  
  2. using Microsoft.Practices.Prism.UnityExtensions;  
  3. using System.Windows;  
  4.   
  5. namespace Prism.Sample.Demo  
  6. {  
  7.     public class BootStrapper : UnityBootstrapper  
  8.     {  
  9.         protected override DependencyObject CreateShell()  
  10.         {  
  11.             return Container.TryResolve<PrismShell>();  
  12.         }  
  13.   
  14.         protected override void InitializeModules()  
  15.         {  
  16.             base.InitializeModules();  
  17.             Application.Current.MainWindow = (PrismShell)Shell;  
  18.             Application.Current.MainWindow.Show();  
  19.         }  
  20.         protected override void ConfigureModuleCatalog()  
  21.         {  
  22.             base.ConfigureModuleCatalog();  
  23.             ModuleCatalog moduleCatalog = (ModuleCatalog)ModuleCatalog;  
  24.               
  25.         }  
  26.     }  
  27. }  
Now we will create Module with Name ModuleA 
 
Create Project of type ClassLibrary with Name Prism.Sample.ModuleA
 
Add ViewModel Folder, inside that create AViewModel and the below code:
  1. using System.ComponentModel;  
  2.   
  3. namespace Prism.Sample.ModuleA.ViewModel  
  4. {  
  5.     public class AViewModel : INotifyPropertyChanged  
  6.     {  
  7.         public AViewModel()  
  8.         {  
  9.             ModuleAContent = "This is Ribbon Region module(ModuleA loaded here), Basically we can use it to display menus";  
  10.         }  
  11.         public event PropertyChangedEventHandler PropertyChanged;  
  12.         public void OnPropertyChanged(string propertyName)  
  13.         {  
  14.             PropertyChanged?.Invoke(thisnew PropertyChangedEventArgs(propertyName));  
  15.         }  
  16.   
  17.         private string _moduleAContent;  
  18.         public string ModuleAContent  
  19.         {  
  20.             get => _moduleAContent;  
  21.             set  
  22.             {  
  23.                 _moduleAContent = value;  
  24.                 OnPropertyChanged(nameof(ModuleAContent));  
  25.             }  
  26.         }  
  27.     }  
  28. }  
Add View folder, inside that create UserControl with the name Aview and add the below code:
  1. <UserControl x:Class="Prism.Sample.ModuleA.View.AView"  
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
  5.              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  6.              xmlns:viewModel="clr-namespace:Prism.Sample.ModuleA.ViewModel"  
  7.              mc:Ignorable="d" Height="100" Width="600">  
  8.     <UserControl.Resources>  
  9.         <viewModel:AViewModel x:Key="vm"/>  
  10.     </UserControl.Resources>  
  11.     <UserControl.DataContext>  
  12.         <Binding Source="{StaticResource vm}"/>  
  13.     </UserControl.DataContext>  
  14.     <Grid>  
  15.         <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"   
  16.                Text="{Binding ModuleAContent}" FontWeight="Bold" TextWrapping="Wrap"  
  17.                Height="60" Width="Auto" FontSize="20" Foreground="Orange" />  
  18.     </Grid>  
  19. </UserControl>  
In the above code we can see that we used MVVM design pattern and Bounded ModuleAContent Variable.
 
Install Prism framework using nuget command: nuget command: install-package Prism.UnityExtensions -v 4.0.0.0 
 
Add AModule class and the below code. In the below code we inherited interface IModule and we have provided implementation for Initialize Method.
 
In Initialize Method we have registered, with Region name and AView, to indicate where Bootstrapper has to load this module in PrsimShell.
  1. using Microsoft.Practices.Prism.Modularity;  
  2. using Microsoft.Practices.Prism.Regions;  
  3. using Prism.Sample.ModuleA.View;  
  4.   
  5. namespace Prism.Sample.ModuleA  
  6. {  
  7.     public class AModule : IModule  
  8.     {  
  9.         private readonly IRegionViewRegistry _regionViewRegistry=null;  
  10.   
  11.         public AModule(IRegionViewRegistry regionViewRegistry)  
  12.         {  
  13.             _regionViewRegistry = regionViewRegistry;  
  14.         }  
  15.         public void Initialize()  
  16.         {  
  17.             _regionViewRegistry.RegisterViewWithRegion("RibbonRegion"typeof(AView));  
  18.         }  
  19.     }  
  20. }  
In BootStrapper.cs configure the developed module in ConfigureModuleCatalog like below.
  1. protected override void ConfigureModuleCatalog()  
  2.        {  
  3.            base.ConfigureModuleCatalog();  
  4.            ModuleCatalog moduleCatalog = (ModuleCatalog)ModuleCatalog;  
  5.            moduleCatalog.AddModule(typeof(AModule));  
  6.        }  
Similarly we need to add ModuleB, ModuleC, ModuleD. For your reference I have uploaded Solution Project. PFA solution for reference to implement ModuleB, ModuleC, Module D.
 
At the end BootStrapper looks like below:
  1. using Microsoft.Practices.Prism.Modularity;  
  2. using Microsoft.Practices.Prism.UnityExtensions;  
  3. using Prism.Sample.ModuleA;  
  4. using Prism.Sample.ModuleB;  
  5. using Prism.Sample.ModuleC;  
  6. using Prism.Sample.ModuleD;  
  7. using System.Windows;  
  8.   
  9. namespace Prism.Sample.Demo  
  10. {  
  11.     public class BootStrapper : UnityBootstrapper  
  12.     {  
  13.         protected override DependencyObject CreateShell()  
  14.         {  
  15.             return Container.TryResolve<PrismShell>();  
  16.         }  
  17.   
  18.         protected override void InitializeModules()  
  19.         {  
  20.             base.InitializeModules();  
  21.             Application.Current.MainWindow = (PrismShell)Shell;  
  22.             Application.Current.MainWindow.Show();  
  23.         }  
  24.         protected override void ConfigureModuleCatalog()  
  25.         {  
  26.             base.ConfigureModuleCatalog();  
  27.             ModuleCatalog moduleCatalog = (ModuleCatalog)ModuleCatalog;  
  28.             moduleCatalog.AddModule(typeof(AModule));  
  29.             moduleCatalog.AddModule(typeof(BModule));  
  30.             moduleCatalog.AddModule(typeof(CModule));  
  31.             moduleCatalog.AddModule(typeof(DModule));  
  32.         }  
  33.     }  
  34. }  
Below is the snap of the end result window.
 
WPF Application Using Prism
 

Summary

 
In this article we understood about developing Prism applications using Prism + WPF + MVVM.