问题
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");
}
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");
}
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
?
Update
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.
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.
回答1:
Took my little experiment one step further and tried the basic Shell template app.
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.
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.
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;
}
}
Don't stone me.
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.
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.
来源:https://stackoverflow.com/questions/62431815/xamarin-forms-page-displayalert-in-page-onappearing