繁体   English   中英

如何在WPF中的ViewModel之间进行通信以及如何控制视图生命周期

[英]How to communicate between ViewModels in WPF and how to control Views lifecycle

MainWindow,FirstWindow和SecondWindow有三个窗口。 MainWindow可以打开FirstWindow和SecondWindow。

现在我的问题是:

  • 如何从FirstWindow打开SecondWindow,并在SecondWindow打开时关闭FirstWindow。 这时,我可以控制SecondWindow但无法控制MainWindow,就像使用MainWindow中的SecondWindow.ShowDialog()一样。
  • 单击SecondWindow上的“保存”按钮后,将关闭SecondWindow,并更新MainWindow的DataGrid。 如何更新来自另一个ViewModel的数据或如何在处理事件时返回数据?

你在这里问多个事情。

基本上你需要2件事。 用于在视图模型之间传递消息的事件聚合器(也称为messenger)。 有不同的框架可以实现它,或者它们是MVVM框架的一部分。

其次,您需要的是导航服务,以便将导航与视图模型分离,因为导航需要了解视图相关技术(WPF,UWP,Silverlight等)

我同意Tseng的回答,并会尝试扩展他的答案。

第一部分

对于模块之间的低耦合通信(不仅是ViewModels),我们可以尝试实现EventAggregator模式。 事件聚合器有助于在低耦合应用程序中实现订阅者/发布者模式。 我知道几个不同的实现。

第一个基于CodeProject的帖子并使用WeakReference来帮助您防止内存泄漏。 我不会发布整个代码,因为您只需下载源代码并使用它。 在此实现中,您必须为订户实现ISubscriber接口。

第二个是Microsoft Prism实现。 这是一个开源项目,然后您可以看到接口实现基本事件类 在此实现中,您必须手动取消订阅该事件。

第三个也是最后一个是MVVMLight库及其Messenger类。

如您所见,所有这些实现都使用Singleton模式来保存订阅者。

第二部分

第二部分是关于导航。 最简单的方法是使用页面导航基础结构。 但是在MVVM世界中,我们有许多不同的导航概念。

使用导航抽象的主要目的是将导航逻辑与具体视图渲染技术(WPF,Silverlight,WinRT,Xamarin)分开。

例如,在Microsoft Prism中,我们可以使用区域和RegionManager在视图和窗口之间进行导航。 这是非常笨重的导航框架,只有一篇文章后很难理解这个概念。

MVVM Light也有自己的导航机制

对于我的项目,我使用自己的工作空间导航实现。 它是一种混合机制,它结合了来自Prism的.net和Regions概念的页面导航原理。

结论

这篇文章不是你问题的答案。 但我希望您了解MVVM概念会对您有所帮助。

如上所述,有许多MVVM框架包含基础结构(不仅包括Messenger和NavigationService,还包括基本命令实现,PopupService,转换器, INotifyPropertyChanged -helpers和基本ViewModel实现),以实现应用程序中的典型方案。

您需要使用表单类的实例来传递数据。 请参阅下面的简单的两个表单项目

表格1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Form2 form2;
        public Form1()
        {
            InitializeComponent();
            form2 = new Form2(this);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            form2.Show();
            string  results = form2.GetData();
        }
    }
}
​

表格2

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        Form1 form1;
        public Form2(Form1 nform1)
        {
            InitializeComponent();

            this.FormClosing +=  new FormClosingEventHandler(Form2_FormClosing);
            form1 = nform1;
            form1.Hide();
        }
        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            //stops form from closing
            e.Cancel = true;
            this.Hide();
        }
        public string GetData()
        {
            return "The quick brown fox jumped over the lazy dog";
        }

    }
}
​

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM