-
Migrating Composite Application Guidance (Prism-v2) to XBAP
2 CommentsI’ve seen that there are quite a few questions on how to use Composite Application Guidance for WPF and Silverlight (a.k.a Prism) with XBAP applications on the discussion list, so I’ll try show you in this post how to migrate the HelloWorld demo (included with CAL) to XBAP. If you are in a hurry, you can skip directly to the Solution.
Problem
The main issue is that XBAP applications rely on WPF framework to create the NavigationWindows that will be holding XBAP pages and CAL needs to create the main window on the Bootstrapper (creating instances of NavigationWindows is not allowed in PartialTrust applications).
The first thing that you will do to convert your WPF application into an XBAP application is changing <Window> for <Page> in you XAMLs. In most scenarios that is practically all you have to do because WPF framework is intelligent enough to create the right environment for the application: If you are using Windows, it just creates a new instance of a window and calls it’s Show method (like you usually do in the CAL’s Bootstrapper). But if you are using Pages, it needs to host pages in NavigationWindows or the Browser.
But, if you are using CAL after changing your Windows for Pages, you will end up commenting the call to the Show Method (pages don’t have a Show method) and setting the starupURI of the application. And that’ were the root of the problem lies: WPF creates an instance of a Page and you are creating another instance in the Bootstrapper. That will mess up things and you will end up loosing references to the CAL’s regions and contentControls.
Solution
Based on Mokosh’s Prism and WPF Browser Application (Xbap) post that shows a good way run Prism v1 solution as XBAPs, let’s migrate a Prism v2 solution to run as an XBAP application is as follows:
We will start with the HelloWorldDemo.Desktop Quickstart included in Prism v2.
- Set the shell as the startup page of the application. To do that, open the App.xml file and add StartupUri=”Shell.xaml” to the <Application> element.
<Application x:Class=“HelloWorld.App”
xmlns=“http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=“http://schemas.microsoft.com/winfx/2006/xaml”
StartupUri=“Shell.xaml“>
<Application.Resources>
</Application.Resources>
</Application> - In the App.xaml code behind (App.xaml.cs) remove the OnStartup method. We will add the BootStrapper initialization afterwards.
- In the Shell.xaml file change the <Window> element for a <Page> element. You should end up with the Shell.xaml code as follows:
<Page x:Class=“HelloWorld.Shell”
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=“Hello World” Height=“300” Width=“300“>
<ItemsControlName=“MainRegion” />
</Page> - In the Shell.cs make Shell inherit from Page instead of Window. Ej: public partial class Shell : Page
- To avoid creating a new instance of the shell, get the one created during the Application startup. A good place to do that is the Shell constructor.
- Now we will need to add a property to the Bootstrapper class to have a reference to the Shell and then return it in the CreateShell method. So the complete Bootstrapper code should be:
- Press F5 and Enjoy!
public Shell() { Bootstrapper bootStrapper = new Bootstrapper(); bootStrapper.ShellPage = this; bootStrapper.Run(); InitializeComponent(); }
class Bootstrapper : UnityBootstrapper { private DependencyObject shellPage; public DependencyObject ShellPage { get { return shellPage; } set { shellPage = value; } } protected override DependencyObject CreateShell() { return ShellPage; } protected override IModuleCatalog GetModuleCatalog() { ModuleCatalog catalog = new ModuleCatalog() .AddModule(typeof(HelloWorldModule.HelloWorldModule)); return catalog; } }
Further improvements:
- You can host the XBAP application directly in the browser if you follow these 6 steps proposed by Charles: Converting EXE Projects to XBAPs
- You can take a look at Damian‘s migration of the Reference Implementation and download the XBAP RI: Composite Application Guidance for WPF & Silverlight (Prism v2) Reference Implementation migrated to XBap
Technorati Tags: Patterns and Practices,Composite Application Guidance,WPF,XBAP,Prism,CAL
- Set the shell as the startup page of the application. To do that, open the App.xml file and add StartupUri=”Shell.xaml” to the <Application> element.
-
2 Comments:
Leave a comment
Your email address will not be published.
Damian Schenkelman’s Blog » Blog Archive » Composite Application Guidance for WPF & Silverlight (Prism v2) Reference Implementation migrated to XBap said on March 13, 2009:
[...] While doing this we found a couple of really interesting things that are required to migrate an existing Composite WPF application to XBAP. You can read about most of them in this blog post. [...]
Tailton said on March 7, 2010:
Good post.
I liked very much.