Я делал некоторые тесты о сложной привязке данных .NET, и мне нужно иметь некоторые советы для изменения отката, выполненного пользователем. Предположим, например, что у меня есть 2 классов в моем BL слоя:.NET Сложные привязки возвращают изменения
«Человек» представляют ядро человека объект:
internal class Person{
public String Name{get; set;}
public String Surname{get; set;}
public int Age { get; set; }
}
«PeopleList» представляет список лица объекта:
internal class PeopleList : List<Person> {
//Let's assume that this class has a whole bunch of function with a complex business logic in it.
public Person[] getPeopleByName(String name)
{
return this.Where(x => String.Compare(name, x.Name, true) == 0).ToArray();
}
public Person[] getPeopleByAge(int age)
{
return this.Where(x => x.Age.Equals(age)).ToArray();
}
}
Теперь я хочу, чтобы пользователь редактировал экземпляр объекта PeopleList через форму с помощью DataGridView. Так я создал окно формы приложения и Load() событие я сделал это:
private void frmTest_Load(object sender, EventArgs e)
{
//Intialize _peopleList object
_peopleList = new PeopleList();
this.initializePeopleWithTestData();
//Initialize _peopleBindingList by passing PeopleList (it inherits from List<Of ?> and it implements IList interface)
this._peopleBindingList = new BindingList<Person>(_peopleList);
//Initialize _peopleBindingSource
this._peopleBindingSource = new BindingSource();
this._peopleBindingSource.DataSource = this._peopleBindingList;
this._peopleBindingSource.SuspendBinding(); //Let's suspend binding to avoid _peopleList to be modified.
//Set peopleBindingList as DataSource of the grid
this.dgwPeople.DataSource = _peopleBindingSource;
}
С вышеупомянутым кодом я могу просмотреть/редактировать/удалять/добавлять человек в dgwPeople (это мой DataGridView) без проблем , но даже если я назвал «SuspendBinding()» над BindingSource, если пользователь редактирует сетку, система привязки сразу же влияет на данные, содержащиеся в моем объекте _peopleList! И это не хорошо, потому что таким образом я теряю исходную версию своих данных, и я не могу откатить их больше, если пользователь решил отменить изменения.!
В простой привязке есть фантастический атрибут «DataSourceUpdateMode», который позволяет мне решить, когда привязка должна повлиять на источник данных. Если я установил его в «Никогда», мне нужно явно вызвать метод Write() для фиксации изменений. Есть ли что-то подобное для сложной привязки?
Как я могу избежать привязки, чтобы немедленно повлиять на мои исходные данные в сложной привязке? Есть ли способ изменения отката (кроме сохранения копии клонов исходного объекта)? Есть ли какой-либо шаблон, который помогает справляться с подобными ситуациями?
Вы можете скачать мой тестовый раствор (VS2012) here
Спасибо заранее!
DataTable будет делать это через AcceptChanges. Или в классе вы можете сохранить исходное значение или вы могли бы сделать копию данных в классе. Я бы добавил класс AcceptChanges или RollBackChanges. – Paparazzi
Благодарим за отзыв. Эффективно это довольно элегантное решение, но применимое только в определенных контекстах ... в реальных случаях бизнес-классы, такие как Person и PersonList, обычно находятся в отдельных логических сборках (поэтому очень сложно внести изменения). Кроме того, эти сборки не имеют ссылок на материал UI, поэтому я не думаю, что это хорошая идея, чтобы бизнес-класс реализовал связанные с UI методы/интерфейс, такие как «INotifiyPropertyChanged». Я совершенно неправ? – GiveEmTheBoot
Если INotifiyPropertyChanged совершенно не прав, Microsoft полностью ошибается. Как вы ожидаете, чтобы пузырьки изменились с уровня данных на пользовательский интерфейс, если вы не реализуете INotifiyPropertyChanged? Как откат пользовательского интерфейса? – Paparazzi