c# - Page.OnAppearing 中的 Xamarin.Forms Page.DisplayAlert
问题描述
我无法在Xamarin.FormsDisplayAlert
的回调中显示弹出窗口。这是我到目前为止所尝试的:OnAppearing
Page
protected override void OnAppearing()
{
base.OnAppearing();
this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}
考虑到DisplayAlert
技术上是一个async
函数,返回 a Task
,我还尝试了以下方法:
protected async override void OnAppearing()
{
base.OnAppearing();
await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}
但是,两者似乎都不起作用。OnAppearing
我的猜测是,它根本没有多大意义async
,因为它不返回 a Task
,所以这变成了关于调用框架的即发即弃的情况。DisplayAlert
在这种情况下,同样的扩展也适用。所以一方面我真的不希望这会起作用,但万一我错了,是否可以使用DisplayAlert
in OnAppearing
?
更新
似乎我未能提供一些背景信息。我正在使用 Xamarin.Forms Shell 模板;虽然我已经开发了一些超出初始模板的内容,但目前很难说 Shell 本身在多大程度上做出了贡献。另外,我的主要目标平台是Android。
话虽如此,我能够启动一个空白的应用程序模板并在其他新鲜的情况下尝试上面的代码MainPage
——两者都工作得很好。我仍然不知道为什么它们在我的实际应用程序环境中不起作用,所以我将在那里进行一些挖掘并报告任何发现。
解决方案
让我的小实验更进一步,并尝试了基本的 Shell 模板应用程序。
将 OP 示例DisplayAlert
代码添加到主代码ItemsPage
隐藏中不起作用。如果我这样做,
protected async override void OnAppearing()
{
base.OnAppearing();
if (viewModel.Items.Count == 0)
viewModel.LoadItemsCommand.Execute(null);
await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}
项目将加载,但不会显示任何对话框。相反,如果我将对话框向上移动,
protected async override void OnAppearing()
{
base.OnAppearing();
await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
if (viewModel.Items.Count == 0)
viewModel.LoadItemsCommand.Execute(null);
}
对话框不会显示,项目也不会加载。因此,异步执行死亡和/或徘徊在天空中的大桶中。
然后我尝试将DisplayAlert
示例添加到AppShell
主页,只是发现该类OnAppearing
根本没有调用覆盖Shell
。以下打开的 Shell 问题证实了这一点: [Bug] Shell - OnAppearing not execution #6486。
最后,作为最后的延伸,我尝试将调用入侵到inDisplayAlert
执行的异步回调LoadItemsCommand
中ItemsPage.OnAppearing
。有点讨厌,因为它将视图传递到视图模型中,这首先直接违背了良好的 MVVM ——
async Task ExecuteLoadItemsCommand(ItemsPage view)
{
if (IsBusy)
return;
IsBusy = true;
try
{
Items.Clear();
var items = await DataStore.GetItemsAsync(true);
foreach (var item in items)
{
Items.Add(item);
}
await Device.InvokeOnMainThreadAsync(async () =>
await view.DisplayAlert("Alert", "Consider yourself alerted", "OK"));
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
不要用石头砸我。
这似乎没有更好的结果。就像DisplayAlert
直接在页面中调用时一样OnAppearing
,执行只需要午休。绑定到IsBusy
标志的微调器从未停止,因此这表明该finally
块甚至从未被执行。
在这一点上,我的一般理解是,目前可以从 Shell 的ContentPage
. 在这个实现中,即使对await
ed 的调用DataStore.GetItemsAsync
也不是真正的异步,所以我有点怀疑它在给定一个真正的异步数据库连接的情况下是否真的有效。我已经能够DisplayAlert
在普通事件处理程序的上下文中工作,所以我认为这个问题的范围是任何初始化逻辑在期间发生的OnAppearing
任何事情,以及它最终直接调用或调度的任何事情。其中大部分只是观察性推测,但我可能会将其作为错误转发,除非有人可以提供更完整的分析。
更新(用于关闭、强迫症、文档等)
正如评论所示,我使用的 Xamarin.Forms 版本 (4.2.0) 有一个错误,该错误已在更高版本中修复。
推荐阅读
- stripe-payments - 条带集成 - 前端和后端的最佳方法
- kubernetes - 在kubernetes集群中登录harbor 2.0.1时禁止403
- django - 每次我在 django 项目中更改产品字段时都会更新日期
- javascript - CSS 模块被捆绑,但没有使用使用 Rollup underhood 的 TSDX 引用
- deep-learning - 当使用 OpenAI Gym 的跳帧包装器时,np.max 行的目的是什么?
- docker - 有没有办法仅在图像中有新更改时将新标签推送到注册表?
- encoding - 编码时如何让FFMPEG使用更多GPU
- amazon-web-services - API Gateway URI 版本控制
- aws-lambda - 创建 Cloudformation 堆栈后如何触发 lambda
- reactjs - 在 App.js 组件中使用 React 监听本地存储变化