代码之家  ›  专栏  ›  技术社区  ›  adrianm

在wpfmvvm中打开对话框

  •  9
  • adrianm  · 技术社区  · 15 年前

    目前我是这样做的(效果很好)

    • ViewModel引发控制器侦听的事件。
    • 控制器计算出新窗口的详细信息(即View、ViewModel和model)并将其打开(ShowDialog)

    有很多步骤,但他们都有意义,并没有太多的打字。

    代码如下所示(窗口要求输入用户名)

    视图模型:

    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的实现细节。(即,如果对话框被文本框替换,则模型需要更改)

    5 回复  |  直到 10 年前
        1
  •  14
  •   Community CDub    8 年前

    比如:

    Open File Dialog MVVM

    具体来说,卡梅隆·麦克法兰的回答正是我所做的。通过提供的服务 接口 提供IO和/或用户交互 :

    • 这是可以测试的
    • 它抽象了任何对话框的实现 因此,您处理这些类型的事情的策略可以在不影响组成代码的情况下进行更改
    • 视图模型保持自治 . 一、 和您一样,在控制器和ViewModel之间进行通信时感觉不太好。如果没有其他原因使ViewModel易于测试,那么ViewModel应该保持自治。

    希望这有帮助。

        2
  •  2
  •   Community CDub    8 年前

    我用 this

    var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);
    
        3
  •  0
  •   Guge    15 年前

    我的解决方案:

    如果我的代码需要某个视图是模态的,它会在这个属性中放置对它的引用。MainWindowView通过INotifyPropertyChanged机制监视此属性。如果Modal设置为某个VM,MainWindowView类将获取该VM并将其放入ModalView窗口中,在该窗口中,适当的用户控件将通过DataTemplates的魔力显示,该窗口将使用ShowDialog显示。ModalViewModelBase有一个DialogResult属性和一个名为IsFinished的属性。当模态VM将IsFinished设置为true时,视图关闭。

    模态视图的原理是在显示模态视图的同时禁用其他视图。这是视图逻辑的一部分,基本上是无外观的。这就是为什么我在MainWindowViewModel中有一个属性。如果我更进一步,我应该让主VM中所有其他VM的所有其他属性或命令在模态模式下抛出异常,但我觉得这太过分了。

    实际上拒绝用户任何其他操作的视图机制不必通过弹出窗口和showdialog来执行,它可以是您将模式视图放在现有窗口中,但禁用所有其他窗口或其他一些操作。这个与视图相关的逻辑属于视图本身。(一个典型的设计师不能为这种逻辑编写代码,这似乎是次要的问题。有时我们都需要帮助。)

    所以我就是这样做的。我提供它只是作为一个建议,可能有其他的思考方式,我希望你得到更多的答复了。

        4
  •  0
  •   Raj    15 年前

    我用过 EventAggregator 类似场景下的Prism v2。prims的好处是,您不必在MVVM应用程序中使用整个框架。您可以提取EventAggregator功能,并将其与当前设置一起使用。

        5
  •  -1
  •   xdoo    15 年前

    您可以看看这篇MVVM文章。它描述了控制器如何与ViewModel通信:

    http://waf.codeplex.com/wikipage?title=Model-View-ViewModel%20Pattern&ProjectName=waf