.NET Complex绑定还原更改

时间:2013-11-30 13:50:58

标签: .net data-binding rollback

我正在对复杂的.NET数据绑定进行一些测试,我需要一些建议才能回滚用户所做的更改。例如,让我们假设我的BL层中有2个类:

“人”代表核心人物对象:

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();
    }
}

现在我想让用户通过带有DataGridView的表单编辑PeopleList对象的实例。 所以我创建了一个Windows窗体应用程序,在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)中的人没有问题,但即使我在BindingSource上调用“SuspendBinding()”,如果用户编辑网格,绑定系统会立即影响我的_peopleList对象中包含的数据!这并不好,因为这样我放弃了原始版本的数据,如果用户决定取消更改,我就不能再回滚它们了。!

在简单绑定中有一个很棒的属性“DataSourceUpdateMode”,让我决定绑定何时必须影响数据源。如果我将其设置为“从不”,我必须显式调用Write()方法来提交更改。复杂的绑定有类似的东西吗?

如何避免绑定在复杂绑定中立即影响我的原始数据?有没有办法回滚更改(除了保留原始对象的克隆副本)?是否有任何模式有助于处理这种情况?

您可以下载我的测试解决方案(VS2012)here

提前致谢!

1 个答案:

答案 0 :(得分:1)

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; }
}