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

泄露秘密 提交于 2020-01-03 17:01:36

问题


There are three windows MainWindow, FirstWindow and SecondWindow. MainWindow can open FirstWindow and SecondWindow.

Now my question is:

  • How to open SecondWindow from FirstWindow, and close FirstWindow when the SecondWindow open. At this time, I can control SecondWindow but can't control MainWindow, just like using SecondWindow.ShowDialog() from MainWindow.
  • After I click the "save" button on SecondWindow, the SecondWindow shall be closed and the DataGrid of MainWindow shall be updated. How to update data from another ViewModel or how to return data when event was handled?

回答1:


You are asking multiple for multiple things here.

Basically you need 2 things. An event aggregator (also called messenger) to pass messages between view models. There are different frameworks that implement it or they come as part of MVVM Frameworks.

Second you need is a navigation service to decouple navigation from your view models, as navigation requires knowledge of the view related technology (WPF, UWP, Silverlight etc.)




回答2:


I'm agree with Tseng's answer and will try to extend his answer.

First part

For low-coupled communication between modules (not only ViewModels) we can try to implement EventAggregator pattern. Event aggregator helps to implement subscriber/publisher pattern in low-coupled app. I know few different implementations.

First one based on CodeProject post and uses WeakReference that will help you to prevent memory leak. I will not publish whole code because you can just download source code and use it. In this implementation you must to implement ISubscriber interface for your subscribers.

The second is Microsoft Prism implementation. This is an open source project then you can see interface, implementation and base event class. In this implementation you must unsubscribe from the event manually.

The third and the last is MVVMLight library and its Messenger class.

As you can see all of this implementations uses Singleton pattern for saving subscribers.

Second part

Second part is about navigation. The simpliest way is to use Page navigation infrastructure. But in MVVM-world we have many different concepts for navigation.

The main purpose to use navigation abstractions is to separate navigation logic from concrete view rendering technology (WPF, Silverlight, WinRT, Xamarin).

For example, in Microsoft Prism we can use regions and RegionManager for navigation between views and windows. It's very ponderous navigation framework and it can be difficult to understand the concept after only one article.

MVVM Light also have their own navigation mechanism.

For my projects I use my own realization of navigation via Workspaces. It is a hybrid mechanism that combines Page navigation principes from .net and Regions concept from Prism.

Conclusions

This post is not an answer to your questions. But I hope that it will be helpful to you to understanding MVVM concepts.

As you can read above there are many MVVM-frameworks which contains infrastructure (not only Messenger and NavigationService, but also base command realisations, PopupService, converters, INotifyPropertyChanged-helpers and base ViewModel implementations) to implement typical scenarios in your application.




回答3:


You need to use an instance of the form class to pass data. See my simple two form project below

Form 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();
        }
    }
}
​

Form 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";
        }

    }
}
​


来源:https://stackoverflow.com/questions/34258994/how-to-communicate-between-viewmodels-in-wpf-and-how-to-control-views-lifecycle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!