带棱镜的Base ViewModel中的属性更改

时间:2018-07-04 21:26:50

标签: c# mvvm data-binding 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);
        }
    }  
}

我的问题是:当我在构造函数中设置common属性时,可以正常工作。 但是,当我在OnNavigatingTo中设置通用属性并使用async时,它不起作用。调用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);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

因为您是在单独的线程上进行异步调用,所以不会向UI通知更改。

async void中的OnNavigatingTo不是事件处理程序,这意味着它是在单独的线程中运行的即发即弃功能。

引用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线程上继续,并将获得属性更改通知。

答案 1 :(得分:1)

使用SetProperty时,不应为后场设置值。 所以您应该删除此行:

_common = value;