在WPF MVVM中打开对话框 [英] Open dialog in WPF MVVM

查看:226
本文介绍了在WPF MVVM中打开对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,需要从用户输入一些信息的按钮打开一个对话框。



目前我这样做(这工作正常)




  • 按钮单击在ViewModel中生成一个命令。

  • ViewModel引发一个事件控制器监听。

  • 控制器制定新窗口的详细信息(即View,ViewModel& model)并打开它(ShowDialog)

  • 当窗口关闭时,Controller将结果添加到eventargs并返回到ViewModel

  • ViewModel将信息传递给Model。



    • 有很多步骤,但都是有意义的,没有多少打字。



      代码看起来像这个(窗口要求用户名)



      ViewModel:

        AskUserNameCommand = DelegateCommand(AskUserNameExecute); 
      ...

      public event EventHandler< AskUserEventArgs> AskUserName;

      void AskUserNameExecute(object arg){
      var e = new AskUserNameEventArgs();
      AskUserName(this,e);
      mModel.SetUserName(e.UserName);
      }

      控制器:

        mViewModel.AskUserName + =(sender,e)=> {
      var view = container.Resolve< IAskUserNameView>();
      var model = container.Resolve< IAskUserNameModel>();
      var viewmodel = container.Resolve< IAskUserNameViewModel>(view,model);
      if(dlg.ShowDialog()?? false)
      e.UserName = model.UserName;
      }

      我的问题是水平通信在MVVM模式中的工作原理。
      不知怎的,让控制器参与模型之间的数据传输似乎是错误的。



      我看过调解器模式让模型直接通信。不喜欢这个想法,因为它使模型取决于GUI的实现细节。 (即如果对话框被替换为文本框,则模型需要更改)

      解决方案

      我不喜欢目前的建议有一个原因,所以我以为我会链接到一个几乎相同的问题与答案我像:



      打开文件对话框MVVM



      具体来说,Cameron MacFarland的答案正是我所做的。通过界面提供的服务,以提供IO和/或用户互动是出于以下原因的方式




      • 可测试

      • 它会抽出任何对话框的实现,以便您可以更改处理这些类型事物的策略,而不影响组成代码

      • 不依赖于任何通信模式。你看到的很多建议依赖于一个调解员,像事件聚合器。这些解决方案依赖于与调解员另一方的合作伙伴实施双向沟通,这是很难实现的,而且一个非常宽松的合同。

      • ViewModels保持自治。 STRONG>。我像你一样,感觉不到控制器和ViewModel之间的通信。如果没有任何其他原因,如果这样可以缓解可测试性,ViewModel应该保持自主。



      希望这有帮助。


      I have an application that need to open a dialog from a button where the user enters some information.

      At the moment I do it like this (which works fine)

      • The button click generates a command in the ViewModel.
      • The ViewModel raises an event which the Controller listens to.
      • The Controller works out the details of the new window (i.e. View, ViewModel & model) and opens it (ShowDialog)
      • When the window is closed the Controller adds the result to the eventargs and returns to the ViewModel
      • The ViewModel passes the information to the Model.

      There are a lot of steps but they all make sense and there is not much typing.

      The code looks like this (the window asks for the user's name)

      ViewModel:

      AskUserNameCommand = DelegateCommand(AskUserNameExecute);
      ...
      
      public event EventHandler<AskUserEventArgs> AskUserName;
      
      void AskUserNameExecute(object arg) {
          var e = new AskUserNameEventArgs();
          AskUserName(this, e);
          mModel.SetUserName(e.UserName);
      }
      

      Controller:

      mViewModel.AskUserName += (sender,e) => {
          var view = container.Resolve<IAskUserNameView>();
          var model = container.Resolve<IAskUserNameModel>();
          var viewmodel = container.Resolve<IAskUserNameViewModel>(view, model);
          if (dlg.ShowDialog() ?? false)
              e.UserName = model.UserName;
      }
      

      My question is how the horizontal communication works in the MVVM pattern. Somehow it seems wrong to let the controller be involved in the data transfer between the models.

      I have looked at the mediator pattern to let the models communicate directly. Don't like that idea since it makes the model depending on implemetations details of the GUI. (i.e. if the dialog is replaced with a textbox, the model need to change)

      解决方案

      I don't like most of the current suggestions for one reason or another, so I thought I would link to a nearly identical question with answers I do like:

      Open File Dialog MVVM

      Specifically the answer by Cameron MacFarland is exactly what I do. A service provided via an interface to provide IO and/or user interaction is the way to go here, for the following reasons:

      • It is testable
      • It abstracts away the implementation of any dialogs so that your strategy for handling these types of things can be changed without affecting constituent code
      • Does not rely on any communication patterns. A lot of suggestions you see out there rely on a mediator, like the Event Aggregator. These solutions rely on implementing two-way communication with partners on the other side of the mediator, which is both hard to implement and a very loose contract.
      • ViewModels remain autonomous. I, like you, don't feel right given communication between the controller and the ViewModel. The ViewModel should remain autonomous if for no other reason that this eases testability.

      Hope this helps.

      这篇关于在WPF MVVM中打开对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆