wpf棱镜复合命令

发布于 2024-08-21 09:11:31 字数 746 浏览 1 评论 0原文

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

对于每个工具栏项,我都关联了一个棱镜委托命令对象。

示例:

private ICommand _printCommand;

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

        return _printCommand;
    }
}

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

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

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

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

I have a composite WPF application. I am planning to implement tool bar functionality. There are few toolbar items (basically print, save, hide, expand, undo) which will be common to all views in the main region. For this i have created default toolbar module which will add these items (print, save, hide, expand, undo) to the toolbar region. when user clicks any toolbar item, this need to be handled by all 20 views in the main region.

For each toolbar item, i have associated a prism delegatecommand object.

sample:

private ICommand _printCommand;

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

        return _printCommand;
    }
}

Xaml, bind toolbar item to this command.

In the main region, we display close to 20 views. All these views have to subscibe to this command. I am thinking of using event aggregator to publish an event, and all the views will subcribe to this event.

For ex:
when the user clicks print, print command executes Print method which will publish print event. This event will be subcribed by 20 views and do further processing.

Am I implementing the toolbar in the right way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

£冰雨忧蓝° 2024-08-28 09:11:31

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

例如:应用程序支持 40 个视图
主要区域-> 20 个活动视图,所有视图模型均派生自 BaseViewModel。

工具栏->保存按钮->数据绑定到compositesaveall命令(启用主动感知监视器)
基础视图模型->保存命令-> 当用户点击保存按钮时,根据特定的过滤条件向compositesaveallcommand注册/取消注册

,compositesaveallcommand查找所有已注册的活动命令,并检查所有已注册的viewmodel命令调用(canexecute方法,所有已注册的命令需要返回true)然后调用child命令(执行方法)。

但在我的例子中,如果用户在单个视图中进行修改,则其余 19 个视图不会有任何修改。但我想为单个视图执行保存。看起来复合命令不会调用注册的命令,除非它可以执行所有命令。

I had initially thought of using composite commands. But by going through documentation it may not fit my requirements.

Ex : Application supports 40 views
Main region -> 20 Views that are active , all the view models are derived from baseviewmodel.

toolbar -> save button -> databinding to compositesaveallcommand(activeaware monitor enabled)
baseviewmodel -> save command -> registers/ unregisters based on specific filter conditions to compositesaveallcommand

when user clicks save button ,compositesaveallcommand looks for all registered commands that are active, and checks for all registered viewmodel commands calls (canexecute method, and all registered commands need to return true) then invokes child commands ( execute method) .

But in my case if the user make modifications in a single view , remaining 19 views there are no modifications. But I would like to execute save for single view. Looks like composite command will not invoke registered comamnds unless it can execute all.

凑诗 2024-08-28 09:11:31

如果应用程序允许用户同时执行多个命令,我们可能希望允许用户使用由功能区按钮表示的单个命令来保存不同选项卡上的所有项目。在这种情况下,“全部保存”命令将调用视图模型实例为每个项目实现的每个“保存”命令。
例如,在 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; }
    }
}

If application allows the user to executes multiple commands at the same time, we may want to allow the user to save all the items on different tabs using a single command represented by a ribbon button. In this case, the Save All command will invoke each of the Save commands implemented by the view model instance for each item.
In the Stock Trader RI, for example, the Submit and Cancel commands for each buy/sell order are registered with the SubmitAllOrders and CancelAllOrders composite commands, as shown in the following code example (see the OrdersController class).

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

The preceding commandProxy object provides instance access to the Submit and Cancel composite commands, which are defined statically. For more information, see the class file 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; }
    }
}
怀里藏娇 2024-08-28 09:11:31

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

This is exactly what the CompositeCommand does. I believe there are no examples (the Commanding QuickStart or the RI do not show active aware activity anymore, they did in Prism v1), but if you use the active aware stuff, you get what you are asking for.
The only thing is that you need to make sure that each of the individual DelegateCommands get their IsActive property correctly updated when they should (i.e. when the view gets activated).

悍妇囚夫 2024-08-28 09:11:31

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

使用 EventAggregator 来实现此目的可能很容易,但我认为它可能不太合适。这就是说,这并不是真的错误......事实上,我相信一些 Prism 示例正是这样做的,但我认为它给成分带来了过多的过滤责任,而不是利用框架功能。

您的主题表明您正在考虑使用 CompositeCommands 来实现此目的。您有什么理由不这样做而不是使用 EventAggregator 吗?如果您有一个标准位置,ViewModel 可以在其中注册旨在处理每个按钮的命令,并在每个按钮后面放置一个复合命令,这难道不会为您提供您想要的功能吗?除了能够处理按钮命令之外,每个组成视图/视图模型还能够在按钮不合适时禁用按钮等。

仔细查看 Prism 文档中的 CompositeCommand 示例,看看它们是否不这样做做你想做的事。

I don't really like the idea of using the EventAggregator too much for things like this. Especially if you decided to create a multi document editor interface, each of your editors is going to be responsible for a lot of filtering to get the events that are only appropriate for them.

It might be easy to use EventAggregator for this purpose, but I think it's probably not really the right fit. That said, it's not really wrong... in fact I believe a few of the Prism samples do exactly this, but I think it puts too much responsibility on the constituents for filtering, rather than leveraging framework features.

Your subject suggests you were thinking of using CompositeCommands for this. Is there any reason you aren't doing this instead of using the EventAggregator? If you had a standard place where ViewModels could register their Commands designed to handle each of these buttons with a composite command sitting behind each one, wouldn't that give you the functionality you wanted? In addition to being able to handle the button commands, each of the constituent views/viewmodels would be able to disable buttons when they were inappropriate, etc.

Take a close look at the CompositeCommand samples in the Prism documentation and see if they don't do what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文