【问题标题】:Using viewmodel commands to open new tabs使用 viewmodel 命令打开新选项卡
【发布时间】:2012-02-20 07:42:07
【问题描述】:

我有一个应用程序,其中有一个主视图模型,其视图包含一个选项卡控件,其中每个选项卡都有自己的视图和视图模型(可能还有更多)。我相信这是一个很常见的设计。现在,我想通过从这些选项卡内的控件触发命令来打开新选项卡(通过实例化新视图模型并将它们添加到工作区集合中)。问题是命令是由控制选项卡的内部视图模型接收的,而不是控制选项卡控件的外部视图模型。这样做的最佳做法是什么?我能想到的所有解决方案都是一种“hacky”(为视图模型提供对其父视图模型的引用,从父视图订阅孩子的事件......)。我假设有一个很好的解决方案。

例如,在“实体列表”视图中,单击“新建”按钮或选择一行应该会打开另一个具有“实体详细信息”类型视图的选项卡。但是,该命令将由选项卡绑定到的“实体列表”视图的视图模型接收,而不是选项卡控件绑定到的“工作区列表”视图模型。

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    一种可能性是让您的外部视图模型公开命令以创建新选项卡。我们使用一个集中的 CommandService,它只是一个 name-to-ICommand 的字典,它允许解耦全局命令。像这样的:

    public interface ICommandService
    {
        void RegisterCommand(string name, ICommand command);
        ICommand this[string name] {get;}
    }
    
    public class OuterViewModel
    {
        public OuterViewModel (ICommandService commandService)
        {
            commandService.RegisterCommand("OpenNewTab", OpenNewTab);
        }
    
        private void OpenNewTab (object newTabViewModel)
        {
             // The new tab's viewmodel is sent as the ICommand's CommandParameter
        }
    }
    
    public class InnerViewModel
    {
        public InnerViewModel (ICommandService commandService)
        {
            _commandService = commandService; // Save injected service locally.
        }
    
        public HandleClickOnInnerTabpage()
        {
             AnotherViewModel newVM = new AnotherViewModel(...);
             _commandService["OpenNewTab"].Execute(newVM);
        }
    }
    

    【讨论】:

    • 我决定使用类似的东西。我有一个单例 ServiceRegister,其中一个对象可以将自己注册为某种类型的服务。因此,作为 tabcontrol 绑定的视图模型执行 ...Register(this)。内部视图模型执行 GetServices()。 IOpenWorkspaces 接口包含一个方法,一个参数化的 OpenWorkspace。
    【解决方案2】:

    您可以使用标准 .NET 事件(订阅父事件中的子事件),或者为了进一步解耦,使用事件聚合器模式。

    PrismCaliburn.Micro 等框架实现了事件聚合器模式,MVVM Light Toolkit 提供了一个 Messenger 类用于相同目的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-02
      • 1970-01-01
      • 1970-01-01
      • 2019-10-05
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      相关资源
      最近更新 更多