Рассмотрим следующий объект, часть приложения WPF MVVM:Уведомьте ViewModel, что объект в коллекции был выбран
public class MyObject : INotifyPropertyChanged
{
// INotifyPropertyChanged gubbins
private bool _isSelected;
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
И его использование в следующем ViewModel:
public class MyViewModel : INotifyPropertyChanged
{
// INotifyPropertyChanged gubbins
private List<MyObject> _myObjects;
public List<MyObject> MyObjects
{
get
{
return _myObjects;
}
set
{
_myObjects = value;
OnPropertyChanged("MyObjects");
}
}
public bool CanDoSomething
{
get
{
return MyObjects.Where(d => d.IsSelected).Count() > 0;
}
}
}
В в этой ситуации я могу отслеживать, какой из моих объектов был выбран, и при выборе их будет срабатывать OnPropertyChanged и поэтому может уведомить родительский вид.
Однако CanDoSomething всегда будет ложным, потому что нигде я не могу запустить OnPropertyChanged для создания уведомления. Если я поставлю его в MyObject, он ничего не знает об этом свойстве и ничего не делает. Его нет в ViewModel, потому что ничего не реагирует, когда выбран объект в списке.
Я попытался заменить список на ObservableCollection и пользовательский «TrulyObservableCollection» (см. Notify ObservableCollection when Item changes), но не работает.
Как я могу обойти это, не прибегая к событиям щелчка?
Вы можете подключить 'PropertyChangedEvent' в' MyViewModel' для всех «MyObjects» и когда свойство «IsSelected» будет изменено в Модели, оно уведомит ViewModel, и вы сможете поднять другое измененное событие свойства для «CanDoSomething» 'чтобы показать, что это может измениться. –
Это в основном вопрос о том, как общаться между ViewModels. Один из подходов - передать каждому родительскому элементу ViewModel родительский элемент, поэтому вы можете вызвать метод родительского ViewModel в установщике 'IsSelected'. Другим возможным подходом (должно быть больше) является использование статического события, которое запускается установщиком 'IsSelected', подписывается на это событие в родительском ViewModel и вызывает обработчик' NotifyPropertyChanged (nameof (CanDoSomething)) '. – Sinatr
Хорошая точка, Sinatr. В этой статье Мэтт Гамильтон вводит родительский ViewModel в качестве объекта-хоста. Это приемлемо в случаях, когда дочерний ViewModel действительно не может существовать без родителя (например, в случае с тэгом без родительской временной шкалы). http://matthamilton.net/nested-viewmodels – Christoph