【问题标题】:wpf prism composite commandwpf prism 复合命令
【发布时间】:2011-01-15 20:57:26
【问题描述】:

我有一个复合 WPF 应用程序。我计划实现工具栏功能。有几个工具栏项(基本上是打印、保存、隐藏、展开、撤消)对主区域中的所有视图都是通用的。为此,我创建了默认工具栏模块,它将这些项目(打印、保存、隐藏、展开、撤消)添加到工具栏区域。当用户单击任何工具栏项时,这需要由主区域中的所有 20 个视图来处理。

对于每个工具栏项,我都关联了一个 prism delegatecommand 对象。

样本:

private ICommand _printCommand;

public ICommand PrintCommand
{
    get
    {
        if (_printCommand == null)
        {
            _printCommand = 
                new DelegateCommand<object>(**Print**, **CanPrint**);                    
        }

        return _printCommand;
    }
}

Xaml,将工具栏项绑定到此命令。

在主要区域,我们展示了近 20 个视图。所有这些视图都必须订阅此命令。我正在考虑使用事件聚合器发布一个事件,所有的视图都会订阅这个事件。

例如: 当用户点击打印时,打印命令执行 Print 方法,该方法将发布打印事件。此事件将被 20 个视图订阅并做进一步处理。

我是否以正确的方式实现工具栏?

【问题讨论】:

  • 您希望打印所有视图,还是只打印当前视图,例如具有输入焦点的视图?
  • 对于 print ,我想用输入焦点打印视图。但是对于 save & expand ,它应该应用于所有视图

标签: wpf prism command composite


【解决方案1】:

我最初考虑使用复合命令。但是通过查看文档,它可能不符合我的要求。

例如:应用程序支持 40 个视图 Main region -> 20 Views that are active ,所有的视图模型都是从baseviewmodel派生的。

工具栏->保存按钮->数据绑定到compositesaveallcommand(启用activeaware监视器) baseviewmodel -> 保存命令 -> 根据特定过滤条件注册/取消注册到复合保存命令

当用户单击保存按钮时,compositesaveallcommand 会查找所有已注册的活动命令,并检查所有已注册的视图模型命令调用(canexecute 方法,并且所有已注册的命令都需要返回 true)然后调用子命令(execute 方法)。

但在我的情况下,如果用户在单个视图中进行修改,剩下的 19 个视图没有修改。但我想为单个视图执行保存。看起来复合命令不会调用已注册的命令,除非它可以全部执行。

【讨论】:

  • 是的,在这种情况下,您可能希望在复合命令旁边使用命令。查看带有“保存/全部保存”的棱镜样本,我不记得它是哪一个,但我认为这就是您要找的。它使用常规命令进行保存,使用复合命令进行全部保存。此外,如果您对某个答案有回复,请使用“评论”功能或更新您的答案,而不是发布另一个答案。
【解决方案2】:

如果应用程序允许用户同时执行多个命令,我们可能希望允许用户使用由功能区按钮表示的单个命令将所有项目保存在不同的选项卡上。在这种情况下,Save All 命令将调用视图模型实例为每个项目实现的每个 Save 命令。 例如,在 Stock Trader RI 中,每个买入/​​卖出订单的 Submit 和 Cancel 命令都使用 SubmitAllOrders 和 CancelAllOrders 复合命令注册,如以下代码示例所示(请参阅 OrdersController 类)。

commandProxy.SubmitAllOrdersCommand.RegisterCommand(
                    orderCompositeViewModel.SubmitCommand );
commandProxy.CancelAllOrdersCommand.RegisterCommand(
                    orderCompositeViewModel.CancelCommand );

前面的 commandProxy 对象提供对静态定义的 Submit 和 Cancel 复合命令的实例访问。有关详细信息,请参阅类文件 StockTraderRICommands.cs。

public class MyViewModel : NotificationObject
{
    private readonly CompositeCommand saveAllCommand;

    public ArticleViewModel(INewsFeedService newsFeedService,
                            IRegionManager regionManager,
                            IEventAggregator eventAggregator)
    {
        this.saveAllCommand = new CompositeCommand();
        this.saveAllCommand.RegisterCommand(new SaveProductsCommand());
        this.saveAllCommand.RegisterCommand(new SaveOrdersCommand());
    }

    public ICommand SaveAllCommand
    {
        get { return this.saveAllCommand; }
    }
}

【讨论】:

    【解决方案3】:

    这正是 CompositeCommand 所做的。我相信没有示例(Commanding QuickStart 或 RI 不再显示主动感知活动,它们在 Prism v1 中做了),但是如果您使用主动感知的东西,您会得到您所要求的。 唯一的事情是,您需要确保每个单独的 DelegateCommands 在它们应该正确更新它们的 IsActive 属性时(即当视图被激活时)。

    【讨论】:

      【解决方案4】:

      我不太喜欢将 EventAggregator 用于此类事情的想法。特别是如果您决定创建一个多文档编辑器界面,您的每个编辑器都将负责大量过滤以获取仅适合他们的事件。

      为此目的使用 EventAggregator 可能很容易,但我认为它可能并不适合。话虽如此,这并没有错……事实上,我相信一些 Prism 样本正是这样做的,但我认为这将过多的责任放在过滤的成分上,而不是利用框架功能。

      您的主题表明您正在考虑为此使用 CompositeCommands。您是否有任何理由不这样做而不是使用 EventAggregator?如果你有一个标准的地方,ViewModel 可以注册他们的命令,这些命令旨在处理每个按钮,每个按钮后面都有一个复合命令,那不会给你想要的功能吗?除了能够处理按钮命令之外,每个组成视图/视图模型还能够在按钮不合适时禁用按钮等。

      仔细查看 Prism 文档中的 CompositeCommand 示例,看看它们是否符合您的要求。

      【讨论】:

        猜你喜欢
        • 2015-02-03
        • 1970-01-01
        • 2012-10-31
        • 2020-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-29
        相关资源
        最近更新 更多