【问题标题】:How does a toolbar button know to await?工具栏按钮如何知道等待?
【发布时间】:2017-10-20 12:02:22
【问题描述】:

如果我有这个...

<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();
}

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

【问题讨论】:

    标签: .net xamarin


    【解决方案1】:

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

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

    【讨论】:

    • 那么,是同步调用的?
    • 这应该会给你一些看法:stackoverflow.com/questions/37419572/…
    • 我没有看到相关性。
    • 我添加了一条附加评论。还有很多关于 async/await 如何工作的详细文档。
    【解决方案2】:

    没有,您需要使用提供异步命令的 3rd 方库。我个人喜欢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();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2010-10-01
      • 1970-01-01
      相关资源
      最近更新 更多