Добавление INotifyPropertyChanged в модель?
я сталкиваюсь с некоторыми вопросами дизайна в моем приложении WPF MVVM (Prism), был бы рад получить ваш совет. Моя модель очень проста:
public class Customer
{
public string FirstName {get;set;}
public string LastName {get;set;}
}
Как вы можете видеть, у меня нет поддержки INotifyPropertyChnaged для моего класса модели. У меня также есть ViewModel для экрана CustomerDetails, который поддерживает INotifyPropertyChanged.
public class CustomerDetailsViewModel:INotifyPropertyChanged /*Or NotificationObject*/
{
/*INotifyPropertyChanged event */
private Customer item;
public Customer Item
{
get{return item;}
set
{
item=value;
//Raise PropertyChanged
//Set IsDirty to true
}
}
}
на мой взгляд, я использую привязку к элементу.FirstName и моя ViewModel обновляются. Моя проблема - так как только Свойство FirstName обновляется через представление, и сама модель не поддерживает INotifyPropertyChanged, поэтому не вызывается задатчик элементов, а IsDirty остается равным false (и поэтому не обновляет уведомление IsDirty в пользовательском интерфейсе).
Я знаю, что могу поддерживать INotifyPropertyChanged в модели, а затем зарегистрироваться в элементе.PropertyChanged событие в модели представления и фактически установить IsDirty в true, но - Поскольку я также использую CodeFirst и мою модель класс, разделяемый между моей серверной и клиентской сторонами (не используя ссылку на службу Add), я не хочу добавлять материал INotifyPreoprtyChanged на мою серверную сторону.
Я создаю новый проект, который будет использовать шаблоны T4 для копирования по одному всех моих сущностей (как клиент) и добавления поддержки INotifyPropertyChanged к каждой модели. Это кажется разумным или нет? есть другие предложения?
спасибо!
5 ответов
Option1.
Отдельные сущности, которые передаются между клиентом и сервером (DTO), от сущностей, которые являются моделями на стороне клиента. Реализовать INPC
в модели. Сопоставление между этими сущностями.
Option2.
Bind view для просмотра только свойств модели. Сделать вид, что обертывание соответствующих свойств модели.
Представляет собой смесь первых двух вариантов. Не агрегируйте модель в view model. Сопоставление между модели и посмотреть модель. Создайте свойства модели представления, соответствующие свойствам модели.
Ну это просто не самый лучший. Гораздо лучше было бы использовать VM, как это
public class CustomerDetailsViewModel : INotifyPropertyChanged
{
public CustomerDetailsViewModel(Customer customer)
{
_item = customer;
}
private Customer _item;
public string FirstName
{
get { return _item != null ? _item.FirstName : null; }
set
{
if (_item == null)
_item = new Customer(); // just an example, probably it's not the desired behavior
_item.FirstName = value;
RaisePropertyChanged(...);
}
}
...
}
Это будет придерживаться духа MVVM.
если вы хотите, чтобы ваш UI, чтобы заметить, когда ваша модель объекта ваша модель класс должны реализовать INotifyPropertyChanged
и аналогичные интерфейсы MVVM (IDataErrorInfo
, etc...) для того, чтобы Notify
для пользовательского интерфейса, что property changed
.
это потому, что вы не всегда обновляете свою модель из viewmodel, где вы должны реализовать INotifyProperyChanged
и уведомления об изменениях.
перенос соответствующих свойств модели в viewmodel, используемый при не удается реализовать INotifyPropertyChanged
в классе model, что делает viewmodel очень быстрым и создает ненужное дублирование кода.
сценарий к примеру:
public class Customer
{
public string FirstName {get;set;}
public string LastName {get;set;}
// Changes the first name.
public void ChangeFirstName(string newName)
{
FirstName = newName;
//The UI will never know that the property changed, and it won't update.
}
}
устранение:
реализовать INotifyPropertyChanged
в классе модели создайте backing fields
на properties
, и для каждого свойства setter
, после set
операции, поднять OnPropertyChanged
вызывается метод с property
имя.
Я думаю, что вы на правильном пути. На стороне сервера, вам не нужно INotifyPropertyChanged
, поэтому не добавляйте его в классы домена на стороне сервера.
вы можете просто добавить некоторые символы сборки, такие как" WPF", в свои клиентские проекты; и в коде первые определения реализуют INotifyPropertyChanged
только если есть символ сборки "WPF". Затем просто добавьте классы домена на стороне сервера в качестве ссылок на приложение презентации. Что-то вроде:
#if WPF
public class MyEntity : INotifyPropertyChanged
#else
public class MyEntity
....
Если вам не нравится загромождать вашу модель кодом INotifyPropertyChanged, вы можете попробовать использовать пакет NUGet под названием PropertyChanged.Фоди!--2-->
вы можете использовать его как это:
using PropertyChanged;
[ImplementPropertyChanged]
public class Customer
{
public string FirstName {get;set;}
public string LastName {get;set;}
}
любое публичное свойство в этом классе теперь будет поддерживать INotifyPropertyChanged