WPF中MVVM下的父子视图通信

Parent and Child View communication under MVVM on WPF

我已经为这个问题苦苦挣扎了一段时间。我正在构建我的第一个 WPF MVVM 应用程序。在此应用程序中,我有一个 AppView(及其相应的视图模型)。子视图包含在选项卡中并由单独的视图(用户控件)表示,并且每个视图都有一个视图模型。到目前为止,一切都很好。

在一个视图中,有一个客户列表和一个删除按钮。我在视图模型上也有一个 correspondig 命令来实际删除记录,这个工作正常。现在我想要删除按钮创建一个带有两个按钮的新视图,一个用于确认,另一个用于取消,然后如果用户单击 "Confirm" 按钮,则执行删除。

这里的问题是每个视图及其对应的视图模型都是相互隔离的(据我所知),所以我无法访问第二个视图视图模型以查看是否单击了确认按钮。

目前我找到的唯一可行的解​​决方案是在一个视图上添加一个事件并将另一个视图订阅该事件。但这项技术对于这样一项微不足道的任务来说是相当复杂的。还有其他选择吗?两个视图不能共享相同的数据上下文或视图模型吗?

谢谢!

var dialog = new DialogViewModel();// could be a DialogService if you wish

在此 DialogViewModel 或 DialogService 中,您可以再次选择实际操作方式。

dialog.Result 在这种情况下 return 您的确认要么是真要么是假

var settings = new Dictionary<string, object>(); settings["Owner"] = this; settings["WindowStartupLocation"] = WindowStartupLocation.CenterParent; windowManager.ShowDialog(dialog, null, settings);

if(dialog.Result == true) do the delete on the parent viewmodel.

或者您可以使用 IEventAggregator 和消息包来完成这一切。我个人将第一个用于很多事情。有时根据情况组合。

大多数人会喜欢 SoC 的 IDialogService 方法,并使用它进行 DI 以将其带入使用它的视图模型中。然后每个视图模型将负责自己的对话框。从那里您可以调用 ShowDialog,因为它是 WindowManager 的一部分,您可以单击是或否,或者您为对话视图设置的任何内容。给猫剥皮的方法有很多,但最后你想要 KISS 方法和一些不会破坏你试图坚持的模式的东西。不管怎样,你都可以将它添加到 viewmodelbase base class for您要继承的所有视图模型都可以全局访问。无论如何,所有功能都取决于您希望您的应用程序如何运行。

--更新--

public class YourViewModel(IWindowManager winMan)
{
     private readonly IWindowManager _winMan;
     public YourViewModel()
     {
       _winMan = winMan;
     }

     public void DeleteCustomer()
     {
        var dialog= new DialogViewModel(); // not best way but...
        var settings = new Dictionary<string, object>();
        settings["Owner"] = this;  //<< Parent
        settings["StartupLocation"] = WindowStartupLocation.CenterParent;
        _winMan.ShowDialog(dialog, null, settings);

        if(dialog.Result)
          //do delete
        else
          //do nothing
     }
}