使用viewmodel命令打开新选项卡

时间:2012-02-20 07:42:08

标签: c# wpf mvvm

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

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

2 个答案:

答案 0 :(得分:1)

您可以使用标准.NET事件(订阅父级中的子事件),也可以使用事件聚合器模式进行更多解耦。

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

答案 1 :(得分: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);
    }
}