Отследить изменение свойств объекта

228
14 апреля 2017, 18:59

Есть коллекция вида ObservableCollection<BaseClass> Project {get;set;}.

Задача в следующем:

Если какое-то свойство объекта изменилось, то нужно уведомить пользователя о том, что в проект внесены правки и его требуется сохранить.

Ничего не придумал, кроме как реализовать INotifyPropertyChanged у базового класса, но классов достаточно много и каждое свойство разворачивать в свойство с полем, чтобы вызывать OnPropertyChanged довольно муторно.

Существует ли какая-нибудь лаконичная альтернатива?

Answer 1

Альтернативой ручной реализации INotifyPropertyChanged будет либо использование сниппетов, либо использование специализированных инструментов для инъекции IL-кода в сборку при компиляции. Общепризнанным лидером в этой области является PostSharp, но он, естественно, платный. Тем не менее существует опенсурс проект для изменения сборок при компиляции под названием Fody, одно из дополнений которого позволяет делать как раз реализацию INF. Кстати, советую ознакомиться с полным списком дополнений для Fody на странице в GitHub, там много интересного. Также можно писать свои дополнения, схема разработки не очень дружелюбная, но зато есть множество примеров (все существующие дополнения также лежат на GitHub).

Answer 2

Можете попробовать как-то так:

Создаёте коллекцию, все элементы коллекции при таком подходе должны реализовывать INPC.

ObservableCollection<INotifyPropertyChanged> items = 
                              new ObservableCollection<INotifyPropertyChanged>();

Вешаете обработчик на событие изменений в коллекции:

items.CollectionChanged += 
    new System.Collections.Specialized.NotifyCollectionChangedEventHandler(
                                                        items_CollectionChanged);

В делегате пробегаемся по старым/новым элементам и убираем/добавляем обработчики изменения свойств в объектах:

static void items_CollectionChanged(object sender, 
               System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    foreach (INotifyPropertyChanged item in e.OldItems)
        item.PropertyChanged -= new 
                               PropertyChangedEventHandler(item_PropertyChanged);
    foreach (INotifyPropertyChanged item in e.NewItems)
        item.PropertyChanged += 
                           new PropertyChangedEventHandler(item_PropertyChanged);
}

Собственно внутри этого метода напишите код уведомления:

static void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    throw new NotImplementedException();
}

Ну и каждое свойство самого объекта, входящего в коллекцию должно быть связано с интерфейсом INPC. Для более ёмкой и читаемой реализации свойств внутри объекта воспользуйтесь сторонними библиотеками, например MVVM Light.

READ ALSO
Скрыть panel если курсор за ее пределами

Скрыть panel если курсор за ее пределами

Panel1 открывается по нажатию на buttonНужно чтобы panel1 скрылась когда курсор выходит за ее границы

212
С# WinForms. Обновить данные в форме

С# WinForms. Обновить данные в форме

Имеется 2 формы, form1 - картинки с названиями велосипедов, форма AddBicycle - для добавления нового велосипеда в магазинПроблема заключается в том,...

287
Как удалить из коллекции строки по определенной части?

Как удалить из коллекции строки по определенной части?

Есть коллекция , в коллекции строки вида:

227