U
uler3161
Guest
This is probably going to be hard to understand, but here it goes...
I have two business objects that inherit from a base class that implements INotifyPropertyChanged: ParentObject and ChildObject as seen below.
I have two forms open at the same time. The first is a search form. It has a DataGridView with a BindingSource containing a list of ParentObjects.
The second form is an editor for a single ParentObject. It has a button that adds ChildObjects to the ParentObject.Children list. It has a DataGridView with BindingSource bound to ParentObject.Children. Finally, theres a disabled TextBox that is bound to the ParentValue property on the ParentObject.
My expectation is that I would edit a ParentObject. Add a ChildObject. Change the ChildObject.ChildValue by editing the cell in the DataGridView. And then trigger the ParentValue TextBox to update and show the new ParentValue.
What happens depends on whether the ParentObject in my editor is "Equal" to one of the ParentObjects in the search form. They are guaranteed to be different instances. However, it appears that the Databinding uses Equals/GetHashCode during binding, and I have overridden these methods to consider records with the same ID to be equal.
If Im editing a record that isnt in the search form, everything works great. So lets say I have ParentObjects with ID 1, 2, and 3 in the search view. If Im editing ParentObject #4 its fine.
But, lets say Im editing a ParentObject #3. The ParentValue TextBox will not update unless I rebind it.
I think the issue is Im apparently using the same BindingContext between both the search and edit forms. Assigning a new BindingContext to my editor form doesnt help. Regardless of whether the bindings of both forms are tied together, I dont understand why it wouldnt update the ParentValue TextBox. I would expect any control bound to ParentValue of ParentObject #3 on either form would be updated, but thats not the case.
If it helps I can paste more code or maybe even attach a complete solution showing the problem.
public class BusinessBase : INotifyPropertyChanged
{
public int ID
{
get;
set;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(
object sender,
string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(sender, new PropertyChangedEventArgs(propertyName));
}
}
public class ChildObject : BusinessBase
{
private decimal _childValue;
public decimal ChildValue
{
get
{
return _childValue;
}
set
{
_childValue = value;
OnPropertyChanged("ChildValue");
}
}
}
public class ParentObject : BusinessBase
{
private readonly IList<ChildObject> _children = new List<ChildObject>();
public decimal ParentValue
{
get
{
return _children.Sum(p => p.ChildValue) * 12;
}
}
public IList<ChildObject> Children
{
get
{
return _children;
}
}
public void Add(ChildObject child)
{
if (_children.Contains(child))
{
return;
}
_children.Add(child);
child.PropertyChanged += OnChildChanged;
OnPropertyChanged("Children");
}
public override bool Equals(object obj)
{
var item = obj as ParentObject;
if (item == null)
return false;
if (item == this)
return true;
return item.ID == ID;
}
public override int GetHashCode()
{
return ID;
}
private void OnChildChanged(
object a,
PropertyChangedEventArgs b)
{
OnPropertyChanged(this, "ParentValue");
}
}
Continue reading...
I have two business objects that inherit from a base class that implements INotifyPropertyChanged: ParentObject and ChildObject as seen below.
I have two forms open at the same time. The first is a search form. It has a DataGridView with a BindingSource containing a list of ParentObjects.
The second form is an editor for a single ParentObject. It has a button that adds ChildObjects to the ParentObject.Children list. It has a DataGridView with BindingSource bound to ParentObject.Children. Finally, theres a disabled TextBox that is bound to the ParentValue property on the ParentObject.
My expectation is that I would edit a ParentObject. Add a ChildObject. Change the ChildObject.ChildValue by editing the cell in the DataGridView. And then trigger the ParentValue TextBox to update and show the new ParentValue.
What happens depends on whether the ParentObject in my editor is "Equal" to one of the ParentObjects in the search form. They are guaranteed to be different instances. However, it appears that the Databinding uses Equals/GetHashCode during binding, and I have overridden these methods to consider records with the same ID to be equal.
If Im editing a record that isnt in the search form, everything works great. So lets say I have ParentObjects with ID 1, 2, and 3 in the search view. If Im editing ParentObject #4 its fine.
But, lets say Im editing a ParentObject #3. The ParentValue TextBox will not update unless I rebind it.
I think the issue is Im apparently using the same BindingContext between both the search and edit forms. Assigning a new BindingContext to my editor form doesnt help. Regardless of whether the bindings of both forms are tied together, I dont understand why it wouldnt update the ParentValue TextBox. I would expect any control bound to ParentValue of ParentObject #3 on either form would be updated, but thats not the case.
If it helps I can paste more code or maybe even attach a complete solution showing the problem.
public class BusinessBase : INotifyPropertyChanged
{
public int ID
{
get;
set;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(
object sender,
string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(sender, new PropertyChangedEventArgs(propertyName));
}
}
public class ChildObject : BusinessBase
{
private decimal _childValue;
public decimal ChildValue
{
get
{
return _childValue;
}
set
{
_childValue = value;
OnPropertyChanged("ChildValue");
}
}
}
public class ParentObject : BusinessBase
{
private readonly IList<ChildObject> _children = new List<ChildObject>();
public decimal ParentValue
{
get
{
return _children.Sum(p => p.ChildValue) * 12;
}
}
public IList<ChildObject> Children
{
get
{
return _children;
}
}
public void Add(ChildObject child)
{
if (_children.Contains(child))
{
return;
}
_children.Add(child);
child.PropertyChanged += OnChildChanged;
OnPropertyChanged("Children");
}
public override bool Equals(object obj)
{
var item = obj as ParentObject;
if (item == null)
return false;
if (item == this)
return true;
return item.ID == ID;
}
public override int GetHashCode()
{
return ID;
}
private void OnChildChanged(
object a,
PropertyChangedEventArgs b)
{
OnPropertyChanged(this, "ParentValue");
}
}
Continue reading...