从不同的ViewModel执行相同的Prism命令

时间:2012-03-07 22:40:23

标签: c# wpf mvvm prism

是否可以使用Prism从WPF应用程序中的不同ViewModel以某种方式执行一个命令?

让我解释一下我的意思。

我有MainMenuViewModel类:

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

            return _aboutCommand;
        }
    }
}

还有此模型的视图:

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

应用程序中还有另一个模块,它应该以相同的行为执行命令(甚至可能更好 - 相同的命令):

public class MunisatorViewModel
{
    private ICommand _aboutCommandInAnotherModule;

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

            return _aboutCommandInAnotherModule;
        }
    }
}

此模块具有视图:

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

是否可以避免重复的代码?

P.S。我明白,我可以为这两个ViewModel创建基类并在那里描述这个命令,但问题是,有些ViewModel已经有了不同的基类。

2 个答案:

答案 0 :(得分:2)

使用EventAggregator引发这样的事件。这允许您在UI的不同区域之间进行松散耦合的通信。

发布/订阅概念,通过实现CompositeEvent对象传递数据效果很好。

或者,您可以将命令设置为静态并从不同区域访问它,但这似乎并不那么好。

Prism documentation详细介绍了您的选择。

希望有所帮助。

答案 1 :(得分:0)

也许你可以将你的AboutCommand重构为一个单独的类/对象,然后可以将它注入到两个视图模型中(构造函数,设置器......)。这样每个viewmodel都只会提供对命令对象的引用,并且会有一些重复的代码,用于从主视图模型“外包”AboutCommand逻辑的价格。

另一种更静态的方法可能是使用包含CompositeCommands的命令代理,例如AboutCommand。然后,您可以在任何地方注册about命令的(或多个)实现。

希望这有帮助。