WPF -使用MVVF命令关闭运行新线程的窗口
本文关键字:线程 窗口 新线程 运行 使用 MVVF 命令 WPF | 更新日期: 2023-09-27 18:11:55
设置
我有一个窗口和视图模型。视图模型有一个执行Task
的命令。当任务完成时,我想要的效果是窗口关闭。
最可接受的(最佳实践)方法是什么?
我倾向于认为Dispatcher。调用很糟糕,但这是一个没有意义的问题,因为视图模型没有对窗口或其调度程序的引用。
edit:澄清一下,这个窗口属于UI线程。该命令本身调用包装器来执行异步http请求(它返回一个任务)。该命令可以附加一个ContinueWith。
我不想将视图模型与视图紧密耦合(例如通过将Window传递给视图模型)
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中(无论是在async进程的回调方法中,还是在没有运行async的命令方法的末尾):
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
事件,然后完成。