【问题标题】:Property change in Base ViewModel with prism带有棱镜的基本 ViewModel 中的属性更改
【发布时间】:2018-12-13 07:45:25
【问题描述】:

我正在使用 prism 开发一个安卓应用。

我正在尝试制作 Base 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 中设置公共属性并使用异步时,它不起作用。调用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);
        }
    }
}

【问题讨论】:

  • 如果我将我的CommonPropertyBaseViewModel 移动到我的AssignedViewModel 它可以工作

标签: c# mvvm data-binding prism


【解决方案1】:

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

_common = value;

【讨论】:

  • 事实上,这将阻止OnPropertyChanged 事件,因为SetProperty 不会看到新值与旧值不同(显然)
  • 嗨,@Mahdi Asgari。谢谢你的帮助。这绝对是我的问题。我什至没有注意到那行代码。
  • 另外,感谢@Haukinger 的贡献。
【解决方案2】:

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

OnNavigatingToasync 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 线程上继续运行,并会收到属性更改通知。

【讨论】:

  • 嗨@Nkosi。我感谢您的帮助。对我来说,这看起来像是一个长期的解决方案。如果我把我的共同财产放在我所有的 ViewModel 中,也许会更容易。但是,我不知道这是否会降低我的表现(至少一点点)你觉得呢?
猜你喜欢
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
相关资源
最近更新 更多