[英]WPF - Closing window using MVVF command that runs new thread
設置
我有一個窗口和一個視圖模型。 viewmodel有一個執行Task
的命令。 任務完成后,我希望效果是關閉窗口。
什么是最可接受的(最佳實踐)方法?
我傾向於認為Dispatcher.Invoke很爛而且很糟糕,但這是有爭議的,因為視圖模型沒有對窗口或其調度程序的引用。
編輯:澄清一下,該窗口屬於UI線程。 該命令本身調用包裝程序以執行異步http請求(該請求返回任務)。 該命令可以附加一個ContinueWith。
我不想將viewmodel與視圖緊密耦合(例如,通過將Window傳遞給view模型)
public class Api
{
Task MakeHttpCall();
}
public class ViewModel, DependencyObject
{
private Api _api;
public Task DoHttpCall() { return _api.MakeHttpCall(); }
public MyCommand MyCommandInst { get; private set; }
}
public class MyCommand : ICommand
{
void Execute(object parameter)
{
var viewModel = GetViewModel(parameter);
viewModel.DoHttpCall().ContinueWith( t => HandleCompletionAndSomehowTriggerWindowClose(t));
}
}
然后是view.xaml: <Button Command={Binding MyCommandInst} CommandParameter={Binding}>Do Stuff</Button>
我使用MVVM Light來幫助簡化此過程。 ViewModel沒有對View的引用,它只是發布一條要關閉的消息,並且注冊了View以接收那些消息。
在我的視圖背后的代碼中,我訂閱了Messenger服務,如下所示:
public class MyView
{
public MyView()
{
InitializeComponent();
Messenger.Default.Register<NotificationMessage>(this, msg =>
{
if ((msg.Sender == this.DataContext) && (msg.Notification.ToUpper() == "CLOSE"))
this.Close();
});
}
}
然后在ViewModel中(在異步過程中的回調方法中,或者如果未運行異步,則在命令方法的末尾):
Messenger.Default.Send(new NotificationMessage(this, "Close"));
通常,我相信,使用MVVM模式關閉窗口取決於在視圖所預訂的視圖模型上引發某種形式的Close
事件:
public class MyView
{
public MyView(MyViewModel viewModel)
{
this.DataContext = viewModel;
viewModel.Close += (_, __) => Dispatcher.Invoke(this.Close);
}
}
從任務的ContinueWith
操作中引發Close
事件,您就完成了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.