Где отписаться от MessagingCenter, чтобы изменения, сделанные несколько раз в представлении View C, отображались в View A, если стек навигации - View A / View B / View C - PullRequest
0 голосов
/ 31 октября 2019

Следующий код работает, если было выполнено только одно редактирование. Я хочу знать, как мне поступить, т. Е. Где отписаться от Центра обмена сообщениями, чтобы можно было отображать несколько правок для одного и того же элемента.

У меня есть три вида, модель и соответствующие модели вида. Это:

  • Страница 1 ListPage, ListPageViewModel - список элементов
  • Страница 2 ItemPage, ItemPageViewModel - для просмотра сведений оэлемент и имеет кнопку Edit
  • Page 3 ItemDetailPage, ItemDetailPageViewModel - для редактирования сведений об элементе и кнопку Save
  • Item, ItemViewModel -модель предметаПусть стек навигации будет Page 1 / Page 2 / Page 3 - я хочу, чтобы изменения, внесенные на странице 3, распространялись обратно на страницу 1. Поэтому я использую MessagingCenter в модели представления страницы 2. Поскольку изменения, сделанные на странице 3, автоматически отображаются на странице 2из-за INotifyPropertyChanged, но изменения на странице 2 не отображаются автоматически на странице 1, поскольку itemviewmodel не совпадает. Поэтому я использую центр сообщений. Сценарий Допустим, пользователь выбирает элемент Foo из списка. Он идет на страницу предмета Foo. Там он нажимает кнопку Edit, выполняет редактирование. Затем он снова нажимает Edit и выполняет другое редактирование. Теперь он нажимает кнопку «Назад» в навигационной панели и возвращается на страницу списка. То, как код написан в настоящее время, первое изменение отображается в списке, но не второе. Это потому что отписка происходит сразу. Я хочу знать, где я должен отписаться, чтобы я мог получить все изменения, сделанные без утечки памяти или фантомных звонков. В ItemPageViewModel после того, как я отредактировал элемент, я использую MessagingCenter, чтобы ListPageViewModel узнал, что элемент был отредактирован. Но если я откажусь от подписки в том виде, в каком она есть сейчас, она не сработает после первого редактирования, если пользователь выполнит два редактирования подряд, прежде чем нажать кнопку back на панели навигации на ItemPage. Если я отписываюсь в IDisposable ListPageViewModel, я получаю все изменения, но я также получаю фантомные звонки. Код работает, но если я помещаю displayalert, он звонит дважды, если я редактирую два разных элемента (это потому, что первый ItemPageViewModel не был отписан)Текущий код в ItemDetailPageViewModel:

    async Task Save()
    {
       if(newItem)
       { // Add item to db }
       else
       {
         // Update item in db
         ItemUpdated?.Invoke(this,Item);
       }
       await _navService.PopAsync();   
    }

Текущий код в ItemPageViewModel:


    private async Task EditItem(ItemViewModel itemViewModel)
        {
            var itemDetailPageViewModel = new ItemDetailPageViewModel(itemViewModel, _dataStore, _navService);
            itemDetailPageViewModel.ItemUpdated += (source, updatedItem) =>
            {
                itemViewModel.Id = updatedItem.Id;
                itemViewModel.Name = updatedItem.Name;
                itemViewModel.Description = updatedItem.Description;
                itemViewModel.Type = updatedItem.Type;

                MessagingCenter.Send<ForMessageCenter, ItemViewModel>(new ForMessageCenter(), "edit", itemViewModel);

            };         

            await _navService.PushAsync(new ItemDetailPage(itemDetailPageViewModel));
        }

Код в ListPageViewModel выглядит следующим образом:


    private async Task SelectItem(ItemViewModel itemViewModel)
    {
            if (itemViewModel == null)
                return;

            SelectedItem = null;

            var itemPageViewModel = new ItemPageViewModel(itemViewModel, _dataStore, _navService);

       MessagingCenter.Subscribe<ForMessageCenter, ItemViewModel>(this, "edit", (sender, arg) =>  
       {
                // where do i put this
              MessagingCenter.Unsubscribe<ForMessageCenter, ItemViewModel>(this, "edit");

              var itemEdited = Items.FirstOrDefault(c => c.Id == arg.Id);
                itemEdited.Name = arg.Name;
                itemEdited.Description = arg.Description;
                itemEdited.Type = arg.Type;
      }
      await _navService.PushAsync(new ItemPage(itemPageViewModel));
    }

ObservableCollection Items объявляется следующим образом в ListPageViewModel

public ObservableCollection<ItemViewModel> Items { get; private set; }  = new ObservableCollection<ItemViewModel>();

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...