nested bindingsource

nested bindingsource

Old forum URL: forums.lhotka.net/forums/t/2214.aspx


fred posted on Friday, January 26, 2007

I have a manager class

Public class Manager
{
   string Name; //manager name
   stringcollection Members;
}

and  a list of Manager: 

            List<Manager> managers = new List<Manager>();
            Manager p;
           
            p = new Manager("p1");
            p.Members = new System.Collections.Specialized.StringCollection();
            p.Members.Add("p1_attr1");
            p.Members.Add("p1_attr2");
            managers.Add(p);

            p = new Manager("p2");
            p.Members = new System.Collections.Specialized.StringCollection();
            p.Members.Add("p2_attr1");
            p.Members.Add("p2_attr2");
            managers.Add(p);

            parentBindingSource.DataSource=managers;

I have a form to edit managers: a textbox for editing name, a listbox for editing members.

this.parentBindingSource= new System.Windows.Forms.BindingSource(this.components);
his.ManagerBindingNavigator.BindingSource = this.parentBindingSource;
this.parentBindingSource.DataSource = typeof(Manager);
this.parentNameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.parentBindingSource, "Name", true));

this.childBindingSource = new System.Windows.Forms.BindingSource(this.components);
 this.childBindingSource.DataMember = "Members";
 this.childBindingSource.DataSource = this.parentBindingSource;
this.membersListBox.DataSource=this.childBindingSource;

My question is: if I add a member to listbox for Members and then choose to cancel the editing,  it doesn't work.

How can I implement this? I hope I can cancel the entire record editing no matter what changes you have made to the text box  for name or listbox for members

Thank you.

RockfordLhotka replied on Friday, January 26, 2007

Your example classes aren't shown inheriting from a CSLA base class, so you'd have to implement IEditableObject manually. You'd have an easier time if you inherit from BusinessBase.

The trick is to make sure you have an snapshot of the object's state before any adding or removing of items in the collection.

Assuming your collection is your root object, you probably want to call BeginEdit() explicitly on the collection itself before binding it to the BindingSource. That way its edit level will be 1 (and so will its children) before data binding gets involved.

Then, to cancel, you would need to do a CancelEdit() on the BindingSource first to reduce the current row's edit level. Then an explicit CancelEdit() on the collection itself to reduce the overall collection's edit level back to 0 - undoing any changes made to the collection, including additions or deletions of items.

fred replied on Saturday, January 27, 2007

Thank you for your response. Unfortunately, the collection  is not a root object. Instead it is a property in another class. it is like

public class Company
{
   string name;
   List<Department> Departments;
}

public class Department
{
  string name;
   List<Manager> Managers;
}
public class Manager:Employee
{
   int level;
}
public class Employee
{
 string Name;
}

I knew I could implement IEditableObject, but making a backup copy before editing is too expensive. Inheriting from BusinessBase doesn't seem to be able to simplify the implementation. Isn't there any better way to do this? 

Thanks

RockfordLhotka replied on Saturday, January 27, 2007

I hate to say it, but the only way to get your objects to return to a previous state is to have access to that previous state. The only way your objects will know to return to that previous state is if they implement IEditableObect - that's the way data binding works.
 
You can get to the previous state, generally speaking, in two ways: taking a snapshot of the object's state like I do in CSLA, or reloading the object from its original data source (like the database).
 
Of those two, it is usually cheaper to copy the data in memory than it is to reload everything from the database.
 
I didn't write all that n-level undo stuff into CSLA for fun you know :)  I wrote it to solve this exact issue.
 
Rocky
 

Copyright (c) Marimer LLC