Пример
Рассмотрим почтовое приложение. Папка содержит много сообщений. FolderViewModel предоставляет представлению наблюдаемую коллекцию этих сообщений:
Код: Выделить всё
public class FolderViewModel(IService service) : ObservableObject
{
public ObservableCollection Messages { get; } = service.LoadMessagesForFolder(/*...*/);
}
Код: Выделить всё
public class Message
{
public string Subject { get; set; }
public bool IsRead { get; set; }
public bool IsFlagged { get; set; }
}
Однако при взаимодействии с сообщением возникают следующие две проблемы:
- Пользовательский интерфейс не обновляется при изменении сообщения: поскольку сообщение является POCO, оно не реализует INotifyPropertyChanged; такие изменения, как пометка как прочитанная или переключение флага, не передаются в пользовательский интерфейс.
- Команды не могут быть чисто и легко привязаны к родительскому элементу представления списка (например, в WinUI): команда для кнопки Удалить в каждом элементе сообщения должна быть привязана сама к себе.
Мой обходной путь заключался в создании модели представления элемента, которая обертывает модель, предоставляет наблюдаемые свойства для пользовательского интерфейса и перенаправляет команды:
Код: Выделить всё
public partial class MessageItemViewModel(Message model) : ObservableObject
{
private readonly Message _model = model;
[ObservableProperty]
public partial bool IsRead { get; set; } = model.IsRead;
[ObservableProperty]
public partial bool IsFlagged { get; set; } = model.IsFlagged;
// commands for setting flag, etc.
}
- Каждое соответствующее свойство модели теперь существует дважды (один раз в модели, один раз в оболочке), что приводит к дублированию кода.
- Большие коллекции обернутых элементов увеличивают использование памяти.
- Оболочки часто требуют сервисов, но их также необходимо создавать вручную, поскольку их модель используется в качестве параметра. Это не позволяет внедрять сервисы через контейнер DI.
- Когда модели представления элементов подписываются на внешние события или изменения домена, существует потенциальный риск утечек.
Каков рекомендуемый подход MVVM для отражения изменений состояния модели в пользовательском интерфейсе? Существует ли чистый шаблон, обычно используемый в приложениях MVVM для обработки этого сценария?
Подробнее здесь: https://stackoverflow.com/questions/798 ... ls-in-mvvm
Мобильная версия