簡體   English   中英

如何在MVVM中管理多個窗口

[英]How to manage multiple windows in MVVM

我知道有幾個類似於這個的問題,但是我還沒有找到明確的答案。 我正試圖深入了解MVVM,並盡可能保持純粹的東西,但不確定如何在堅持模式的同時啟動/關閉窗口。

我最初的想法是使用ViewModel觸發代碼來啟動新View的數據綁定命令,然后View的DataContext通過XAML設置為它的ViewModel。 但這違反了我認為的純MVVM ......

在一些谷歌搜索/閱讀答案之后,我遇到了一個WindowManager的概念(就像在CaliburnMicro中一樣),現在如果我要在一個vanilla MVVM項目中實現其中一個,那么我的ViewModels是否可以使用它? 或者只是我申請的核心? 我目前正在將我的項目分離為Model程序集/項目, ViewModel程序集/項目和View程序集/項目。 這應該進入一個不同的“核心”組裝嗎?

這導致了我的下一個問題(與上述有關),如何從MVVM的角度啟動我的應用程序? 最初我會從App.xaml啟動我的MainView.xaml,而XAML中的DataContext將附加指定的ViewModel。 如果我添加一個WindowManager ,這是我的應用程序首先啟動的嗎? 我是否從App.xaml.cs的代碼中執行此操作?

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

我要給出的一般建議是不要嘗試做“ 純粹的 ”MVVM; 我經常閱讀諸如“應該存在零代碼”之類的內容......等等,我不同意。

我目前正在將我的項目分離為模型程序集/項目,ViewModel程序集/項目和View程序集/項目。 這應該進入一個不同的“核心”組裝嗎?

將視圖和ViewModel分離到不同的程序集中是您可以做的最好的事情,以確保您不會在viewModel中引用與視圖相關的內容。 這種強烈的分離你會沒事的。

使用兩個不同的程序集從ViewModel中分離模型也是一個好主意,但這取決於模型的外觀。 我個人喜歡3層架構,所以通常我的模型是WCF客戶端代理,並且確實存儲在它們自己的程序集中。

無論如何,“核心”程序集總是一個好主意(恕我直言),但只是為了公開可以在應用程序的所有層中使用的基本實用程序方法(例如基本擴展方法等等)。

現在,關於觀點的問題(如何展示它們等等),我想說的很簡單 我個人喜歡在我的Views的代碼隱藏中實例化我的ViewModel。 我還經常在我的ViewModel中使用事件 ,因此通知關聯視圖它應該打開另一個視圖。

例如,當用戶單擊按鈕時,您有MainWindow應該顯示子窗口的場景:

// 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">

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM