Tuesday, October 25, 2011

Setting up a Composite WPF Application Properly.

It's time to step back from working on bits and pieces of something large and remind myself how to create a MVVM project from scratch. There are probably templates available now but I'll start with an empty C# WPF project and call it MVVM for simplicity. Renamed MainWindow to Shell everywhere in the solution because Shell is the conventional name for a top-level window in the application built in the Composite Application Library.

Composite Application Library displays and hides controls through the use of Regions. Several controls can be displayed as regions, one of them is ItemsControl.

An attached property RegionManager.RegionName indicates which region is associated with the control. So, in the Shell.xaml I replaced the Grid element with the ItemsControl element:

<ItemsControl Name="MainRegion" cal:RegionManager.RegionName="MainRegion"/>

For the code to compile, the following line has to be added to the Window tag

xmlns:cal="http://www.codeplex.com/CompositeWPF"

and the Microsoft.Practices.Prism dll has to be referenced in the project which contains the definition of RegionManager.RegionName

The bootstrapper initializes the application build using the Composite Application Library. At this point the bootstrapper only returns the new instance of a Shell class. Added the Bootstrapper class to the solution:

class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return this.Container.Resolve();
}

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

App.Current.MainWindow = (Window)this.Shell;
App.Current.MainWindow.Show();
}

protected override void ConfigureModuleCatalog()
{
}
}

At this point, the reference to Microsoft.Practices.Prism.UnityExtensions is required (for UnityBootstrapper). And not to forget the

using Microsoft.Practices.Unity;

otherwise the container would not resolve! Basically, Container.Resolve constructs an instance of the concrete class, resolving any dependencies that it has.

Now the bootstrapper has to run when the application starts. To achieve this, the Startup event of the application is handled in the App.xaml.cs file.

public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
}

And since the instance of the Shell is manually created by the bootstrapper, the StartupUri attribute is not needed anymore in the App.xaml Application tag.

<Application x:Class="MVVM.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>

</Application.Resources>
</Application>

The application is fully functional now!

References:

WPF Hands-On Lab: Getting Started with the Composite Application Library

What does this mean in Prism/Unity: Container.Resolve()

UnityBootstrapper Class

Bootstrapper

by . Also posted on my website

No comments: