I have a Xamarin Form that is bound to a ViewModel. When this ViewModel is created I want it go get data from the DB asynchronously. My issue is I'm not sure how I to call the async method as the constructor cannot call an async method and the getter cannot call an async method.
I'm using pure XAML for the UI, is it possible for the XAML to call a method on initialisation?
My 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;
}
}
My 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 codebehind:
public partial class DonorView : ViewPage<DonorViewModel>
{
public DonorView ()
{
InitializeComponent ();
}
}
I thought maybe I could call it in the XAML code behind, but again this is in the constructor.
Any suggestions?
Thanks
OnAppearing is a possible way to do it because you can legitimately use
public async void OnAppearing()
{
}
However it causes many issues such as when you come back from page in front it will run again.
Depending upon what navigation service or style you are using, I created a new event that gets call only when you first get to the page.
In my BaseViewModel.cs the OnNavigated event https://github.com/adamped/xarch-starter/blob/master/Mobile/Base/BaseViewModel.cs
Which is called when you Push the page on to the stack. Basically call this method when you push the page to your NavigationPage.
Alternatively if you want a quick way, use the OnAppearing method but put a flag/bool in there so you can tell when it has already run once and then won't run again.
I get around this by calling the async code in my view model in OnAppearing of the page instead of the constructor. Constructors are for memory allocation not retrieve data asynchronously.
However, if you really wanted to, you could call .Wait() on your task and block the thread. I would NOT recommend this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With