Page.OnAppearing中的Xamarin.Forms Page.DisplayAlert [英] Xamarin.Forms Page.DisplayAlert in Page.OnAppearing

查看:366
本文介绍了Page.OnAppearing中的Xamarin.Forms Page.DisplayAlert的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法在Xamarin.Forms PageOnAppearing回调中显示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.GetItemsAsyncawait 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 awaited 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆