문제

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!

도움이 되었습니까?

해결책

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; }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top