2013-11-30 2 views
0

Я делал некоторые тесты о сложной привязке данных .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

Спасибо заранее!

+0

DataTable будет делать это через AcceptChanges. Или в классе вы можете сохранить исходное значение или вы могли бы сделать копию данных в классе. Я бы добавил класс AcceptChanges или RollBackChanges. – Paparazzi

+0

Благодарим за отзыв. Эффективно это довольно элегантное решение, но применимое только в определенных контекстах ... в реальных случаях бизнес-классы, такие как Person и PersonList, обычно находятся в отдельных логических сборках (поэтому очень сложно внести изменения). Кроме того, эти сборки не имеют ссылок на материал UI, поэтому я не думаю, что это хорошая идея, чтобы бизнес-класс реализовал связанные с UI методы/интерфейс, такие как «INotifiyPropertyChanged». Я совершенно неправ? – GiveEmTheBoot

+1

Если INotifiyPropertyChanged совершенно не прав, Microsoft полностью ошибается. Как вы ожидаете, чтобы пузырьки изменились с уровня данных на пользовательский интерфейс, если вы не реализуете INotifiyPropertyChanged? Как откат пользовательского интерфейса? – Paparazzi

ответ

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; } 
} 
Смежные вопросы