views:

480

answers:

2

From MSDN:

It is likely that most of the views in your modules will not have to be displayed directly, but only after some action by the user. Depending on the style of application, you may want to use menus, toolbars, or other navigation strategies for your users to access views. In the initialization method of the module, you can also register with the application's navigation structure. In the event handlers of your navigation structure (that is, when a user clicks on a menu item), you might use View Injection techniques to add views to the appropriate regions.

I've a similar scenario, I'm adding Views to Regions in the Initialization method of Module using RegisterViewWithRegion. I'd love to display a View based user interaction with a Menu (which is a different module).

How do I achieve this behavior without breaking decoupled behavior of Modules in Prism?

Is it possible to Activate/Show a View which has been added to a Region, say by ModuleA from ModuleB?

A: 

RegisterViewWithRegion does not have an overload that accept View name as parameter. This could have eased integrating Modules. I've added a work item in Codeplex

Currently I'm adding reference to other Modules for View Injection and losing loosely coupled nature of Prism

Raj
This is not necessary. I'll post an alternative shortly.
Anderson Imes
+2  A: 

What I do is create a view registry in my Shell with the following interface (I'm simplifying here):

public interface IViewRegistry
{
     void RegisterView(string title, string key, Func<UIElement> viewCreationMethod);
     void OpenView(string key);
}

This is way oversimplifying, but hopefully this gives you a picture. Each module registers its views with the shell using this interface on initialization. In my shell, I create a ViewStore that stores these things.

public static class ViewStore
{
     public Dictionary<string, ViewEntry> Views { get; set; }
     static ViewStore()
     {
          Views = new Dictionary<string, ViewEntry>();
     }

     public void RegisterView(string name, string key, Func<UIElement> createMethod)
     {
         Views.Add(key, new ViewEntry() { Name = name, CreateMethod = createMethod });
     }
}

Then from my IViewRegistry implementation:

public class ViewRegistryService : IViewRegistry
{
     public void RegisterView(string title, string key, Func<UIElement> createMethod)
     {
          ViewStore.RegisterView(title, key, createMethod);
     }

     public void OpenView(string key)
     {
          //Check here with your region manager to see if
          //the view is already open, if not, inject it
          var view = _regionManager.Regions["MyRegion"].GetView(key);
          if(view != null)
          {
               view = ViewStore.Views[key]();
               _regionManager.Regions["MyRegion"].Add(view, key);
          }
          _regionManager.Regions["MyRegion"].Activate(view);
     }

     private IRegionManager _regionManager;
     public ViewRegistryService(IRegionManager rm)
     {
          _regionManager = rm;
     }
}

Now I have two things:

  1. A ViewStore I can use to create a menu in my shell.
  2. A way for modules to open views owned by other modules without coupling beyond simple ModuleDependencies (in reality, even the ModuleDependency is not necessary, but probably correct.

Obviously this way oversimplifies things. I have things that indicate whether or not a view should be a menu item. My app has several menus, etc, but this is the basics and should get you going.

Also, you should give Stackoverflow a little bit of a chance to get you an answer... you only gave us 3 hours before you gave up :)

Hope this helps.

Anderson Imes
Thanks for the inputs. Could you please have a look at http://stackoverflow.com/questions/1678423/what-is-the-best-method-to-load-views-dynamically-from-a-navigation-control-in-pr I did that post before seeing your reply here.
Raj
Hi could you give me a sample of RegisterView(), especially the Func<UIElement> part.
Raj
Here's a sample: http://dl.dropbox.com/u/376992/CAGMenus.zip
Anderson Imes