我有一个绑定到ViewModel的Xamarin表单。创建此ViewModel时,我希望它以异步方式从数据库中获取数据。我的问题是我不知道如何调用异步方法,因为构造函数无法调用异步方法,并且getter无法调用异步方法。
我正在使用纯XAML作为用户界面,XAML是否可以在初始化时调用方法?
我的ViewModel:
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代码中调用它,但这又是在构造函数中。
有什么建议吗?
由于
答案 0 :(得分:9)
OnAppearing是一种可能的方法,因为你可以合法地使用
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
但是它会导致许多问题,例如当你从前面的页面回来时它会再次运行。
根据您使用的导航服务或样式,我创建了一个新事件,只有在您第一次访问该页面时才会收到呼叫。
在我的BaseViewModel.cs中OnNavigated事件 https://github.com/adamped/xarch-starter/blob/master/Mobile/Base/BaseViewModel.cs
将页面推送到堆栈时调用的内容。当您将页面推送到NavigationPage时,基本上调用此方法。
或者,如果你想要一个快速的方法,使用OnAppearing方法,但在那里放一个标志/ bool,这样你就可以告诉它什么时候已经运行一次,然后再不会再运行。
答案 1 :(得分:3)
我通过在页面的OnAppearing中调用视图模型中的异步代码而不是构造函数来解决这个问题。构造函数用于内存分配,不能异步检索数据。
但是,如果你真的想,你可以在你的任务上调用.Wait()并阻止线程。我不会推荐这个。