редактирование объектов и флаг isDirty()
Я работаю над системой, когда пользователь может редактировать существующие объекты (точнее," фильтровать " объекты домена) через GUI. В качестве подсказки пользовательского интерфейса мы хотим включить кнопку сохранения, только если пользователь действительно изменил что-то в объекте. Мне было интересно, есть ли у кого-нибудь опыт работы с этой проблемой и как лучше всего подойти к этому.
Я думал о добавлении флага isDirty () к объекту домена. Когда пользователь начинает редактировать фильтр, я бы сделал копию, передал это к GUI и пусть пользователь вносит изменения в копию. Привязка к флагу isDirty () затем включит/отключит кнопку Сохранить. При сохранении различия затем объединяются в исходный объект и сохраняются.
кроме того, я думал, что произойдет, если пользователь отменит изменения, которые он внес в объект. Затем флаг isDirty () должен возвращать false. Поэтому я думаю, что единственный способ достичь этого-сохранить исходное значение каждого свойства внутри домена объект.
какие идеи?
7 ответов
правильно!
кроме того, вы можете выставить два метода: BeginEdit-в этом методе ваш флаг IsDirty помечается как True. Это означает, что вы делаете модификацию. Вызовите этот метод, когда вы собираетесь внести изменения
CancelEdit-в этом методе сбросьте флаг IsDirty на False. Значит, у вас есть arborted процесс редактирования и возвращается в исходное состояние. Вызовите этот метод при отмене любых внесенных изменений.
и один раз любой изменения сохраняются, вы также сбрасываете флаг IsDirty в False.
надеюсь, это поможет.
Если вы используете .NET framework, вы можете взглянуть на CSLA .NET framework от Rockford Lhotka:http://www.lhotka.net/cslanet/Default.aspx
CSLA-это зрелый фреймворк, который включает в себя управление состоянием объекта (IsDirty), функциональность отмены, привязку данных и многое другое, а также бесплатный и с открытым исходным кодом.
есть несколько интерфейсов, которые вы можете реализовать, чтобы помочь с отслеживанием изменений и отменить: INotifyPropertyChanged и IEditableObject. Оба этих интерфейса позволяют объекту хорошо играть с привязкой данных.
public class Person : INotifyPropertyChanged, IEditableObject
{
private bool isDirty;
public bool IsDirty
{
get { return isDirty; }
}
private string firstname = string.Empty;
public string Firstname
{
get { return firstname; }
set
{
if (firstname == value) return;
firstname = value;
NotifyPropertyChanged("Firstname");
}
}
private string lastname = string.Empty;
public string Lastname
{
get { return lastname; }
set
{
if (lastname == value) return;
lastname = value;
NotifyPropertyChanged("Lastname");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
isDirty = true;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private bool inTrans;
private Person copy;
public void BeginEdit()
{
if (!inTrans)
{
if (copy == null)
copy = new Person();
copy.isDirty = isDirty;
copy.Firstname = Firstname;
copy.Lastname = Lastname;
inTrans = true;
isDirty = false;
}
}
public void CancelEdit()
{
if (inTrans)
{
isDirty = copy.isDirty;
Firstname = copy.Firstname;
Lastname = copy.Lastname;
inTrans = false;
}
}
public void EndEdit()
{
if (inTrans)
{
copy = null;
inTrans = false;
}
}
}
Если у вас есть набор объектов, которые редактируются, вам, вероятно, понадобится что-то большее, чем логический флаг для isDirty(). Эта проблема не отличается от подсчета ссылок, т. е. увеличивает грязный счет при редактировании и уменьшает при отмене. Если вы поддерживаете undo, я подозреваю, что вы закончите с довольно волосатой логикой. Я бы держал его подальше от ваших объектов домена.
Да, это хорошо работает. Вместо отмены я использую метод IsDirty для обозначения того, что что-то могло изменить запись, а затем это вызывает мою "логику изменения записи". Я разработал свою собственную структуру, где каждое поле таблицы фактически является свойством объекта. Каждый раз, когда поле записывается в объекты, устанавливается флаг "isDirty". В методе "SaveObject" объекта (на самом деле его вспомогательный класс, но может быть легко в объекте, но я хотел, чтобы возможность сохранения объектов в различные манеры, как xml, база данных, ect.), Я проверяю IsDirty, и если его false, то я пропускаю сохранение. Это упрощает логику, поскольку каждый раз, когда у меня была возможность изменить объект, я вызываю SaveObject и позволяю фреймворку обрабатывать его.
в зависимости от вашего домена, вы можете использовать равенство для проверки различий. Сохраните исходный объект и сделайте копию объекта для редактирования. В любое время, когда может быть выполнено редактирование, измените пользовательский интерфейс соответствующим образом.
преимущество этого предложения заключается в том, что он не придерживается определенных функций GUI (флаг isDirty ()) на ваших объектах домена, но YMMV
Если вы поддерживаете операцию отмены на уровне детализации больше, чем "отменить все с момента последнего сохранения", я бы предложил стек отмены. Когда что-то редактируется, оно (или это функтор операции отмены или делегат) добавляется в стек. Когда вы отменяете, вы просто поп стек и отменить операцию выскочил. Ваш флаг isDirty () - это просто проверка, содержит ли стек отмены элементы, а не дополнительное хранилище и логику для обновления.