views:

1206

answers:

1

Does anyone know of WPF code examples using Prism in which modules each register themselves as a menuitem in a menu within another module?

(I've currently got an application which tries to do this with the EventAggregator, so one module listens for published events from other modules which need to have their title in the menu as a menu item, but I'm getting problems with the order of loading and threading etc. I want to find an example that uses classic Prism structure to do this.)

I'm thinking in terms of this:

Shell.xaml:

<DockPanel>
    <TextBlock Text="Menu:" DockPanel.Dock="Top"/>
    <Menu 
        Name="MenuRegion" 
        cal:RegionManager.RegionName="MenuRegion" 
        DockPanel.Dock="Top"/>
</DockPanel>

Contracts View:

<UserControl x:Class="ContractModule.Views.AllContracts"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <MenuItem Header="Contracts">
    </MenuItem>
</UserControl>

Customers View:

<UserControl x:Class="CustomerModule.Views.CustomerView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <MenuItem Header="Customers">
    </MenuItem>
</UserControl>

But up to know I've done non-Prism MVVM application structure and Menus were always nicely bound to ObservableCollections in the ViewModel and the above seems to break this nice pattern. Is the above the customary way to do it in Prism?

+3  A: 

Update:

I created a sample for you. It's here: Sample

It's got a few things you've probably not thought of yet, like a contract that will allow your modules to control your shell (so you can do stuff like Open Window, that kind of thing). It's designed with MVVM in mind... I dunno if you are using that, but I would consider it.

I tried for a few minutes to get the tab titles correct, but I ended up leaving off with "A Tab". It's left as an exercise for you if you go with a tabbed UI. I've designed it to be lookless, so you can replace the XAML in the Shell.xaml without breaking anything. That's one of the advantages to the RegionManager stuff if you use it right.

Anyway, good luck!


I've never seen an example of this, but you'd have to implement this yourself.

You'd have to create your own interface, something like this:

public interface IMenuRegistry
{
     void RegisterViewWithMenu(string MenuItemTitle, System.Type viewType);
}

Your Modules then would declare a dependency on an IMenuRegistry and register their views.

Your implementation of IMenuRegistry (which you would likely implement and register in the same project that hosts your Bootstrapper) you would add those menu items to your menu or treeview or whatever you are using for your menu.

When a user clicks on an item you'll have to use your Bootrapper.Container.Resolve(viewType) method to create an instance of the view and stuff it in whatever placeholder you want to show it in.

Anderson Imes
Your CAGMenus example looks very interesting, I'll take a closer look at that. I solved this issue by making a LayoutManager in which each module registers itself, then in the Intialize() method of the LayoutManager, it builds the application based on all the registered parts.
Edward Tanguay