在异步方法返回值之前,从异步方法导航到另一个ContentPage

时间:2017-03-20 16:12:07

标签: c# xamarin.forms async-await content-pages

我需要在此异步方法返回值之前启动另一个ContentPage:

public class GettingCountry : ContentPage
{
    public static List<string> CountriesList = new List<string>();

    MainPage mainPage = new MainPage();
    public async Task<List<RootObject>> FetchAsync(string url)
    {
        string jsonString;
        using (var httpClient = new System.Net.Http.HttpClient())
        {
            var stream = await httpClient.GetStreamAsync(url);
            StreamReader reader = new StreamReader(stream);
            jsonString = reader.ReadToEnd();
        }

        var listOfCountries = new List<RootObject>();

        var responseCountries = JArray.Parse(JObject.Parse(jsonString)["response"]["items"].ToString());

        foreach (var countryInResponse in responseCountries)
        {
            var rootObject = new RootObject((int)countryInResponse["id"], (string)countryInResponse["title"]);

            CountriesList.Add(rootObject.Title);
        }

        //I NEED TO NAVIGATE TO FillingPage() FROM HERE:
        await Navigation.PushAsync(new FillingPage());

        //await Navigation.PushModalAsync(new NavigationPage(new FillingPage()));

        return listOfCountries;
    }

需要启动的页面是:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FillingPage : ContentPage
{
    public FillingPage ()
    {
        GettingCountry gettingCountry = new GettingCountry();

        Label header = new Label
        {
            Text = "Заполните бланк",
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.CenterAndExpand,
            TextColor = Color.Blue
        };

        Entry nameEntry = new Entry()
        {
            Placeholder = "Имя",
        };

        Entry surnameEntry = new Entry()
        {
            Placeholder = "Фамилия"
        };

        Picker countryPicker = new Picker()
        {
            Title = "Страна",
            VerticalOptions = LayoutOptions.CenterAndExpand
        };

        foreach (string country in GettingCountry.CountriesList)
        {
            countryPicker.Items.Add(country);
        }

        SearchBar townSearchBar = new SearchBar()
        {
            Placeholder = "Город",
            SearchCommand = new Command(() =>
            {
            })
        };

        SearchBar universitySearchBar = new SearchBar()
        {
            Placeholder = "Университет",
            SearchCommand = new Command(() =>
            {
            })
        };
        Button myButton = new Button()
       {
           TextColor = Color.Green,
           Text = "Выполнить",
           FontSize = 22
       };

        // Accomodate iPhone status bar.
        this.Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 5);

        // Build the page.
        this.Content = new StackLayout
        {
            Children =
            {
                header,
                nameEntry,
                surnameEntry,
                countryPicker,
                townSearchBar,
                universitySearchBar,
                myButton
            }
        };
    }
}

}

但是,只有当我按下按钮时,此代码await Navigation.PushAsync(new FillingPage());才能正常工作。当我按下按钮时,所需的页面开始很好。但是方法中的相同代码不起作用。我已将其删除了。它转到FillingPage(),但是当我尝试从异步方法内部启动它时,它不会启动它。

1 个答案:

答案 0 :(得分:4)

这可能是因为未在主线程上执行操作。尝试包装代码如下:

Device.BeginInvokeOnMainThread(async () =>
{
    await Navigation.PushAsync(new FillingPage());
}

编辑:在发送私信后,我了解到问题中没有足够的信息来了解真正的问题。应用程序在FetchAsync中调用Application.OnStart并且它根本不属于视图层次结构,因此导航方法不起作用。提供了以下内容:

protected override void OnStart ()
{
    getCountry();
}

private async void getCountry()
{
    var url = "...";
    GettingCountry gettingCountry = new GettingCountry();
    await gettingCountry.FetchAsync(url);
}

GettingCountryContentPage被用作某种数据访问类的,它当前不是用户界面的一部分,因为MainPage被设置为其他内容。快速破解会更像是:

private async void getCountry()
{
    var url = "...";
    GettingCountry gettingCountry = new GettingCountry();
    var data = await gettingCountry.FetchAsync(url);
    await MainPage.Navigation.PushAsync(new FillingPage(data));
 }

我建议另外两个方面来改进。

  1. 考虑重构GettingCountry,因为它不需要是ContentPage
  2. 调查另一个调用,以便不使用async void