views:

174

answers:

1

Like any MVVM WPF app I have a handful of view models. Each has a few commands. My view implements a Fluent UI (Office ribbon) so there are some items that light up based on the context of the application. The ribbon is a child to the main application.

The basic structure of my app is that it manages a COURSE. A COURSE has multiple MODULES in it, so I have a VM for course & module... and each has commands.

When the app loads I set the data context of the main window to the course so binding the course commands to the ribbon is easy and works fine.

The challenge comes when the user starts to work with a module. When a module is selected from a list the details are shown in another user control. Now... my challenge is how to wire up the commands to the ribbon.

I assume I could have some event handler that programatically wires up the current module's commands to all the relevant controls in the ribbon and removes everything when the context goes away. But that seems like a lot of unnecessary work. Is there a cleaner way of doing this?

I thought about routed commands/events, but someone told me that this wouldn't work because they won't bubble all thew ay up to the Window and back down to the ribbon.

Looking for some guidance here... I'm a bit of a noob to MVVM (but loving it!).

A: 

Idea: Introduce a ShellCommands class which is exposed as a service.

public class ShellCommands : IShellCommands
{
    public ICommand SaveCommand { get; set; }
    ...
}

Then the CourseViewModel and the ModuleViewModel can use the same service to register their commands.

public class CourseViewModel : ViewModel 
{
    public CourseViewModel(IShellCommands shellCommands, ...)
    {
        this.ShellCommands = shellCommands;
        ...
    }

    public IShellCommands ShellCommands { get; private set; }
}

In XAML you can access the service via the ShellCommands property.

<MenuItem Header="Save" Command="{Binding ShellCommands.SaveCommand}"/>

.

More Informations: WPF Application Framework (WAF)

jbe
AC
Scratch the last comment... I got it wired up for one command on the CourseViewModel. However downstream I create instances of the ModuleViewModel which have their own commands. Problem is that the ShellCommand property on the main window isn't getting updated with these new commands because they are new instances of the ModuleViewModel. Seems like this would be a challenge folks would run into frequently. Is there no generally accepted technique to address it (or am I just going about this the wrong way)?
AC
When I understand your comment right then you just needs to implement the INotifyPropertyChanged interface on ShellCommands. When the ModuleViewModel sets a command then the ShellCommands object raises a PropertyChanged event and notifies WPF that it has to update the command binding in the Main Window.
jbe