В процессе изучения MVVM натолкнулся на проблему обновления данных в Model, полученных из ViewModel , имеется некое приложение, в котором:
Model:
public class Journal:IJournal<Common,Excavation>
{
public Common CommonInfo { get; set; }
public ObservableCollection<Excavation> Excavations { get; set; }
}
public class Common:ICommon
{
public String Object { get; set; }
public UInt32 NumJournal { get; set; }
}
public class Excavation:IExcavation
{
public String NumExcavation { get; set; }
public DateTime DateCreateExcavation { get; set; }
}
ViewModel:
class JournalViewModel : PropertyChangedNotification,IJournal<CommonViewModel,ExcavationViewModel>
{
public CommonViewModel CommonInfo
{
get { return GetValue(() => CommonInfo); }
set { SetValue(() => CommonInfo, value); }
}
public ObservableCollection<ExcavationViewModel> Excavations
{
get { return GetValue(() => Excavations); }
set { SetValue(() => Excavations, value); }
}
public JournalViewModel(Journal journal)
{
CommonInfo = new CommonViewModel(journal.CommonInfo);
Excavations = new ObservableCollection<ExcavationViewModel>();
foreach (var excavation in journal.Excavations)
{
Excavations.Add(new ExcavationViewModel(excavation));
}
}
}
class CommonViewModel : PropertyChangedNotification,ICommon
{
public String Object
{
get { return GetValue(() => Object ); }
set { SetValue(() => Object , value); }
}
public UInt32 NumJournal
{
get { return GetValue(() => NumJournal ); }
set { SetValue(() => NumJournal , value); }
}
public CommonViewModel(Common common)
{
Object = common.Object;
NumJournal = common.NumJournal ;
}
}
class ExcavationViewModel : PropertyChangedNotification, IExcavation
{
public String NumExcavation
{
get { return GetValue(() => NumExcavation ); }
set { SetValue(() => NumExcavation , value); }
}
public DateTime DateCreateExcavation
{
get { return GetValue(() => DateCreateExcavation ); }
set { SetValue(() => DateCreateExcavation , value); }
}
public ExcavationViewModel(Excavation excavation)
{
NumExcavation = common.NumExcavation ;
DateCreateExcavation = common.DateCreateExcavation ;
}
}
Думаю будет совершенно не критично, если обойтись без View. В приведенном примере кода четко видно, что объект класса Journal передается в конструктор JournalViewModel и после чего, данные из этого объекта заносятся в свойства VM. Однако заносятся только данные, т.е. VM с M по сути не связаны. Возникает вопрос, а что если модель предназначена для сериализации и десериализации в определенный формат файла и работает именно с ним, ведь нужно обновлять данные модели...
Начитавшись статей, нашел 3 различных способа решить проблему обновления модели из VM:
1) Создать метод в VM который будет обновлять всю модель сразу (действия обратные действиям в конструкторе в полученный объект Journal записывать данные из свойств VM)
2) Создать некие Event отслеживающие изменения VM и записывающие данные в M
3) Создать свойство хранящее начальный объект Journal и в конструкторе записывать в него принимаемого значения после чего в getter и setter свойств использовать return Journals.Common (например) Однако, есть некоторая проблема с типами не могу понять, где ссылка работает, а где перестает действовать. Потому что я передаю объект (ссылку) Journal в конструктор VM, он так же содержит внутри себя Common который тоже является объектом (ссылкой), но связывания не происходит передаются только данные.
В данном примере
class BookViewModel : ViewModelBase
{
public Book Book;
public BookViewModel(Book book)
{
this.Book = book;
}
public string Title
{
get { return Book.Title; }
set
{
Book.Title = value;
OnPropertyChanged("Title");
}
}
}
Связь VM с M реализована как раз через ссылку, не пойму правильно ли так их связывать в условиях паттерна, ведь по сути мы просто протягиваем модель и в нее через привязку к представлению записываем данные... В данной статье видел картинку в ней указано что VM общаясь с M использует 3 вида связи:
- События изменения модели
- Обновление модели
- Получение данных
Сейчас работаю по примеру. не смотря на то что проблема выгрузки возникла почти сразу не обращал внимание, а теперь решил все таки заняться этим =(
Если есть возможность, подскажите, пожалуйста, куда лучше копать чтобы не набить еще больше шишек..
GetModel— вы уверены, что так надо? Почему у вас создаётся новый модельный объект публичным методом, причём каждый раз новый? Это скорее всего крайне неправильно. Модельные объекты должны жить сами по себе, VM имеет право создавать новые модельные объекты тогда, когда это нужно бизнес-логике, а не левой пятке любого, кто может вызвать публичный метод. – VladD Jun 24 '15 at 20:05