簡體   English   中英

在 ShowDialog 之后立即從 ViewModel 執行操作

[英]Do an action from ViewModel right after ShowDialog

我有一個這樣的ViewModel

public class WelcomeWindowVm : ViewModel
{
    private ViewModel view;

    public WelcomeWindowVm(){
        this.View = new LoginVm() { 
            Completed += (o, e) => {
                this.View = new OtherVm(e.User){ 
                    Completed += (o, e) =>; // and so on
                } 
            }
        };
    }

    public ViewModel View {
        get {
            return this.view;
        }

        set {
            this.view = value;
            this.OnPropertyChanged(nameof(this.View));
        }
    }
}

LoginVm是另一個 Viewmodel,它的 Completed 事件在其上的命令完成時觸發(該事件僅在使用正確的登錄憑據時觸發)。 OtherVm是另一個 vm,它的完成事件因任何原因被觸發。

我使用DataTemplate呈現View 例如:

<Window.Resources>   
   <DataTemplate DataType="vm:LoginVm">
         Textboes and buttons here
    </DataTemplate>
    <DataTemplate DataType="vm:OtherVm">
        ...
    </DataTemplate>
</Window.Resources>
<ContentControl Content={Binding View} />

此窗口的 DataContext 設置為上面的WelcomeWindowVm類,在ShowDialog之前。

這很好用。 當使用 ShowDialog 顯示窗口時,會顯示LoginVm 然后,當OtherVm任何任務完成時,OtherVm,依此類推。

現在我想到了將 Completion 的內容轉換為 Async/await 模式。 LoginVm 現在看起來像這樣:

public LoginVm{
    ...
    private TaskCompletionSource<User> taskCompletionSource = new TaskCompletionSource<User>();
    ...
    // This is the Relay command handler
    public async void Login()
    {
        // Code to check if credentials are correct
        this.taskCompletionSource.SetResult(this.user);
        // ...
    }

    public Task<User> Completion(){
        return this.taskCompletionSource.Task;
    }
}

取而代之的是:

public LoginVm{
    public event EventHandler<CustomArgs> Completed;

    // This is the Relay command handler
    public async void Login()
    {
        // Code to check if credentials are correct
        OnCompleted(this.user);
        // ...
    }
}

這樣我就可以這樣使用它:

public WelcomeWindowVm(){
    var loginVm = new LoginVm();
    this.View = new LoginVm();
    User user = await loginVm.Completion();

    var otherVm = new OtherVm(user);
    this.View = otherVm;
    Whatever wev = await otherVm.Completion();

    //And so on
}

但是我不能在構造函數中使用 await ,即使我為此使用了異步方法,自從ShowDialog阻塞以來,在調用ShowDialog之后我將如何在另一個類中調用它?

我認為使用async void會起作用。 但據我所知,除非我在事件處理程序中使用它,否則應該避免它。

也許使用async Task方法但不await它?

你可以這樣做:

    public WelcomeWindowVm() {
        var loginVm = new LoginVm();
        this.View = loginVm;
        loginVm.Completion().ContinueWith(loginCompleted =>
        {
            var otherVm = new OtherVm(loginCompleted.Result);
            this.View = otherVm;
            otherVm.Completion().ContinueWith(whateverCompleted =>
            {

            });
        });
    }

暫無
暫無

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

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