tags:

views:

388

answers:

1

I am getting up to speed on Composite WPF, building a small demo app to work through the issues. My app has one region, and two modules, Module A and Module B. Each module contains a simple "Hello World" text block. Both modules are set up as load-on-demand, as per this MSDN How-To.

The shell has two buttons, "Load Module A" and "Load Module B". When a button is clicked, the corresponding module is loaded. So, lets say I click "Load Module A", then "Load Module B". Module A, then Module B load as expected. But if I click "Load Module A" again, nothing happens.

I'm stuck at this point. I think my problem is that I need to activate and deactivate the views in the modules, rather than using load-on-demand. But I have no idea how to do that, and I can't find any documentation or blogs that talk about it.

So, here's my question: How to I load/unload (or show/hide) views? If someone can point me to sample code, I'd really appreciate it. Thanks for your help.

+1  A: 

I found my answer. Here is the approach: Load all the modules at startup, then activate and deactivate views as you need them. I am going to write this issue up as a CodeProject article, but here is an outline of how to do it:

(1) In the module Initialize() method, add the module, but don't activate it:

public void Initialize()
{
    // Get main region
    var mainRegion = m_RegionManager.Regions["MainRegion"];

    // Load Module B
    var newView = new ModuleBView();
    mainRegion.Add(newView, "ModuleA.ModuleAView");
}

Note that the Add() method has two parameters. The second parameter is the name of the view, which we set to the value produced by the ToString() method of the view. We'll see why in the next step.

(2) When activating a view, we need to deactivate the previous view. But we may not know the name of the view, so we deactivate all active views:

public static void ClearRegion(IRegion region)
{
    // Get existing view names
    var oldViewNames = new List<string>();
    foreach (var v in region.Views)
    {
        var s = v.ToString();
        oldViewNames.Add(s);
    }

    // Remove existing views
    foreach (var oldViewName in oldViewNames)
    {
        var oldView = region.GetView(oldViewName);
        region.Deactivate(oldView);
    }
}

Since we set the name of each view equal to its ToString() value, we can get the names easily without knowing anything about them in advance.

(3) Now we activate the new view. I do it in an MVVM ICommand.Execute() method:

public void Execute(object parameter)
{
    // Get main region
    var mainRegion = m_ViewModel.RegionManager.Regions["MainRegion"];

    // Clear region
    ModuleServices.ClearRegion(mainRegion);

    // Activate Module A view
    var moduleAView = mainRegion.GetView("ModuleA.ModuleAView");
    mainRegion.Activate(moduleAView);
}

Hopefully, that will be enough to get you going. Like I said, I plan to do a more complete writeup, with demo code, for CodeProject.

David Veeneman
Foresight Systems

David Veeneman