简体   繁体   English

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

[英]Property change in Base ViewModel with prism

I'm using prism to develop an android app. 我正在使用棱镜开发一个Android应用程序。

I'm trying to make a Base ViewModel. 我正在尝试制作基本ViewModel。 Inside this ViewModel I would like to set common properties to all my ViewModels. 在此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);
        }
    }  
}

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. 但是,当我在OnNavigatingTo设置通用属性并使用async时,它不起作用。 The SetProperty is triggered when calling the OnNavigatingTo , but my binded label with this common property doesn´t refresh the value. 调用OnNavigatingTo时会触发SetProperty ,但是具有此公共属性的绑定标签不会刷新该值。

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);
        }
    }
}

Because you are doing asynchronous invocation on a separate thread the UI is not being notified of the change. 由于您是在单独的线程上进行异步调用,因此不会向UI通知更改。

The async void of OnNavigatingTo , which is not an event handler, means it is a fire and forget function running in a separate thread. 不是事件处理程序的OnNavigatingTo async void ,意味着它是在单独的线程中运行的即发即OnNavigatingTo功能。

Reference Async/Await - Best Practices in Asynchronous Programming 参考Async / Await-异步编程最佳实践

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. 这样,当等待的操作完成时,代码将在UI线程上继续,并且它将获取属性更改通知。

when you use SetProperty, you should not set value for the backfield. 使用SetProperty时,不应为后场设置值。 so you should remove this line: 因此,您应该删除以下行:

_common = value;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM