Using Page class with WPF (PRISM)

Topics: Prism v2 - WPF 3.5
Apr 14, 2009 at 9:06 AM
Hi ,

    I am trying to writing a PRISM application that will use a Page class instead of a Window class. Do we have any sample to demonstrate this.
I made a few changes after reading the blog post http://www.mokosh.co.uk/post/Prism-and-WPF-Browser-Application-(Xbap).aspx but still
when I try to mark a region within my page as a PRISM Region (Name="MainRegion") I get an exception as below.

Cannot create instance of 'Menu' defined in assembly 'NavigationApplication, Version=1.0.3391.18580, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation.  Error in markup file 'Menu.xaml' Line 1 Position 7.

In the above exception, Menu is the class derived from Page class.

Any help?

Thanks,
Ranjith
Apr 15, 2009 at 6:39 PM

Hi Ranjith,

 

I see that you are using Prism v2 (because of the tag you used in the post) and Mokosh's post  targets Prism v1 (because he uses some v1 classes IModuleEnumerator, StaticModuleEnumerator). You might take a look at my post Migrating Composite Application Guidance (Prism-v2) to XBAP that uses this same approach to migrate the HelloWorld Quickstart in Prism v2.

 

I followed Mokosh's steps on the HelloWorld quickstart application but couldn't reproduce the same exception you are receiving. Instead I get the following error:

"An exception of type 'System.NullReferenceException' occurred in Microsoft.Practices.ServiceLocation.dll but was not handled in user code" in the CreateRegion method of the RegionManager class.

 

To solve this issue I needed to make some changes to Mokosh's solution:

1.  Replace GetModuleEnumerator method in Mokosh's Bootstrapper with the following one:
protected override IModuleCatalog GetModuleCatalog()

{

ModuleCatalog catalog = new ModuleCatalog()

.AddModule(typeof(HelloWorldModule.HelloWorldModule));

return catalog;

}

2.       Page constructor should first execute the bootstrapper, then Initialize the components (this way the RegionManager can be located)

public Shell()

{

    Bootstrapper bootStrapper = new Bootstrapper();

    bootStrapper.ShellPage = this;

    bootStrapper.Run();

 

    InitializeComponent();           

}

 

There are also some things that should be done and the post does not say explicitly:

·         StartupUri tag should be added in app.xaml. For example: <Application StartupUri="shell.xaml">

·         OnStartup method from App class should be deleted

·         You should replace Window by Page in Shell class (both in xaml and cs). For example: <Page ......   and  public partial class Shell : Page

 

Please let me know if this helps you solve your issue. If not please tell me what changes have you done to make Mokosh's solution run in Prism v2.

 

Matias Bonaventura

http://blogs.southworks.net/matiasb

Jun 11, 2009 at 11:00 PM

Hi,

I was trying to add navigation to the Erwin "outlook style" application. Everything went fine with the above guidelines, except that the RegionManager is always empty, thus leading to not having the view rendered. Everything compile fine.

The problem seems to be in CreateShell method, which should be changed only to return the ShellPage property:

protected override DependencyObject CreateShell()
{
   var shell = Container.Resolve<Shell>();
   var model = Container.Resolve<IApplicationModel>();
   shell.DataContext = model;
   shell.Show();
   return shell;
}
should be changed to:
    protected override DependencyObject CreateShell()
    {
        return ShellPage;
    }

That's means that the RegionManager is not resolved via the Container? How shall be added the Model in that case?

Thanks,
Emanuel Pasat

Jun 12, 2009 at 8:51 PM

Hi Emanuel,

 

If I understood your problem correctly, you followed the steps for Migrating Composite Application Guidance (Prism-v2) to XBAP in Erwin's outlook app and views are not showing.

I followed those steps and was able to reproduce the situation you mention by changing the CreateShell method with the code you posted.

 

In this case, views are not showing because the ApplicationModel is not being set as the dataContext for the Shell.

 

Workaround

Modify the CreateShell method in the bootstrapper as follows:

protected override System.Windows.DependencyObject CreateShell()

{

    //var shell = Container.Resolve<Shell>();

    var model = Container.Resolve<IApplicationModel>();

    ((Shell)ShellPage).DataContext = model;

    //shell.Show();

    return ShellPage;

}

 

Hope it helps!

 

Matias Bonaventura

http://blogs.southworks.net/matiasb