Страницы

Поиск по вопросам

пятница, 5 июля 2019 г.

Вопрос о Model и ViewModel в MVVM

Работали мы когда-то с WinForm и был у нас некий класс: class City { public int ID {get;set;}
public string Name {get;set;}
public List {get;set;} .... } Потом мы узнали про WPF и решили перейти на него. Но если это WPF, то занчит надо делать все по канону (т.е. с использованием MVVM) и надо бы сделать ViewModel. Дак вот тут-то я и теряюсь. Как лучше сделать? Доработать тот самый класс City - сделать его наследником INotifyPropertyChanged (При этом коллекции заменить на ObservableCollection), но ведь тогда у нас Model и ViewModel сольются воедино? Не хорошо получается, или хорошо?. Или же создать для него ViewModel: class CityViewModel : INotyPropertyCjanged { private City _city;
public int ID { get {return _city.ID; } set {_city.ID = value; RaisePropertyChanged("ID");} } ... } Но что же тогда делать с List? Как ее упаковать в ObservableCollection? Направьте пожалуйста на путь истинный... Примеры приветствуются! UPD И пока не забыл. Допустим нам надо наполнить нашу модель данными из, например, баз данных. Где должна лежать функция получения данных? Во ViewModel или View или еще где?


Ответ

Смотрите. Классы модели лежат отдельно, и не пересекаются с классами VM. Классы VM моделируют сущности вашей «бизнес-логики», то есть, внутренние объекты в терминах программы. Классы модели моделируют сущности своей предметной области. Например, ID интересен модели, но может быть вовсе не интересен программе, так что переносить его в VM нет особого смысла (разве что он нужен в UI). Таким образом, у нам получается вот что: Модель: class City { public int ID { get; private set; } public string Name { get; private set; } public List Areas { get; private set; } }
static class CityHelpers { static City GetCityByName(string name) { ... } } VM: class CityVM : INotifyPropertyChanged // или даже DependencyObject { public CityVM(City city) { name = city.Name; Areas = new ObservableCollection(); foreach (var area in city.Areas) Areas.Add(new AreaVM(area)); }
public Name { get { return name; } set { if (name == value) return; name = value; RaisePropertyChanged("Name"); } }
public ObservableCollection Areas { get; private set; }
// ну и ещё имплементация INotifyPropertyChanged } Функции получения данных лежат, понятно, в модели: VM не должна знать, как именно и откуда берутся данные. Но вот попросить модель загрузить данные должна именно VM (причём желательно грузить их не в UI-потоке, конечно, а то будет подвисать).

Комментариев нет:

Отправить комментарий