How to load a Module on Menu Click

Topics: Prism v1, Prism v2 - Silverlight 2, Prism v2 - WPF 3.5
Feb 12, 2009 at 7:44 PM
Hi,
Im Having a requirement tht ,Shell contains Menu Bar with MenuItem.Upon Clicking on MenuItem is there any Possiblity of loading particular Module.Plz answer me asap.It is very imp.

With regards,
Mahender
Feb 16, 2009 at 5:39 PM

Hi Mahender,

 

You can add a Command to your MenuItem that loads a module on demand when the user right clicks on it by using the Module Loader and the Module Enumerator services (in Prism v1).

You can check the DirectoryLookupModularity and ConfigurationModularity quickstarts to see different ways of how modules could be loaded on demand, and the Commanding quickstart to see the usage of the commands provided by the Composite Application Library.

For further understanding, you can read the following articles in the documentation:

·         How to: Load Modules On Demand

·         How to: Dynamically Load Modules

·         How to: Create Locally Available Commands

·         How to: Create Globally Available Commands

 

For Prism v2, the approach is the same but the services involved during the module loading process were changed for the Module Catalog and Module Loader. You can download the Prism v2 – Drop 10 and check the same quickstarts and topics in the documentation (under the Development Activities section).

 

Please let me know if this helps. If you want more specific guidance on this, please provide me which version of Prism are you using.

 

Mariano Converti

http://blogs.southworks.net/mconverti

Feb 17, 2009 at 9:19 PM
Edited Feb 18, 2009 at 9:56 PM
Similar to mahens, I am creating my first Prism app (V2).  I have a module that contains the RibbonBar, and other views (controls) that represent the other functions. For the sake of discussion, let's say I have a PieChart module, PieChart.Xaml, and PieChart.xaml.cs.

When I click on the PieChart button in the RibbonBar, I want the main region to load the PieChart view.

In the examples, it appears that I have to go through a Presentaion Layer to do this. All I really want to do is set the view to a specific on based on what was clicked in the RibbonBar.

Are commands the way to go here?
EDIT:
Well,due to the fact that the RibbonBar doesn't implement ICommand, this is a little contrived, but here goes.
I returned my RibbonBar to the Shell.xaml. Each command has a CommadParameter naming the command.

In the CodeBehind, I have a single OnRibbonCommand that handles all the commands. \
(if e.Parameter =="Census")
   MenuCommands.CensusCommand.Execute(info);

From this, I utilize a common static class that has CompositeCommands to call the command. The appopriate modules Register  via this:

 public DelegateCommand<object> MenuCommand { get; set; }
MenuCommand = new DelegateCommand<object>(OnMenuCommand, ShouldBeEnabled);
  MenuCommands.CensusCommand.RegisterCommand(MenuCommand);
        private void OnMenuCommand(object param)
        {
            //do things...
        }



This is all well and good, but I am still trying to figure out how to show/hide modules in the regionmanager.


Feb 20, 2009 at 5:10 AM
Hi,
I found doing it using events is quite easy. So in the command method, I pass the moduleName I want to load:

public

 

void OnMenuCommand(string parameter)

 

{

 

var module = moduleEnumerator.GetModule(parameter);

 

moduleLoader.Initialize(

new[] { module });

 

 

RequiredModuleView requiredModuleView = new RequiredModuleView();
requiredModuleView.ModuleName = parameter;
//In case the module contains few views
requiredModuleView.ViewName = "...."
//In case the module need to load a specific item selected in another view
requiredModuleView.RequiredObjectId = ...
eventAggregator.GetEvent<
ActivateModuleEvent>().Publish(requiredModuleView);

 

}

My RequiredModuleView class look like that:

 

public

 

class RequiredModuleView
{
public string ModuleName { get; set; }
public string ViewName { get; set; }
public int SelectedObjectId { get; set; }
}

and ActivateModuleEvent is simply:

 

public

 

class ActivateModuleEvent : CompositeWpfEvent<RequiredModuleView>
{
}

Both the classses are in the common project which is referenced by all modules.
Then in the module itself:

 

public

 

void Initialize()
{
...
ActivateModuleEvent activateModuleEvent = this.eventAggregator.GetEvent<ActivateModuleEvent>();
activateModuleEvent.Subscribe(ActivetModuleEventHandler,
ThreadOption.UIThread, true, p => p.ModuleName == "the mopdule name");
}

 

private

 

void ActivetModuleEventHandler(RequiredModuleView requiredModuleView)
{
if (requiredModuleView.ViewName == "FileTypeBuilder")
{
IFileTypeBuilderCompositeViewPresentationModel presentationModel = _container.Resolve<IFileTypeBuilderCompositeViewPresentationModel>();
IRegion popRegion = _regionManager.Regions[RegionNames.PopWindowRegion];
if (!popRegion.Views.Contains(presentationModel.View))
{
popRegion.Add(presentationModel.View);
this.builderModel = presentationModel;
}
presentationModel.LoadData(requiredModuleView.SelectedObjectId);
popRegion.Activate(presentationModel.View);
}
}

There might be more elegant way to do it but this one worked for me :)
Hope it helps,
Ken