簡體   English   中英

WPF:在 MVVM 中管理窗口(打開、關閉等)?

[英]WPF: Managing windows (opening, closing, etc...) in MVVM?

我在很多地方讀到過它。 大多數人都指的是這兩個鏈接:

我不明白他們中的任何一個。 說到 MVVM,我是初學者。 當談到 MVVM 中的窗口操作時,有些人會提到控制器。 這些是什么以及它們是如何實施的? 按照書本,MVVM 由模型、視圖模型和視圖組成——控制器從哪里來?

如果有人可以提供以下用例的示例,那將是非常棒的(對於所有剛開始使用這個的人,就像我一樣):

  1. 先決條件:打開一個窗口。
  2. 用戶單擊一個按鈕。
  3. 新窗口打開,一些數據被傳遞到那個窗口,即一些字符串。
  4. 關閉新窗口(或單擊按鈕)並將一些數據傳遞到第一個窗口。
  5. 傳遞的數據改變了窗口上的某些內容。

ViewModel 到 ViewModel 的通信通常由事件聚合器模式的實現來處理。

MVVM Light 使用Messenger類,Prism 有另一種實現,但基本上這是一種在視圖模型之間發送消息而無需耦合的方法。

有一些示例和描述用法的文章 我建議看一看。

關於 WPF 中的控制器,我不知道。

關於這個例子:

-我有一個帶有 WindowsViewModel 的 Windows。 這個類應該有一個綁定到按鈕的命令。

-用戶點擊按鈕。 執行命令。

-命令打開一個新窗口。

在這里您應該創建對話框視圖模型,並且您應該以某種方式創建窗口。 或者使用 ViewModel 創建 Window,但 ViewModel 不應該對 View 了解太多,否則無法測試。

我們使用這樣的東西是因為我們有一些要求,但它可能會簡單得多,碰巧這是我手頭唯一的例子:

bool? ShowDialogImpl<TViewModel>(Action<TViewModel> setup) where TViewModel : ViewModel
{
    return (bool?)DispatcherHelper.UIDispatcher.Invoke(
        (Func<bool?>)(() =>
        {
            var viewModel = viewModelFactory.Get<TViewModel>();
            viewModel.ViewService = this;
            setup(viewModel);
            var window = new Window
            {
                Owner = this,
                SizeToContent = SizeToContent.WidthAndHeight,
                WindowStartupLocation = WindowStartupLocation.CenterOwner,
                Content = ViewFactory.CreateView<TViewModel>(),
                DataContext = viewModel,
                WindowStyle = WindowStyle.ToolWindow,
                ShowInTaskbar = false
            };
            window.SetBinding(TitleProperty, new Binding("Title"));
            openDialogs.Push(window);
            window.Activated += (sender, args) => window.SizeToContent = SizeToContent.Manual;
            var result = window.ShowDialog();
            openDialogs.Pop();
            viewModelFactory.Release(viewModel);
            return result;
        }));
}

基本上:我們創建一個窗口和一個視圖模型。 視圖模型是使用容器從工廠創建的。 setup Action 委托是我們數據的入口點。

  • 溝通:

第一個窗口是網格,第二個對話框用於編輯網格的數據。 在 Windows 中,我們有:

messenger.Register<EntityUpdated<FooClass>>(this, message => UpdateItem(message.Entity));

在對話框中:

messenger.Send(new EntityUpdated<FooClass>(subject));

這樣,我們就知道何時在編輯對話框中更新了某些內容以刷新網格。

希望這對你有幫助:)

如果您不打算允許用戶在兩個窗口都打開時來回切換(即第一個打開第二個,第二個必須關閉才能返回到第一個),您可以簡單地設置兩個窗口的 viewmodel 到同一個 viewmodel 實例,並將第二個窗口打開為模態,並且您來回傳遞的字符串只是視圖模型的屬性,數據綁定到視圖中的某些內容。

暫無
暫無

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

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