【问题标题】:Execute same Prism Command from different ViewModels从不同的 ViewModel 执行相同的 Prism 命令
【发布时间】:2012-03-07 22:40:22
【问题描述】:

是否可以使用 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>

是否可以避免重复代码?

附:我知道,我可以为这两个 ViewModel 创建基类并在那里描述这个命令,但问题是,一些 ViewModel 已经有不同的基类。

【问题讨论】:

    标签: c# wpf mvvm prism


    【解决方案1】:

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

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

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

    Prism documentation 详细说明您的选择。

    希望对您有所帮助。

    【讨论】:

    • 我知道 EventAggregator,但在这种情况下避免重复代码无济于事。
    • 是的... MainMenuViewModel 将实现显示关于菜单的代码。它还将订阅一个名为“AboutCommandFired”的事件,MunisatorViewModel 将发布该事件。在 MainMenuViewModel 中,您可能还需要将实现移出匿名方法,以便可以从 DelegateCommand 和事件聚合器调用它。
    • 但在这种情况下,我仍然应该复制用于创建命令的代码,并将不同的命令分配给视图。我的问题是,是否可以将 SAME 命令实现用于不同的视图。
    【解决方案2】:

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

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

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-15
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多