簡體   English   中英

WPF-使用運行新線程的MVVF命令關閉窗口

[英]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.

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