Xamarin Forms 在创建时异步填充数据
Xamarin Forms populate data async on create
我有一个绑定到 ViewModel 的 Xamarin 表单。创建此 ViewModel 时,我希望它异步地从数据库中获取数据。我的问题是我不确定如何调用异步方法,因为构造函数无法调用异步方法并且 getter 无法调用异步方法。
我正在为 UI 使用纯 XAML,XAML 是否可以在初始化时调用方法?
我的视图模型:
public class DonorViewModel : BaseViewModel
{
public DonorViewModel (IRepository<Donor> donorRepository)
{
_donorRepository = donorRepository;
}
private string _name;
public string Name {
get {
return _name;
}
set {
if (_name != value) {
_name = value;
OnPropertyChanged ("Name");
}
}
}
private IRepository<Donor> _donorRepository;
private async Task GetName()
{
var donor = await _donorRepository.Get(d => d.Id == 1);
Name = donor.Name;
}
}
我的XAML:
<?xml version="1.0" encoding="UTF-8"?>
<d:ViewPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DonationExample.DonorView"
xmlns:d="clr-namespace:DonationExample;assembly=DonationExample"
x:TypeArguments="local:DonorViewModel"
xmlns:local="clr-namespace:DonationExample">
<ContentPage.BindingContext>
</ContentPage.BindingContext>
<StackLayout Spacing="10"
VerticalOptions="End"
Orientation="Horizontal"
HorizontalOptions="Start">
<Label x:Name="lblName" Font="20" Text="{Binding Name}" />
</StackLayout>
</d:ViewPage>
XAML 代码隐藏:
public partial class DonorView : ViewPage<DonorViewModel>
{
public DonorView ()
{
InitializeComponent ();
}
}
我想也许我可以在后面的 XAML 代码中调用它,但这又是在构造函数中。
有什么建议吗?
谢谢
我通过在页面的 OnAppearing 中调用我的视图模型中的异步代码而不是构造函数来解决这个问题。构造函数用于内存分配而不是异步检索数据。
但是,如果您真的想要,可以在您的任务上调用 .Wait() 并阻塞线程。我不会推荐这个。
OnAppearing 是一种可行的方法,因为您可以合法地使用
public async void OnAppearing()
{
}
然而,它会导致许多问题,例如当您从前面的页面返回时,它会再次 运行。
根据您使用的导航服务或样式,我创建了一个仅在您首次访问该页面时才会调用的新事件。
在我的 BaseViewModel.cs OnNavigated 事件中
https://github.com/adamped/xarch-starter/blob/master/Mobile/Base/BaseViewModel.cs
将页面推送到堆栈时调用。当您将页面推送到 NavigationPage 时基本上会调用此方法。
或者,如果您想要一个快速的方法,请使用 OnAppearing 方法,但在其中放置一个 flag/bool,这样您就可以判断它何时已经 运行 一次,然后不会 运行 再次.
我有一个绑定到 ViewModel 的 Xamarin 表单。创建此 ViewModel 时,我希望它异步地从数据库中获取数据。我的问题是我不确定如何调用异步方法,因为构造函数无法调用异步方法并且 getter 无法调用异步方法。
我正在为 UI 使用纯 XAML,XAML 是否可以在初始化时调用方法?
我的视图模型:
public class DonorViewModel : BaseViewModel
{
public DonorViewModel (IRepository<Donor> donorRepository)
{
_donorRepository = donorRepository;
}
private string _name;
public string Name {
get {
return _name;
}
set {
if (_name != value) {
_name = value;
OnPropertyChanged ("Name");
}
}
}
private IRepository<Donor> _donorRepository;
private async Task GetName()
{
var donor = await _donorRepository.Get(d => d.Id == 1);
Name = donor.Name;
}
}
我的XAML:
<?xml version="1.0" encoding="UTF-8"?>
<d:ViewPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DonationExample.DonorView"
xmlns:d="clr-namespace:DonationExample;assembly=DonationExample"
x:TypeArguments="local:DonorViewModel"
xmlns:local="clr-namespace:DonationExample">
<ContentPage.BindingContext>
</ContentPage.BindingContext>
<StackLayout Spacing="10"
VerticalOptions="End"
Orientation="Horizontal"
HorizontalOptions="Start">
<Label x:Name="lblName" Font="20" Text="{Binding Name}" />
</StackLayout>
</d:ViewPage>
XAML 代码隐藏:
public partial class DonorView : ViewPage<DonorViewModel>
{
public DonorView ()
{
InitializeComponent ();
}
}
我想也许我可以在后面的 XAML 代码中调用它,但这又是在构造函数中。
有什么建议吗?
谢谢
我通过在页面的 OnAppearing 中调用我的视图模型中的异步代码而不是构造函数来解决这个问题。构造函数用于内存分配而不是异步检索数据。
但是,如果您真的想要,可以在您的任务上调用 .Wait() 并阻塞线程。我不会推荐这个。
OnAppearing 是一种可行的方法,因为您可以合法地使用
public async void OnAppearing()
{
}
然而,它会导致许多问题,例如当您从前面的页面返回时,它会再次 运行。
根据您使用的导航服务或样式,我创建了一个仅在您首次访问该页面时才会调用的新事件。
在我的 BaseViewModel.cs OnNavigated 事件中 https://github.com/adamped/xarch-starter/blob/master/Mobile/Base/BaseViewModel.cs
将页面推送到堆栈时调用。当您将页面推送到 NavigationPage 时基本上会调用此方法。
或者,如果您想要一个快速的方法,请使用 OnAppearing 方法,但在其中放置一个 flag/bool,这样您就可以判断它何时已经 运行 一次,然后不会 运行 再次.