在异步方法 returns 值之前从异步方法导航到另一个 ContentPage
Navigate to another ContentPage from async method before the async method returns a value
我需要在此异步方法之前启动另一个 ContentPage returns 值:
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());
只有在我按下按钮时才能正常工作。当我按下一个按钮时,所需的页面会很好地启动。但是方法中的相同代码不起作用。我已经debagged它。它转到 FillingPage()
但当我尝试从异步方法内部启动它时不会启动它。
这可能是操作未在主线程上执行的结果。尝试像这样包装您的代码:
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PushAsync(new FillingPage());
}
编辑: 私信后才知道问题中信息量不够,无法知道真正的问题。该应用程序在 Application.OnStart
中调用 FetchAsync
并且它根本不是视图层次结构的一部分,因此导航方法将不起作用。提供了以下内容:
protected override void OnStart ()
{
getCountry();
}
private async void getCountry()
{
var url = "...";
GettingCountry gettingCountry = new GettingCountry();
await gettingCountry.FetchAsync(url);
}
GettingCountry
是一个 ContentPage
被用作某种数据访问 class,它目前不是 UI 的一部分,因为 MainPage
已设置到别的东西。快速破解更像是:
private async void getCountry()
{
var url = "...";
GettingCountry gettingCountry = new GettingCountry();
var data = await gettingCountry.FetchAsync(url);
await MainPage.Navigation.PushAsync(new FillingPage(data));
}
我建议进一步改进两个方面。
- 考虑重构
GettingCountry
,因为它不需要是 ContentPage
。
- 调查替代呼叫,以便不使用
async void
。
我需要在此异步方法之前启动另一个 ContentPage returns 值:
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());
只有在我按下按钮时才能正常工作。当我按下一个按钮时,所需的页面会很好地启动。但是方法中的相同代码不起作用。我已经debagged它。它转到 FillingPage()
但当我尝试从异步方法内部启动它时不会启动它。
这可能是操作未在主线程上执行的结果。尝试像这样包装您的代码:
Device.BeginInvokeOnMainThread(async () =>
{
await Navigation.PushAsync(new FillingPage());
}
编辑: 私信后才知道问题中信息量不够,无法知道真正的问题。该应用程序在 Application.OnStart
中调用 FetchAsync
并且它根本不是视图层次结构的一部分,因此导航方法将不起作用。提供了以下内容:
protected override void OnStart ()
{
getCountry();
}
private async void getCountry()
{
var url = "...";
GettingCountry gettingCountry = new GettingCountry();
await gettingCountry.FetchAsync(url);
}
GettingCountry
是一个 ContentPage
被用作某种数据访问 class,它目前不是 UI 的一部分,因为 MainPage
已设置到别的东西。快速破解更像是:
private async void getCountry()
{
var url = "...";
GettingCountry gettingCountry = new GettingCountry();
var data = await gettingCountry.FetchAsync(url);
await MainPage.Navigation.PushAsync(new FillingPage(data));
}
我建议进一步改进两个方面。
- 考虑重构
GettingCountry
,因为它不需要是ContentPage
。 - 调查替代呼叫,以便不使用
async void
。