internal class Person, iNotifyPropertyChanged
{
// todo implement NotifyPropertyChanged
private string name;
private string nameOrig;
public String Name
{
get {return name; }
set
{
if (name == value) return;
name = value;
NotifyPropertyChanged("Name");
}
}
public void RollBack() { Name = nameOrig; }
public void CommitChanges() { nameOrig = name; }
public Person (string Name) { name = Name; nameOrig = name; }
}
.NET Complex binding revert changes
-
06-08-2022 - |
Pregunta
I was doing some test about complex .NET databinding, and i need to have some advice in order to rollback changes made by the user. Let's assume, for example, that i've got 2 classes in my BL layer:
"Person" represent the core person object:
internal class Person{
public String Name{get; set;}
public String Surname{get; set;}
public int Age { get; set; }
}
"PeopleList" represent the list of person object:
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();
}
}
Now i want to let user edit an instance of a PeopleList object through a form with a DataGridView. So i created a windows form application and in Load() event i did this:
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;
}
With the above-mentioned code i can see/edit/delete/add people in dgwPeople (that's my datagridview) without problem, but even if i called "SuspendBinding()" over the BindingSource, if the user edits the grid, the binding system immediately affects the data contained into my _peopleList object! And this is not good because in this way i loose the original version of my data and i can't rollback them no more if the user decide to cancel changes.!
In the simple binding there's a fantastic attribute "DataSourceUpdateMode" that let me decide when the binding has to affect the datasource. If i set it to "Never" i have to call explicitly the Write() method to commit changes. Is there something similar for the complex binding?
How can i avoid binding to affect my original data immediately in complex binding? Is there any way to rollback changes (apart from keep a clone copy of the original object)? Is there any pattern that helps in handling this kind of situations?
You can download my test solution (VS2012) here
Thanks in advance!
Solución