2015-12-14 26 views
4

有三個窗口MainWindow,FirstWindow和SecondWindow。 MainWindow可以打開FirstWindow和SecondWindow。現在如何在WPF中的ViewModels之間進行通信以及如何控制視圖生命週期

我的問題是:

  • 如何從FirstWindow打開SecondWindow,並密切FirstWindow當SecondWindow開放。此時,我可以控制SecondWindow,但無法控制MainWindow,就像使用MainWindow中的SecondWindow.ShowDialog()一樣。
  • 當我點擊SecondWindow上的「保存」按鈕後,SecondWindow應該關閉,並且MainWindow的DataGrid應該被更新。如何更新來自另一個ViewModel的數據或處理事件時如何返回數據?
+0

而不是使用乘法窗口 - >使用一個窗口,並乘以UserControls,這將代表第一,第二和第三個視圖。例如帶TabItems的TabControl – Fabio

回答

-1

您需要使用表單類的實例來傳遞數據。見下面

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

    } 
} 
​ 
+0

這個問題被標記爲WPF和MVVM,而不是WinForms。 MVVM是爲了解耦代碼,以避免緊密耦合和簡單的測試,並避免幾乎所有的代碼。完全不同的設計理念 – Tseng

1

你問多了許多東西在這裏我簡單的雙格式的項目。

基本上你需要2件東西。事件聚合器(也稱爲信使)在視圖模型之間傳遞消息。有不同的框架可以實現它,或者它們是MVVM框架的一部分。

第二你需要的是一個導航服務,從您的視圖模型脫鉤導航,導航需要查看相關的技術知識(WPF,UWP,Silverlight的等)

1

我與Tseng's answer同意,並會嘗試延長他的答案。

第一部分

對於模塊(不僅的ViewModels),我們可以嘗試實現EventAggregator圖案之間的低耦合通信。事件聚合器有助於在低耦合應用中實施訂閱者/發佈者模式。我知道幾個不同的實現。

第一個基於CodeProject post,並使用WeakReference來幫助您防止內存泄漏。我不會發布整個代碼,因爲您可以下載源代碼並使用它。在此實現中,您必須爲訂戶實現ISubscriber界面。

第二個是Microsoft Prism執行。這是一個開源項目,你可以看到interface,implementationbase event class。在此實現中,您必須手動取消訂閱該事件。

第三個也是最後一個是MVVMLight庫和它的Messenger類。

正如你可以看到所有這些實現使用Singleton模式來保存訂閱者。

第二部分

第二部分是導航。最簡單的方法是使用Page navigation基礎結構。但在MVVM世界中,我們有許多不同的導航概念。

使用導航抽象的主要目的是將導航邏輯從具體視圖呈現技術(WPF,Silverlight,WinRT,Xamarin)中分離出來。

例如,在Microsoft Prism中,我們可以使用區域和RegionManager來瀏覽視圖和窗口。這是一個非常笨重的導航框架,只有一篇文章後很難理解這個概念。

MVVM Light也有自己的navigation mechanism

對於我的項目,我使用我自己的導航實現Workspaces。它是一種混合機制,它結合了來自Prism的.net和Regions概念的頁面導航原理。

結論

這個職位是不是一個回答您的問題。但是我希望能夠幫助你理解MVVM的概念。

正如你可以看到上面有許多MVVM的框架包含基礎設施(不僅Messenger和的NavigationService,也基本指令的實現,PopupService,轉換器,INotifyPropertyChanged -helpers和base ViewModel實現)來實現應用程序中的典型場景。

+0

您的回答非常有用,非常感謝! – Prince

+1

使用Prism的PubSubEvents時,您不必取消訂閱,除非您將'keepSubscriberReferenceAlive'訂閱爲'true'。當Prism設置爲false時,它將使用弱事件。對於棱鏡5和6來說這是真實的。不知道該框架的舊版本 – Tseng

相關問題