Integrating Modules with Application in Prism aka CompositeWpf

走远了吗. 提交于 2019-12-12 08:16:55

问题


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?


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/1671526/integrating-modules-with-application-in-prism-aka-compositewpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!