2014-02-14 56 views
4

我知道有幾個類似於這個問題的問題,但是我還沒有完全找到明確的答案。我正在嘗試使用MVVM,並儘可能保持純粹的東西,但不確定在堅持這種模式的情況下如何去啓動/關閉窗口。如何管理MVVM中的多個窗口

我原來的想法是數據綁定命令ViewModel觸發代碼來啓動一個新的視圖,與視圖的DataContext然後設置爲它的ViewModel通過XAML。但這違反了純MVVM我認爲...

經過一些谷歌搜索/閱讀的答案我遇到了WindowManager的概念(如在CaliburnMicro),現在如果我要在vanilla MVVM項目中實現其中的一個,確實這與我的ViewModels?或者只是在我的應用程序的核心?我目前正在將我的項目分成Model裝配/項目,ViewModel裝配/項目和View裝配/項目。這是否應該進入另一個「核心」程序集?

對於我的下一個問題(與上述內容有些關係),我如何從MVVM的角度啓動我的應用程序?最初,我會從App.xaml啓動我的MainView.xaml,並且XAML中的DataContext將附加指定的ViewModel。如果我添加一個WindowManager,這是我的應用程序啓動的第一件事情嗎?我是否在App.xaml.cs的背後執行此操作?

+0

好的問題。對於啓動,我通常通過後面的app.xaml.cs代碼引導所有的東西,但它總是讓我覺得有點......髒。 – hschne

+0

爲了使用MVVM風格的幾個窗口,你可以看到我最近的[回覆](http://stackoverflow.com/questions/20242817/resolving-wpf-windows-in-structure-map/21763694#21763694)到這個話題。 –

回答

2

那麼它主要取決於你的應用程序的樣子(即同時打開多少個窗口,模式窗口或沒有......等)。

我給的一般建議是不是試着做「」MVVM;我經常閱讀「應該有零代碼」等等,我不同意。

我目前正在將我的項目分解成一個模型組件/項目, ViewModel組件/項目和視圖組件/項目。是否應該將 轉換爲不同的「核心」程序集?

分離的意見和的ViewModels成不同的組件是可以做,以確保你永遠不會引用關係到您的視圖模型視圖的東西是最好的事情。你會很好的與這個強大的分離。

使用兩個不同的組件分離模型與ViewModel可能是一個好主意,但這取決於你的模型是什麼樣子。我個人喜歡3層架構,所以通常我的模型是WCF客戶端代理,並確實存儲在他們自己的程序集中。

無論如何,「核心」程序集總是一個好主意(恕我直言),但只是公開可用於應用程序所有層的基本實用程序方法(如基本擴展方法等) 。

現在你有關於視圖的問題(如何顯示它們......等),我會說做簡單。我個人喜歡在視圖的代碼隱藏中實例化ViewModel。我也經常在我的ViewModel中使用事件,所以關聯的視圖會被通知它應該打開另一個視圖。

例如,情景你有一個主窗口應該顯示一個子窗口時,一個按鈕,用戶點擊:

// Main viewModel 
public MainViewModel : ViewModelBase 
{ 
    ... 
    // EventArgs<T> inherits from EventArgs and contains a EventArgsData property containing the T instance 
    public event EventHandler<EventArgs<MyPopupViewModel>> ConfirmationRequested; 
    ... 
    // Called when ICommand is executed thanks to RelayCommands 
    public void DoSomething() 
    { 
     if (this.ConfirmationRequested != null) 
     { 
      var vm = new MyPopupViewModel 
      { 
       // Initializes property of "child" viewmodel depending 
       // on the current viewModel state 
      }; 
      this.ConfirmationRequested(this, new EventArgs<MyPopupViewModel>(vm)); 
     } 
    } 
} 
... 
// Main View 
public partial class MainWindow : Window 
{ 
    public public MainWindow() 
    { 
     this.InitializeComponent(); 

     // Instantiates the viewModel here 
     this.ViewModel = new MainViewModel(); 

     // Attaches event handlers 
     this.ViewModel.ConfirmationRequested += (sender, e) => 
     { 
      // Shows the child Window here 
      // Pass the viewModel in the constructor of the Window 
      var myPopup = new PopupWindow(e.EventArgsData); 
      myPopup.Show();   
     }; 
    } 

    public MainViewModel ViewModel { get; private set; } 
} 

// App.xaml, starts MainWindow by setting the StartupUri 
<Application x:Class="XXX.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      ... 
      StartupUri="Views/MainWindow.xaml"> 
+0

我一直傾向於在我的視圖背後的代碼中這樣做,因爲它有效地控制了UI,所以代碼應該與UI的其餘部分一起使用。然而,我一直在迴避,因爲「純粹」沒有隱瞞心態。這可能是我的方式取決於我得到的替代答案。 – danbroooks