我有一个应用程序,我有一个主视图模型,其视图包含一个tabcontrol,其中每个选项卡都有自己的视图和viewmodel(可能还有更多)。我相信这是一个非常常见的设计。现在,我想通过从这些选项卡中的控件发出命令来打开新选项卡(通过实例化新的视图模型并将它们添加到工作空间集合中)。问题是命令是由内部视图模型接收的,它控制选项卡,而不是控制tabcontrol的外部视图。这样做的最佳做法是什么?我能想到的所有解决方案都有点“hacky”(给viewmodel一个对其父视图模型的引用,从父节点订阅一个子节点...)。我假设有一个很好的解决方案。
例如,从“实体列表”视图中,单击“新建”按钮或选择行应打开另一个带有“实体详细信息”类型视图的选项卡。但是,该命令将由绑定选项卡的“实体列表”视图的viewmodel接收,而不是tabcontrol绑定到的“工作空间列表”视图模型。
答案 0 :(得分:1)
您可以使用标准.NET事件(订阅父级中的子事件),也可以使用事件聚合器模式进行更多解耦。
Prism和Caliburn.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);
}
}