Page.OnAppearing中的Xamarin.Forms Page.DisplayAlert [英] Xamarin.Forms Page.DisplayAlert in Page.OnAppearing
问题描述
我无法在Xamarin.Forms Page
的OnAppearing
回调中显示DisplayAlert
弹出窗口.到目前为止,这是我尝试过的:
I am unable to get a DisplayAlert
popup to show within the OnAppearing
callback of a Xamarin.Forms Page
. Here is what I have tried so far:
protected override void OnAppearing()
{
base.OnAppearing();
this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}
考虑DisplayAlert
从技术上讲是一个async
函数,返回一个Task
,我也尝试了以下方法:
Considering DisplayAlert
is technically an async
function, returning a Task
, I have also tried the following:
protected async override void OnAppearing()
{
base.OnAppearing();
await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}
但是,两者似乎都不起作用.我的猜测是,使OnAppearing
完全成为async
并没有多大意义,因为它不会返回Task
,因此对于调用框架.在这种情况下,DisplayAlert
的扩展名相同.因此,一方面我根本不希望这能完全起作用,但是如果我错了,是否可以在OnAppearing
中使用DisplayAlert
?
However, neither seem to work. My guess is it doesn't really make much sense to make OnAppearing
to be async
at all, since it does not return a Task
, and so this turns into a fire-and-forget situation with respect to the calling framework. Same by extension goes for DisplayAlert
in this context. So on the one hand I don't really expect this to work at all, but in case I'm wrong, is it possible to use DisplayAlert
in OnAppearing
?
更新
似乎我未能提供一些背景信息.我正在使用Xamarin.Forms Shell模板;尽管我已经在初始模板上开发了一些内容,所以在这一点上很难说Shell本身在多大程度上做出了贡献.另外,我的主要目标平台是Android.
Seems I failed to provide some context. I'm working from an Xamarin.Forms Shell template; though I have already developed some past the initial template, so it's hard to say at this point to what extent the Shell itself contributes at all. Also, my main target platform is Android.
总而言之,我能够启动一个空白的应用程序模板,并在其他全新的MainPage
中尝试上述代码-都可以正常工作.我仍然不知道为什么它们在我的实际应用程序上下文中不起作用,因此我将在那里进行一些挖掘并报告所有发现.
That all being said, I was able to start a blank app template and try the above code in the otherwise fresh MainPage
-- both worked fine. I still do not know why they do not work in my actual application context, so I am going to do some digging there and report back any findings.
推荐答案
将我的小实验再进一步一步,并尝试了基本的Shell模板应用程序.
Took my little experiment one step further and tried the basic Shell template app.
将OP样本DisplayAlert
代码添加到后面的主要ItemsPage
代码中不起作用.如果我这样做了,
Adding the OP sample DisplayAlert
code to the main ItemsPage
codebehind did not work. If I did this,
protected async override void OnAppearing()
{
base.OnAppearing();
if (viewModel.Items.Count == 0)
viewModel.LoadItemsCommand.Execute(null);
await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}
项目将加载,但不会显示对话框.相反,如果我将对话框上移,
the items would load but no dialog would show. If instead I moved the dialog up,
protected async override void OnAppearing()
{
base.OnAppearing();
await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
if (viewModel.Items.Count == 0)
viewModel.LoadItemsCommand.Execute(null);
}
对话框将不会显示,也不会加载项目.因此,异步执行死掉和/或徘徊在空中的一大桶中.
the dialog would not show nor would the items load. So the async execution died and/or wandered off into the great big bit bucket up in the sky.
然后我尝试将DisplayAlert
示例添加到AppShell
主页中,只是发现OnAppearing
替代根本没有被调用给Shell
类.以下打开的Shell问题已确认了这一点: [错误] Shell-OnAppearing不执行
#6486 .
I then tried adding the DisplayAlert
sample to the main AppShell
page, only to find the OnAppearing
override does not get called at all for the Shell
class. This was confirmed by the following open Shell issue: [Bug] Shell - OnAppearing not executing
#6486.
最后,作为最后的扩展,我尝试将对DisplayAlert
的调用破解到ItemsPage.OnAppearing
中的LoadItemsCommand
执行的异步回调中.有点讨厌,因为它将视图传递到了视图模型中,这首先直接抵制了良好的MVVM-
Finally, just as a final stretch, I tried hacking a call to DisplayAlert
into the async callback executed by LoadItemsCommand
in ItemsPage.OnAppearing
. A bit nasty since it's passing the view into the view-model, which is directly against good MVVM in the first place --
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;
}
}
别扔石头.
这似乎没有任何更好的结果.就像直接在页面的OnAppearing
中调用DisplayAlert
时一样,执行只是午休.绑定到IsBusy
标志的微调框永远不会停止,因此这表明finally
块甚至从未执行过.
This didn't seem to have any better results. Just like when calling DisplayAlert
directly in the page's OnAppearing
, the execution just took a lunch break. The spinner bound to the IsBusy
flag never stopped, so that indicates the finally
block never even got executed.
至此,我的一般理解是,目前可以通过Shell的ContentPage
执行的异步操作类型存在一些限制.在本实现中,即使对DataStore.GetItemsAsync
的await
ed调用也不是真正异步的,因此,我怀疑在给定真正的异步数据库连接的情况下,它是否真的可以工作.我已经能够在普通事件处理程序的上下文中使DisplayAlert
工作,因此我认为问题的范围是OnAppearing
期间发生的初始化逻辑以及最终直接调用或调度的问题.其中大部分只是观察性推测,但除非有人可以提供更完整的分析,否则我可能会将其作为错误转发.
My general understanding at this point is that there is currently some limitation in the type of async operations that can be done from a Shell's ContentPage
. Even the await
ed call to DataStore.GetItemsAsync
is not truly asynchronous in this implementation, so I somewhat doubt it would actually work given a real, asynchronous database connection. I have been able to get DisplayAlert
working in the context of a normal event handler, so I think the issue is scoped to whatever initialization logic goes on during OnAppearing
and whatever it ends up directly calling or scheduling. Much of this is just observational speculation, but I may forward this on as a bug, unless someone can offer a more complete analysis.
这篇关于Page.OnAppearing中的Xamarin.Forms Page.DisplayAlert的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!