I have implemented CollectionChanged for an ObservableCollection just like here: Implementing CollectionChanged
Is there a possibility in the OnCollectionChanged method to find out what the name of the changed property is?
EDIT: A history should be written if there is any change in the class. There are three cases I want to achieve:
Property inside a collection is changed: same problem as 2) I don't know the name (and index) of the ch
public class ParentClass : BaseModel
{
public ParentClass()
{
Children = new ObservableCollection<SomeModel>();
Children.CollectionChanged += Oberservable_CollectionChanged;
}
private string id;
public string Id
{
get
{
return id;
}
set
{
string oldId = id;
id = value;
OnPropertyChanged(oldArticleId,id);
}
}
public ObservableCollection<SomeModel> Children { get; set; }
protected virtual void OnPropertyChanged(object oldValue, object newValue, [CallerMemberName] string propertyName = null)
{
//1) Entry is added to history (this part is working)
}
protected void Oberservable_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (INotifyPropertyChanged added in e.NewItems)
{
added.PropertyChanged += OnPropertyChangedHandler;
OnCollectionChanged(CollectionChangedModel.Action.Added, added);
}
}
if (e.OldItems != null)
{
foreach (INotifyPropertyChanged removed in e.OldItems)
{
removed.PropertyChanged -= OnPropertyChangedHandler;
OnCollectionChanged(CollectionChangedModel.Action.Removed, removed);
}
}
}
protected virtual void OnCollectionChanged(CollectionChangedModel.Action action, object value)
{
//2) TODO: History should be written, but I don't have the property name
}
public void OnPropertyChangedHandler(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
//3) TODO: History about changed property in child-class (not working because of missing property name and index)
}
}
This is correct:
Children = new ObservableCollection<SomeModel>();
Children.CollectionChanged += Oberservable_CollectionChanged;
Though you have to ensure nobody will change collection, e.g. like this:
public ObservableCollection<SomeModel> Children { get; }
or rather making it a full property and subscribing/unsubscribing in the setter.
And now regarding Oberservable_CollectionChanged
handler:
- Add and remove in collections: would be working if I know the name of the changed collection
Add sender
to your event.
Wrap arguments into ...EventArgs
class (make it immutable), see msdn.
public event EventHandler<MyCollectionChangedEventArgs> CollectionChanged;
protected virtual void OnCollectionChanged(object sender, MyCollectionChangedEventArgs e)
{
//2) TODO: History should be written, but I don't have the property name
// sender is name
// e.Action and e.Value are parameters
}
- Property inside a collection is changed: same problem as 2) I don't know the name (and index) of the ch
Wrap event handlers into instance containing event handler and value you need (I am leaving that task for you). If unsubscribing is not required, this can be easily achieved by using lamdba closures:
foreach (var added in e.NewItems.OfType<INotifyPropertyChanged>)
{
added.PropertyChanged += (s, e) =>
{
// you have `sender` here in addition to `s`, clever?
};
}