为什么DisplayAlert在构造函数中不起作用?

时间:2018-11-16 23:59:47

标签: xamarin.forms

我的Xamarin.Forms应用程序中存在一些与在页面构造函数中调用async方法有关的问题,因此当我测试某些东西以找出刚发现DisplayAlert方法不起作用的原因时,在页面构造函数中,所以我想知道为什么会这样吗?

这是我的代码:

    public MainPage ()
    {
        InitializeComponent ();
        DisplayAlert("An alert", "Why I don't show up?", "Ok");
    }

并且我还尝试调用具有async方法但又无法正常工作的DisplayAlert方法,这是代码:

    public MainPage ()
    {
        InitializeComponent ();
        Async_Function_Has_DisplayAlert();
    }
    async void Async_Function_Has_DisplayAlert()
    {
        // I tried both and neither of them worked
        await DisplayAlert("An alert", "Why I don't show up?", "Ok");
        await Task.Run(()=> DisplayAlert("An alert", "Why I don't show up?", "Ok"));
    }

那么有人可以解释为什么发生这种情况吗?

3 个答案:

答案 0 :(得分:0)

通常,您不应从构造函数中调用诸如DisplayAlert()之类的可等待方法。 您可以做的是有一个返回void的方法(仍然不是最佳实践),并从构造函数中调用该方法。

尝试后,请调整我的建议。 我使用Device.Timer延迟了警报。 我认为某些组件在尝试调用之前尚未完成加载(在本例中为DisplayAlert)。

public MainPage()
    {
        InitializeComponent();
        Device.StartTimer(TimeSpan.FromSeconds(4), () =>
        {
            ShowMessage();
            return false; // True = Repeat again, False = Stop the timer
        });
    }
    public async void ShowMessage()
    {

        await DisplayAlert("Alert", "I show here", "OK");

    }

enter image description here

答案 1 :(得分:0)

对于构造函数中发生的事情似乎有一个误解。 构造函数只需创建一个新的Page类。

CustomMainPage mainpage = new CustomMainPage();
(App.Current as App).MainPage = new NavigationPage(mainpage);

因此,在将主页类添加到NavigationPage之前,所发生的一切只是CustomMainPage类已初始化,并准备将其插入适当的容器中。 但是,创建新页面后,屏幕上还没有实际的UI。例如,主页对象不会设置宽度或高度,还没有完成布局,等等。 如果您运行与UI相关的任务(例如呈现警报),那么那里就没有简单的基础,可以做任何合理的事情。

当然,您已经可以从构造函数中设置主页的成员,例如将标签或按钮设置为某些值,颜色,样式或所需的任何内容,但这些功能在那时不起作用。 在对页面进行布局和显示时,所有这些值都将被考虑在内,但在构造函数中将不会发生任何事情。

但是,回到您的问题所在:您似乎想通知用户初始化过程中出现了问题。

我看到解决该问题的两种方法:

  1. 在初始化视图之前,请先检查页面上或代码中的前提条件,并显示正在初始化页面的页面或类中的警报。
  2. 在页面类中创建一个私有变量,如果出现问题,可以在页面构造函数中设置该私有变量。这可能是一个简单的bool标志,一个包含错误消息的字符串,一个枚举或任何适合您需要的字符串。然后重写OnAppearing()方法,检查先前设置的标志,并根据该标志的值调用DisplayAlert。

如果您希望页面上具有任何交互性,则应考虑Jason对您的问题的评论,并在OnAppearing中实施它,因为一旦页面完全布局并显示在屏幕上,就会调用此方法。

答案 2 :(得分:0)

杰森推荐的示例代码

public async void ShowMessage()
    {
        await DisplayAlert("Alert", "I show here", "OK");
    }
    protected override void OnAppearing()
    {
        ShowMessage();
    }