我正在嘗試關閉它的ViewModel窗口。我正在使用MVVM模式。我已經厭倦了讓窗戶使用;WPF:從MVVM關閉一個窗口
Window parentWindow = Window.GetWindow(this);
但我不能這樣做,我如何獲得ViewModel的窗口,所以我能夠關閉窗口。我希望能夠在代碼中做到這一點。
你能在代碼中找到父窗口嗎?
我正在嘗試關閉它的ViewModel窗口。我正在使用MVVM模式。我已經厭倦了讓窗戶使用;WPF:從MVVM關閉一個窗口
Window parentWindow = Window.GetWindow(this);
但我不能這樣做,我如何獲得ViewModel的窗口,所以我能夠關閉窗口。我希望能夠在代碼中做到這一點。
你能在代碼中找到父窗口嗎?
讓ViewModel這樣做,如果確實需要的話。
模型舉例說,有不再有效數據
將該信息傳遞到視圖模型
視圖模型識別,它可以不再顯示任何
,然後關閉窗口。
空視圖是表達的正常方式,有沒有更多的數據
對不起,我有點困惑,我正在試圖從ViewModel中找到關閉它的窗口? – user101010101
在MVVM的常規用法中ViewModel和View之間沒有直接鏈接,即不能在viewmodel中寫入類似「myWindow.Close()」的東西。但是,當然,你可以有這樣的事情。本文將引導你http://asimsajjad.blogspot.de/2010/10/closing-view-from-viewmodel-using-mvvm.html –
您可以在視圖模型定義操作
public Action CloseAction { get; set; }
然後,在窗口中(例如在DataContextChanged僅)你可以設置這個動作:
((IClosable)viewModel.Content).CloseAction =() => System.Windows.Application.Current.Dispatcher.Invoke(Close());
那麼,這一切是一個更大的依賴注入模式的一部分,但是基本原理是在這裏... 下一頁,您有理由需要從VM調用該操作。
ViewModels
不應以任何方式引用View
,包括在MVVM中關閉窗口。
相反,View
和ViewModel
之間的通信通過某種事件或消息系統的典型的做法,如Microsoft Prism's EventAggregator
,或MVVM Light's Messenger
例如,View
應訂閱監聽CloseWindow
類型的事件消息,當它收到其中一條消息時,它應該關閉。然後ViewModel
只要在想要告知View
關閉時隨時廣播CloseWindow
消息。
有一個在MVVM事件系統,以及一些例子的簡要概述,在我的博客文章Communication between ViewModels如果你有興趣
有這個任務,不打破MVVM,一個行爲的有用行爲,與Expression Blend 3一起引入,允許視圖掛鉤到完全在ViewModel中定義的命令中。
這種現象說明了一個簡單的技術,以允許 視圖模型來管理一個 模型 - 視圖 - 視圖模型應用的視圖的closing事件。
這允許您在視圖(用戶控件)中掛接一個行爲,該行爲將提供對控件窗口的控制,允許ViewModel 控制是否可以通過標準ICommands關閉該窗口。
Using Behaviors to Allow the ViewModel to Manage View Lifetime in M-V-VM
http://gallery.expression.microsoft.com/WindowCloseBehavior/
是在視圖模型引用的觀點是不是最好的做法。爲什麼? 因爲當你單元測試你的viewmodel它需要你實例化視圖,對於小視圖來說不會那麼困難,但是對於具有複雜樹視圖的複雜視圖?那不會很好。
對我來說,通過視圖模型構造函數傳遞IInputElement
是最簡單的方法。 IInputElement
的好處是路由事件主幹,它具有路由事件所需的RaiseEvent
和AddHandler
方法。因此您可以自由地在應用程序中將任何視圖或視圖模型直接冒泡/隧道/指定事件,而無需額外的庫。
這裏是我的視圖模型簡化代碼,但請記住這種技術只對視圖第一種方法
public class MyViewModel : INotifyPropertyChanged
{
public static readonly RoutedEvent RequestCloseEvent = EventManager.RegisterRoutedEvent("RequestClose",
RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyViewModel));
private IInputElement dispatcher;
public MyViewModel(IInputElement dispatcher)
{
this.dispatcher = dispatcher;
}
public void CloseApplication()
{
dispatcher.RaiseEvent(new RoutedEventArgs(RequestCloseEvent));
}
}
對你的觀點只是
DataContext = new MyViewModel(this)
//notice "this" on the constructor
和根視圖(窗口)工作您的應用只需
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AddHandler(MyViewModel.RequestCloseEvent, new RoutedEventHandler(onRequestClose));
}
private void onRequestClose(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("Are you sure you want to quit?", "Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
Close();
}
}
}
因爲IInputElement
是接口而不是類,您可以輕鬆地創建一個模擬類單元測試
var target = new MyViewModel(new DispatcherMock)
,或者你可以使用Mock庫像RhinoMocks
進一步閱讀,你可以瞭解更多關於如何使用Routed Event
可能重複: http://stackoverflow.com/questions/4376475/wpf-mvvm-how-to-close-a-window –
我想發現,調用窗口的'關閉()'來自'ViewModel'的方法不是一個好的做法,並且是可控的對MVVM的想法本身也是如此。爲此目的使用觸發器。 –