Использование MVVM, как уведомить другие свойства и команды, когда коллекция была изменена

В программе, написанной на C # и Xamarin Forms (но этот вопрос больше основан на MVVM), у меня есть ObservableCollection элементов:

        ObserbableCollection<Item> Items { get; set; }

Когда эта коллекция изменяется (элемент добавляется или удаляется в / из коллекции), мне нужно уведомить другие свойства и команды, потому что все они привязаны к элементам управления на экране XAML (в основном кнопки и метки).

Единственное решение, которое я нашел, было примерно таким:

        Items.CollectionChanged += (sender, args) =>
        {
            ((Command)OnHoldCommand).ChangeCanExecute();
            ((Command)CancelSaleCommand).ChangeCanExecute();
            ((Command)ValidateTakeAwayCommand).ChangeCanExecute();
            ((Command)ValidateEatInCommand).ChangeCanExecute();
            RaisePropertyChanged(() => TotalItems);
            RaisePropertyChanged(() => TotalAmount);
        };

Как вы думаете, есть другое решение? Может быть, используя Fody.PropertyChanged?

Я использую FreshMvvm как фреймворк Mvvm поверх Xamarin Forms.


person hugo    schedule 05.09.2017    source источник
comment
Скажите, пожалуйста, чего вы пытаетесь добиться? Зачем нужны кнопки и метки для прослушивания измененной коллекции?   -  person Yehor Hromadskyi    schedule 06.09.2017
comment
@YehorHromadskyi Потому что некоторые метки на экране отображают информацию, вычисленную при обновлении списка элементов. А некоторые кнопки отключаются командами (с функцией CanExecute). Эти функции CanExecute также зависят от содержимого списка элементов.   -  person hugo    schedule 06.09.2017
comment
Ваш текущий метод - единственный вариант, о котором я знаю, без создания какой-либо каскадной структуры изменений, которая соединяет зависимые объекты вместе.   -  person Bradley Uffner    schedule 06.09.2017


Ответы (1)


Ваши ViewModels обычно реализуют интерфейс INotifyPropertyChanged. Если это так, то вы можете подписаться на событие PropertyChanged и следить за изменениями коллекции, как это делает представление. В обработчике событий можно при необходимости уведомить другие свойства.

Другой более прямой способ - когда ваша ViewModel контролирует вставки / изменения, вы можете напрямую уведомлять другие свойства, например, новый элемент вставлен (вызов метода NotifyPropertyChanged()).

person martinstoeckli    schedule 06.09.2017
comment
Это то, что я сделал, но в событии CollectionChanged коллекции. Результирующий код должен быть таким же, если я понимаю, что вы имеете в виду. - person hugo; 06.09.2017
comment
@hugorgor - В вашем примере вы подписываетесь на событие Collection.OnChange напрямую, конечно, это можно сделать. При подключении к ViewModel.INotifyPropertyChanged.PropertyChanged вы будете получать информацию всякий раз, когда ваше приложение отправляет уведомление, независимо от того, вызвало ли собрание событие. Разница небольшая. - person martinstoeckli; 06.09.2017