Обработка изменяемых моделей в MVVMC#

Место общения программистов C#
Ответить
Anonymous
 Обработка изменяемых моделей в MVVM

Сообщение Anonymous »

В архитектуре MVVM модели не должны содержать логики, связанной с пользовательским интерфейсом. Они представляют собой чистые данные, извлекаемые из памяти через службу. Я вижу проблему, когда пользовательский интерфейс должен реагировать на изменения во внутреннем состоянии модели, но сама модель не должна реализовывать механизмы уведомления, такие как INotifyPropertyChanged или другое поведение, специфичное для платформы пользовательского интерфейса.
Пример
Рассмотрим почтовое приложение. Папка содержит много сообщений. 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; }
}
Из пользовательского интерфейса я могу легко добавлять или удалять сообщения с помощью команд FolderViewModel.
Однако при взаимодействии с сообщением возникают следующие две проблемы:
  • Пользовательский интерфейс не обновляется при изменении сообщения: поскольку сообщение является 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»