То, как мы справляемся с этим, требует немного больше усилий, но оно может быть автоматизировано с помощью макросов VS или инструментов генерации кода, таких как CodeSmith.
Однако этот подход расширяем для любой конструкции пользовательского интерфейса, с которой связана коллекция, и не требует повторной реализации в пользовательском интерфейсе каждый раз, когда вам необходимо знать, есть ли изменения или нет.
Идея состоит в том, чтобы обновить флаги внутри коллекции и бизнес-объекта, чтобы определить, изменилось или нет членство в коллекции или какая-либо конкретная запись в коллекции.
Реализация довольно проста:
Добавление свойства HasChanged в класс бизнес-объекта.
Добавить свойство AnyDeleted в коллекцию. Это будет установлено только если элементы удалены из коллекции.
Инициализировать эти значения как ложные после чтения записей из БД.
(Теперь полудатая часть). Для каждого свойства в классе установите для свойства HasChanged значение true, если значение действительно изменится. Будьте осторожны с нулевыми значениями. Например:
public bool IsSelected
{
get
{
return m_fIsSelected;
}
set
{
if (m_fIsSelected != value)
{
this.HasChanged = true;
m_fIsSelected = value;
}
}
}
Измените коллекцию, чтобы для свойства AnyDeleted было установлено значение true при удалении записи:
protected override void RemoveItem(int index)
{
this.AnyDeleted = true;
base.RemoveItem(index);
}
Наконец, добавьте метод в коллекцию, чтобы указать, изменилось ли что-нибудь или нет. Это метод, который вы будете вызывать для определения необходимости сохранения каких-либо изменений:
public bool HasAnyChanges()
{
// Exceptions are handled by the caller
// If anything was deleted, return true
if (this.AnyDeleted)
{
return true;
}
else
{
foreach (T theItem in this)
{
if (theItem.HasAnyChanges())
{
return true;
}
}
}
return false;
}