Anjo Gasa

I have one main business object in an application, which is a container for various other business objects, themselves container other business objects. It is bound throughout various aspects of the user interface using a BindingSource and its Current property. The object can then be "processed" so to speak, any number of times. I would like to be able to tell if the object has changed in between successive processes. I have looked at these various options:

1. Since all my business objects implement INotifyPropertyChanged, I added a dirty flag in each object that gets set when a property changes. The problem is I have no way for this to be reflected to the parent object, and eventually my main object.

2. Event handlers for BindingSource::CurrentItemChanged. However this only detects changes based on the CurrentChanged event or when properties of the CurrentItem change, so it won't detect changes to child objects.

3. CurrencyManager::ItemChanged event. Get the CurrencyManager via the BindingContext for my BindingSource and attach handlers for the ItemChanged event. Again it seems to only detect changes to the parent object and not children.

Anjo


Re: Windows Forms Data Controls and Databinding Determining when a bound business objects, or any of its children, have changed

Yu Guo – MSFT

Hi, Anjo,

Based on my understanding, you want to get notified when the properties of your main business object or child business objects changed, don't you

I think you can just register the child business object's PropertyChanged event in the main object, and you can get to know which object get changed through sender.
For example.

Code Block

//We have a Main Business Object and two Child Business Objects.

public class BusinessMain : INotifyPropertyChanged

{

private BussinessObject1 obj1;

public BussinessObject1 Obj1

{

get { return obj1; }

set { obj1 = value; }

}

private BussinessObject2 obj2;

public BussinessObject2 Obj2

{

get { return obj2; }

set { obj2 = value; }

}

private string variable = "main";

public string Variable

{

get { return variable; }

set

{

if (variable != value)

{

variable = value;

PropertyChanged(this, new PropertyChangedEventArgs("variable"));

}

}

}

public BusinessMain()

{

obj1 = new BussinessObject1();

obj2 = new BussinessObject2();

obj1.PropertyChanged += new PropertyChangedEventHandler(objPropertyChanged);

obj2.PropertyChanged += new PropertyChangedEventHandler(objPropertyChanged);

}

void objPropertyChanged(object sender, PropertyChangedEventArgs e)

{

PropertyChanged(sender, e);

}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

#endregion

}

public class BussinessObject1 : INotifyPropertyChanged

{

private string variable = "var1";

public string Variable

{

get { return variable; }

set

{

if (variable != value)

{

variable = value;

PropertyChanged(this, new PropertyChangedEventArgs("variable"));

}

}

}

public override string ToString()

{

return variable;

}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

#endregion

}

public class BussinessObject2 : INotifyPropertyChanged

{

private string variable = "var2";

public string Variable

{

get { return variable; }

set

{

if (variable != value)

{

variable = value;

PropertyChanged(this, new PropertyChangedEventArgs("variable"));

}

}

}

public override string ToString()

{

return variable;

}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

#endregion

}

And in your application, you can try these codes

Code Block

BusinessMain main;

private void Form1_Load(object sender, EventArgs e)

{

main = new BusinessMain();

main.PropertyChanged += new PropertyChangedEventHandler(main_PropertyChanged);

BindingSource bs = new BindingSource();

bs.DataMember = "BusinessMain";

bs.DataSource = main;

dataGridView1.AutoGenerateColumns = false;

DataGridViewTextBoxColumn column1 = new DataGridViewTextBoxColumn();

column1.DataPropertyName = "Obj1";

dataGridView1.Columns.Add(column1);

DataGridViewTextBoxColumn column2 = new DataGridViewTextBoxColumn();

column2.DataPropertyName = "Obj2";

dataGridView1.Columns.Add(column2);

DataGridViewTextBoxColumn column3 = new DataGridViewTextBoxColumn();

column3.DataPropertyName = "Variable";

dataGridView1.Columns.Add(column3);

dataGridView1.DataSource = bs;

}

void main_PropertyChanged(object sender, PropertyChangedEventArgs e)

{

MessageBox.Show(sender.GetType().ToString() + " " + e.PropertyName);//We can get to know which one has changed

}

private void button1_Click(object sender, EventArgs e)

{

main.Obj1.Variable = "happy"; //We change the value one by one

main.Obj2.Variable = "hello";

main.Variable = "yes";

}

More info

http://msdn2.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

Hope this helps,
Regards