Изменение свойства в Base ViewModel с призмой - PullRequest
0 голосов
/ 05 июля 2018

Я использую призму для разработки приложения для Android.

Я пытаюсь сделать 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 и использую 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 голосов
/ 08 июля 2018

когда вы используете SetProperty, вы не должны устанавливать значение для backfield. поэтому вы должны удалить эту строку:

_common = value;
0 голосов
/ 05 июля 2018

Поскольку вы выполняете асинхронный вызов в отдельном потоке, пользовательский интерфейс не уведомляется об изменении.

async void из OnNavigatingTo, который не является обработчиком событий, означает, что это функция запуска и забытия, выполняющаяся в отдельном потоке.

Ссылка Async / Await - Лучшие практики в асинхронном программировании

Создать правильный обработчик событий и асинхронных событий для выполнения там ваших асинхронных операций

Например

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

Таким образом, когда ожидаемая операция будет завершена, код продолжится в потоке пользовательского интерфейса и получит уведомление об изменении свойства.

...