У меня есть a BindingSource
то, что я использую в привязке данных winforms, и я хотел бы иметь своего рода подсказку для того, когда пользователь пытается закрыть форму после того, как они внесли изменения в данные. Своего рода "Вы уверены, что хотите выйти, не сохраняя изменения?"
Я знаю, что могу сделать это через BindingSource
CurrencyManager.ItemChanged
событие, просто зеркально отразив "изменило" булевскую переменную.
Однако я хочу больше надежной функциональности. Я хотел бы знать, когда текущие данные отличаются от исходных данных. Событие просто говорит мне если измененные somethings. Пользователь мог все еще изменить свойство, поразить отмену, и я буду все еще думать, что существует изменение в данных для сохранения.
Я хочу подражать этой схожей функциональности блокнота
Если это не возможно, то должен я идти с ItemChanged
обработчик событий, как обрисовано в общих чертах выше или является там лучшим путем?
Для записи я ищу что-то вроде
bool HasChanged()
{
return this.currentState != this.initialState;
}
не это
bool HasChanged()
{
// this._hasChanged is set to true via event handlers
return this._hasChanged;
}
Я не должен просто управлять текущим состоянием и начальным состоянием сам, я ищу способ захватить ту информацию от BindingSource
Если я могу получить эту функциональность от BindingSource
его путь, более идеальный, так как я смогу использовать функциональность на многих различных источниках данных, независимо от типа, и т.д.
Вам нужно будет реализовать интерфейс INotifyPropertyChanged
внутри классов объектов, а затем улавливать каждый раз, когда происходит изменение, с помощью соответствующих обработчиков событий для класс вашего типа в свойстве DataSource
BindingSource
.
Единственный объект, предлагающий то, что вам нужно, - это DataSet
, содержащий как исходное, так и текущее (измененное) состояние постоянной сущности. Затем, когда кто-то отменяет, все, что вам нужно вызвать, - это метод Rollback ()
. Когда кто-то принимает изменения, подойдет вызов метода AcceptChanges ()
.
Помимо DataSet
, возможно, рассмотрение ORM, такого как NHibernate, выполнит эту работу за вас, а также позволит вам использовать определенные пользователем объекты вместо DataSet
. Сохранение ISession
API в вашей форме позволит ISession отслеживать ваши изменения, какими бы они ни были для любого объекта, если это известно NHibernate.
Другое решение, реализующее интерфейс INotifyPropertyChanged
, находится в средстве установки свойств, вы можете сохранить исходное значение в частном поле или для каждого свойства объекта. Вы можете просто иметь абстрактный класс со свойством HasChanges
, возвращать, независимо от того, находится ли каждое свойство в исходном состоянии, а затем возвращать true или false соответственно.
У меня вопрос по поводу нашего интересного начального обсуждения. Я просто хочу убедиться в одном. Назовем это языковым барьером, если хотите. Но публикация события PropertyChanged
через интерфейс INotifyPropertyChanged
также каким-то образом «откатит» объект до исходного состояния. Единственная деталь, о которой вы должны позаботиться, это то, что если пользователь говорит, что не хочет сохранять изменения, перезагрузите этот CurrentItem из базовой базы данных с помощью класса BackgroundWorker
и готово! Никакого отставания от вашего графического интерфейса, ваш пользователь отменил изменения, и вы сбросили объект в его исходное состояние по умолчанию!
Что ж, я думаю, здесь достаточно деталей, чтобы составить себе представление, плюс все другие хорошие ответы, предоставленные другими. Я уверен, что вы найдете свой способ добиться того, чего хотите.
Всего наилучшего! =)
Когда вы открываете свою деталь, вы можете создать клон объекта, который вы собираетесь изменить.
Затем, когда пользователь пытается закрыть форму, вы можете сравнить клон (объект в исходном состоянии) с измененным (или нет) объектом. Если клон и объект не равны, вы можете запросить пользователя.
Вместо того, чтобы немного переворачивать, вы можете проверить состояние по моментальному снимку вашего начального состояния.
Воля прав, вам следует реализовать INotifyPropertyChanged
, в идеале вместе с IDataInfoError
, чтобы получить видимую информацию для вашего пользователей.
Чтобы ваши объекты получали состояние и уведомление при редактировании, попробуйте использовать интерфейс IEditableObject
.
Все три интерфейса по умолчанию используются WinForms и помогают облегчить жизнь программистам.