3

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

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

样本:

private ICommand _printCommand;

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

        return _printCommand;
    }
}

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

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

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

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

4

4 回答 4

2

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

例如:应用程序支持 40 个视图 Main region -> 20 个处于活动状态的视图,所有视图模型都来自 baseviewmodel。

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

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

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

于 2010-02-12T10:02:33.873 回答
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; }
    }
}
于 2011-04-27T10:42:34.117 回答
1

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

于 2010-02-18T21:22:36.653 回答
0

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

为此目的使用 EventAggregator 可能很容易,但我认为它可能并不适合。也就是说,这并没有错……事实上,我相信一些 Prism 样本确实做到了这一点,但我认为它对过滤的成分承担了太多责任,而不是利用框架功能。

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

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

于 2010-02-11T21:57:10.770 回答