如何知道工具栏按钮等待?

时间:2017-10-20 12:02:22

标签: .net xamarin

如果我有这个......

<ContentPage.ToolbarItems>
    <ToolbarItem  Text = "Done" Clicked="Done_Clicked" />
    <ToolbarItem Text = "Cancel" Clicked="Cancel_Clicked" Priority="1" />
</ContentPage.ToolbarItems>

在背后的代码中......

async void Cancel_Clicked(object sender, EventArgs e)
{
    await Navigation.PopModalAsync();
}

工具栏项如何知道其处理程序是异步的?

2 个答案:

答案 0 :(得分:2)

Cancel_Clicked处理程序返回void,因此您的工具栏项(UI线程)无法知道您的方法是否是异步的。

编辑:
内部方法 PopModalAsync()将以异步方式运行 - 它将在未来的某个时间内完成工作。 Cancel_Clicked()将立即返回,对于UI线程,它是同步操作。

答案 1 :(得分:1)

它没有 ,您需要使用提供异步命令的第三方库。我个人喜欢Nito.Mvvm.Async,它为您提供了一个AsyncCommand,您可以使用它并将您的函数绑定到。异步功能运行时,该按钮将被禁用,并在功能完成后重新启用。

<ContentPage.ToolbarItems>
    <ToolbarItem Text = "Done" Command="{Binding DoneCommand}" />
    <ToolbarItem Text = "Cancel" Command="{Binding CancelCommand}" Priority="1" />
</ContentPage.ToolbarItems>

在您的视图模型中。

public MyViewModel()
{
    CancelCommand = new AsyncCommand(ExecuteCancel);
}

public AsyncCommand CancelCommand {get;}

async Task ExecuteCancel()
{
    await Navigation.PopModalAsync();
}

这是一个更复杂的版本,它禁用取消选项,除非当前正在运行“完成”选项。

<ContentPage.ToolbarItems>
    <ToolbarItem Text = "Done" Command="{Binding DoneCommand}" />
    <ToolbarItem Text = "Cancel" Command="{Binding CancelCommand}" Priority="1" />
</ContentPage.ToolbarItems>

在您的视图模型中。

    public MyViewModel()
    {
        DoneCommand = new AsyncCommand(ExecuteDone);
        CancelCommand = new CustomAsyncCommand(ExecuteCancel, CanExecuteCancel);
        PropertyChangedEventManager.AddHandler(DoneCommand, (sender, e) => CancelCommand.OnCanExecuteChanged(), nameof(DoneCommand.IsExecuting));
        PropertyChangedEventManager.AddHandler(CancelCommand, (sender, e) => CancelCommand.OnCanExecuteChanged(), nameof(CancelCommand.IsExecuting));
    }

    private bool CanExecuteCancel()
    {
        return DoneCommand.IsExecuting && !CancelCommand.IsExecuting;
    }

    public AsyncCommand DoneCommand { get; }
    public CustomAsyncCommand CancelCommand { get; }

    async Task ExecuteDone()
    {
        await ... //Do stuff

    }

    async Task ExecuteCancel()
    {
        await Navigation.PopModalAsync();
    }