MVVM: OnBindingContextChange: PropertyChanged не запускается в новой модели представления - PullRequest
0 голосов
/ 23 января 2020

Я кодирую приложение Xamarin и прилагаю все усилия, чтобы придерживаться MVVM, что мне действительно очень нравится

У меня обычно есть ContentPages, содержащие ссылки на Views.

Я устанавливаю контекст привязки на ВМ на странице, а затем использовать OnBindingContextChanged в представлении

. Это позволяет мне использовать метод PropertyChanged, чтобы затем отвечать на условия отображения logi c для моего представления

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

Страница выглядит так

public partial class BindingTextPage : ContentPage
{
    public BindingTextPage()
    {
        InitializeComponent();

        this.BindingContext = new ViewModels.LocationsViewModel();
    }
}

Вид выглядит так

private LocationsViewModel_vm;

public BindingTestView()
{
    InitializeComponent();

    System.Diagnostics.Debug.WriteLine("Debug: Initialised BindingTesView view");

}

protected override void OnBindingContextChanged()
{
    System.Diagnostics.Debug.WriteLine("Debug: BindingTest: OnBindingContextChanged: Context " + this.BindingContext.GetType());

    _vm = BindingContext as LocationsViewModel;

    _vm.PropertyChanged += _vm_PropertyChanged;
}

private void _vm_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    try
    {
        System.Diagnostics.Debug.WriteLine("Debug: BindingTest: Method called");
        System.Diagnostics.Debug.WriteLine("Debug: BindingTest: Property " + e.PropertyName);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine("Debug: BindingTestView: Error changing context " + ex.Message);
    }
}

Извлечь модели представления, очень просто в этом случае установка строки и, следовательно, изменение свойства, которое, как я ожидал, вызвало бы срабатывание PropertyChange?

public LocationsViewModel()
{
    tempMessage = "this is from the view model";
}

public string tempMessage
{
    get
    {
        return _tempMessage;
    }
    set
    {
        _tempMessage = value;
        OnPropertyChanged(nameof(tempMessage));
    }
}

Мои операторы отладки при загрузке показывают, что OnBindingContextChange вызывается, но в этом случае _vm_PropertyChanged никогда не срабатывает? Я ожидаю, что tempMessage будет настроен на это?

1 Ответ

2 голосов
/ 23 января 2020

Порядок событий в вашем коде следующий

  • Конструктор LocationsViewModel называется
  • Из вашего конструктора вы устанавливаете tempMessage
  • Сеттер tempMessage вызывает OnPropertyChanged, поскольку в данный момент событие null не вызывается
  • Конструктор LocationsViewModel оставлен
  • Page.BindingContext set
  • OnBindingContextChanged называется
  • LocationsViewModel.PropertyChanged подписан вашей страницей

Поскольку событие поднимается (или пытается) перед подписью вашей страницы Ваша страница просто не получает информацию о проводимом мероприятии. Если вы установите значение после подписки на событие, обработчик будет вызываться, как и ожидалось.

например,

protected override void OnBindingContextChanged()
{
    _vm = BindingContext as LocationsViewModel;

    _vm.PropertyChanged += _vm_PropertyChanged;

    _vm.tempMessage = "Hello, world!"; // clichée , I know
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...