With the release of Caliburn V1 rapidly approaching, I’ve decided to take the time to demonstrate a really great feature in Caliburn V1 – Prism Integration.
In case you are not familiar with Caliburn or Prism I’ll start out with some links.
Check out Prism (also known as Composite WPF or Composite Application Library) – here
Check out Caliburn – here
Let’s begin with some project setup concerns, there are certain ways I like to setup and organize my folder structure which are helpful when you are trying to things like multi-targeting
Start with your typical SVN style setup with a src, lib and tools folder, but I’m going to add a Desktop folder under source where all of my Desktop (WPF) projects go. Later I will add a Silverlight folder so I can share a lot of code between the WPF and Silverlight versions of the application.
Take a trip out to codeplex and grab the latest binaries from the Caliburn site and put them in your lib folder. Great thing about Caliburn is that Rob’s included the latest binaries of all your favorite IoC containers and Prism so its a nice one stop shop to get you up and running quickly.
Enough with the boring stuff show me some code already!
So first things first, how do you bootstrap this thing? Well good thing for you Caliburn makes using Prism easier than using it by itself.
Open up visual studio and add a new WPF Application and name it [YourProjectName].Shell.
Add references to:
- Caliburn.Core
- Caliburn.PresentationFramework
- Caliburn.Prism
- Microsoft.Practices.Composite
- Microsoft.Practices.Composite.Presentation
- Microsoft.Practices.ServiceLocation;
Open up your App.xaml.cs file and add the following using statements to the top:
using Caliburn.Core;Caliburn is typically configured in the App constructor like this:
using Caliburn.PresentationFramework;
using Caliburn.Prism;
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
CaliburnFramework
.ConfigureCore()
.AfterStart(() =>
{
var binder = (DefaultBinder)ServiceLocator.Current.GetInstance<IBinder>();
binder.EnableMessageConventions();
binder.EnableBindingConventions();
})
.WithPresentationFramework()
.WithCompositeApplicationLibrary(CreateShell)
.WithModuleCatalog(new ModuleCatalog().AddModule(typeof(ContactsModule)))
.Start();
}
private DependencyObject CreateShell()
{
ServiceLocator.Current.GetInstance<IWindowManager>()
.Show(ServiceLocator.Current.GetInstance<ShellPresenter>(), null, ExecuteShutdownModel);
return MainWindow;
}
private void ExecuteShutdownModel(ISubordinate subordinate, Action completed)
{
completed();
}
}
Now you are probably asking yourself what’s up with CreateShell(), what in the world is a ModuleCatalog and where did this ContactsModule come from? Don’t panic… we’ll get there.
Let’s start with CreateShell(). Prism is expecting a shell view which will basically main window where you will “park” all of your other views into Regions on the shell. This is all very interesting stuff but first you need to add a few folders to your project so that Caliburn knows how to find everything. Add a Views and a Presenters folder to Shell project.
Just to get us started we’re not going to get fancy with the ShellView right now. Here a quick snippet using tab control as our region.
<Window x:Class="CaliBrism.Shell.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.codeplex.com/CompositeWPF"
Title="Calibrism" Height="300" Width="300">
<Grid>
<ItemsControl
x:Name="MainControl"
cal:RegionManager.RegionName="MainRegion"
/>
</Grid>
</Window>
Don’t worry about the code-behind right now we won’t need to do anything in there right now. Here’s the ShellPresenter:
namespace CaliBrism.Shell.Presenters
{
public class ShellPresenter : MultiPresenter, IShellPresenter { }
public interface IShellPresenter
{
}
}
Ok so now since we’re using a great composite framework in Prism. We need to add some modules. Start by adding a class library. I like to use a naming convention like [YourProject].Modules.[NameOfModule] so Calibrism.Modules.Contacts is born.
First thing you need to add references to Caliburn and Prism just like you did for the shell project and add a class ContactsModule to initialize your module.
The purpose of the Module class to register any services you may need to register and tell you module’s views which regions they need to park in.
namespace Calibrism.Modules.Contacts
{
public class ContactsModule : IModule
{
private readonly IServiceLocator _serviceLocator;
private readonly IRegionManager _regionManager;
private readonly IBinder _binder;
private readonly IViewStrategy _viewStrategy;
public ContactsModule(IServiceLocator serviceLocator,
IRegionManager regionManager,
IBinder binder,
IViewStrategy viewStrategy
)
{
_serviceLocator = serviceLocator;
_regionManager = regionManager;
_binder = binder;
_viewStrategy = viewStrategy;
}
public void Initialize()
{
var model = _serviceLocator.GetInstance<IContactsListPresenter>();
var view = _viewStrategy.GetView(model, null, null);
_binder.Bind(model, view, null);
_regionManager.RegisterViewWithRegion("MainRegion", () => view);
}
}
}
So now you may be asking what’s IRegionManager, IBinder, IViewStrategy, and IServiceLocator? Ugh so many many things. Well don’t worry for the most part you will only have to deal with this stuff in the ContactsModule after this Caliburn will take over alot of this complicated stuff. So here’s the quick and dirty on all these things
IRegionManager – Don’t let the name fool you. This guy manages Regions (gasp) basically your telling Prism “Hey put this view in the Main Region”
IViewStrategy – This one a little more tricky. This is the way Caliburn figures out what view belongs to a presenter you can read more about that here
IBinder – this guy binds your view to your presenter you can read more here
Ok so now you need to add the contacts list view… you know the drill not much different that the ShellView.
Xaml:
<UserControl x:Class="Calibrism.Modules.Contacts.Views.ContactsListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid Background="AliceBlue">
</Grid>
</UserControl>
Code:
namespace Calibrism.Modules.Contacts.Presenters
{
[Singleton(typeof(IContactsListPresenter))]
public class ContactsListPresenter : Presenter, IContactsListPresenter
{
public ContactsListPresenter()
{
}
}
}
namespace Calibrism.Modules.Contacts.Presenters.Interfaces
{
public interface IContactsListPresenter: IPresenter
{
}
}
Right now we just have a blank canvas. Next time we’ll add the fun stuff…
Stay tuned