Execute same Prism Command from different ViewMode

2019-06-02 23:28发布

问题:

Is it possible to execute somehow one Command from a different ViewModels in the WPF application using Prism?

Let me explain what I mean.

I have the MainMenuViewModel class:

public class MainMenuViewModel
{
    private ICommand _aboutCommand;
    public ICommand AboutCommand
    {
        get
        {
            if (_aboutCommand == null)
            {
                _aboutCommand = new DelegateCommand(() => 
                    { MessageBox.Show("About menu item clicked!"); });
            }

            return _aboutCommand;
        }
    }
}

also there is the View for this model:

<Menu IsMainMenu="True">
    <MenuItem Header="Nápověda">
        <MenuItem Header="O Aplikaci" x:Name="About" 
                  Command="{Binding AboutCommand}" />
    </MenuItem>
</Menu>

There is another module in the application, which should execute the command with the same behavior (or even probably better - the same command):

public class MunisatorViewModel
{
    private ICommand _aboutCommandInAnotherModule;

    public ICommand AboutCommandInAnotherModule
    {
        get
        {
            if (_aboutCommandInAnotherModule== null)
            {
                _aboutCommandInAnotherModule= new DelegateCommand(() =>
                    { MessageBox.Show("About menu item clicked!"); });
            }

            return _aboutCommandInAnotherModule;
        }
    }
}

this module has the View:

<StackPanel Background="White" HorizontalAlignment="Center" VerticalAlignment="Top">
    <Button cmd:Click.Command="{Binding AboutCommandInAnotherModule}">About</Button>
</StackPanel>

Is it possible to avoid the duplicate code?

P.S. I understand, that I can create base class for this two ViewModels and describe this Commands there, but problem is, that some of the ViewModels has already different base classes.

回答1:

Use the EventAggregator to raise events like this. This allows you to have loosely coupled communication between different areas of the UI.

The publish/subscribe concept, passing data through implementing a CompositeEvent object works well.

Alternatively, you can make your command static and access it from different areas but this doesn't seem all that nice.

Prism documentation details your options in depth.

Hope that helps.



回答2:

Maybe you could refactor your AboutCommand into a separate class/object, that then could be injected into both viewmodels (constructor, setter...). This way every viewmodel would just deliver a reference to the command object and there would be duplicate code for the price of 'outsourcing' your AboutCommand-logic from your main viewmodel.

Another more static way could be to use a command proxy that contains CompositeCommands, for example your AboutCommand. Anywhere you could then register the (or multiple) implementation(s) for the about command.

Hope this helps.



标签: c# wpf mvvm Prism