Страницы

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

пятница, 10 января 2020 г.

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

#wpf #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 или еще где?    


Ответы

Ответ 1



Смотрите. Классы модели лежат отдельно, и не пересекаются с классами 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-потоке, конечно, а то будет подвисать).

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

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