我正在对复杂的.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
提前致谢!
答案 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; }
}