属性 带棱镜的基本 ViewModel 发生变化
Property change in Base ViewModel with prism
我正在使用 Prism 开发一个 android 应用程序。
我正在尝试创建一个基本 ViewModel。在这个 ViewModel 中,我想为我的所有 ViewModel 设置通用属性。
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);
}
}
}
我的问题是:当我在构造函数中设置公共 属性 时,工作正常。
但是当我在 OnNavigatingTo
中设置公共 属性 并使用异步时,不起作用。 SetProperty
在调用 OnNavigatingTo
时被触发,但是我用这个普通 属性 绑定的标签不会刷新值。
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);
}
}
}
因为您在单独的线程上执行异步调用,所以 UI 没有收到更改通知。
OnNavigatingTo
的 async void
不是事件处理程序,意味着它是单独线程中的即发即弃函数 运行。
引用Async/Await - Best Practices in Asynchronous Programming
创建适当的事件和异步事件处理程序以在那里执行异步操作
例如
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);
}
}
}
这样,当等待的操作完成时,代码将在 UI 线程上继续,并且会收到 属性 已更改的通知。
当您使用 SetProperty 时,您不应该为后场设置值。
所以你应该删除这一行:
_common = value;
我正在使用 Prism 开发一个 android 应用程序。
我正在尝试创建一个基本 ViewModel。在这个 ViewModel 中,我想为我的所有 ViewModel 设置通用属性。
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);
}
}
}
我的问题是:当我在构造函数中设置公共 属性 时,工作正常。
但是当我在 OnNavigatingTo
中设置公共 属性 并使用异步时,不起作用。 SetProperty
在调用 OnNavigatingTo
时被触发,但是我用这个普通 属性 绑定的标签不会刷新值。
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);
}
}
}
因为您在单独的线程上执行异步调用,所以 UI 没有收到更改通知。
OnNavigatingTo
的 async void
不是事件处理程序,意味着它是单独线程中的即发即弃函数 运行。
引用Async/Await - Best Practices in Asynchronous Programming
创建适当的事件和异步事件处理程序以在那里执行异步操作
例如
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);
}
}
}
这样,当等待的操作完成时,代码将在 UI 线程上继续,并且会收到 属性 已更改的通知。
当您使用 SetProperty 时,您不应该为后场设置值。 所以你应该删除这一行:
_common = value;