Reputation: 25
I'm using prism to develop an android app.
I'm trying to make a Base ViewModel. Inside this ViewModel I would like to set common properties to all my ViewModels.
public class BaseViewModel : BindableBase
{
protected INavigationService _navigationService;
protected IPageDialogService _dialogService;
public BaseViewModel(INavigationService navigationService, IPageDialogService dialogService)
{
_navigationService = navigationService;
_dialogService = dialogService;
}
private string _common;
/// <summary>
/// Common property
/// </summary>
public string CommonProperty
{
get { return _common; }
set
{
_common = value;
SetProperty(ref _common, value);
}
}
}
My problem is: when I set the common property in the constructor, works fine.
But when I´m setting the common property in OnNavigatingTo
and using async, doesn´t work. The SetProperty
is triggered when calling the OnNavigatingTo
, but my binded label with this common property doesn´t refresh the value.
namespace TaskMobile.ViewModels.Tasks
{
/// <summary>
/// Specific view model
/// </summary>
public class AssignedViewModel : BaseViewModel, INavigatingAware
{
public AssignedViewModel(INavigationService navigationService, IPageDialogService dialogService) : base(navigationService,dialogService)
{
CommonProperty= "Jorge Tinoco"; // This works
}
public async void OnNavigatingTo(NavigationParameters parameters)
{
try
{
Models.Vehicle Current = await App.SettingsInDb.CurrentVehicle();
CommonProperty= Current.NameToShow; //This doesn´t works
}
catch (Exception e)
{
App.LogToDb.Error(e);
}
}
}
Upvotes: 0
Views: 1071
Reputation: 292
when you use SetProperty, you should not set value for the backfield. so you should remove this line:
_common = value;
Upvotes: 1
Reputation: 247551
Because you are doing asynchronous invocation on a separate thread the UI is not being notified of the change.
The async void
of OnNavigatingTo
, which is not an event handler, means it is a fire and forget function running in a separate thread.
Reference Async/Await - Best Practices in Asynchronous Programming
Create a proper event and asynchronous event handler to perform your asynchronous operations there
For example
public class AssignedViewModel : BaseViewModel, INavigatingAware {
public AssignedViewModel(INavigationService navigationService, IPageDialogService dialogService)
: base(navigationService, dialogService) {
//Subscribe to event
this.navigatedTo += onNavigated;
}
public void OnNavigatingTo(NavigationParameters parameters) {
navigatedTo(this, EventArgs.Empty); //Raise event
}
private event EventHandler navigatedTo = degelate { };
private async void onNavigated(object sender, EventArgs args) {
try {
Models.Vehicle Current = await App.SettingsInDb.CurrentVehicle();
CommonProperty = Current.NameToShow; //On UI Thread
} catch (Exception e) {
App.LogToDb.Error(e);
}
}
}
That way when the awaited operation is completed the code will continue on the UI thread and it will get the property changed notification.
Upvotes: 1