My objective is to make a list that would fire an event when element within changes. Idea is to create a BindingList of entities that implement INotifyChanged to forward that event to ViewModel.
What i currently have:
public class ViewModel
{
public TagPresenter Tags {get;}
public ViewModel()
{
Tags = new TagPresenter();
Tags.TagCollection.ListChanged += (object o, ListChangedEventargs e) => { DataAccessor.UpdateTag(o[e.NewIndex]); };
foreach(var tag in DataAccessor.GetTags())
Tags.TagCollection.Add(new TagEntity(tag, Tags.TagCollection));
}
}
public class TagPresenter
{
public BindingList<object> TagCollection {get;}
public TagPresenter()
{
TagCollection = new BindingList<object>();
}
}
public class TagEntity : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged {get;}
public Command ChangeState {get;}
public TagEntity(string tag, BindingList<object> parent)
{
ChangeState = new Command(new Action(() => {
NotifyPropertyChanged("Property");
}));
}
public void NotifyPropertyChanged(string _property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_property));
}
}
In this code, ListChanged event triggers when new entities are added into the list in foreach loop, but not when i trigger PropertyChanged of entity within BindingList (breakpoint within NotifyPropertyChanged method stops, but ListChanged event does not fire)
OK, figured it out, the problem was due to boxing\unboxing of TagEntity to and from object in BindingList. Once i've added abstract class TagBase that implemented INotifyChanged, and switched collection to BindingList it got to work as intended:
public class ViewModel
{
public TagPresenter Tags {get;}
public ViewModel()
{
Tags = new TagPresenter();
Tags.TagCollection.ListChanged += (object o, ListChangedEventargs e) => { DataAccessor.UpdateTag(o[e.NewIndex]); };
foreach(var tag in DataAccessor.GetTags())
Tags.TagCollection.Add(new TagEntity(tag, Tags.TagCollection));
}
}
public class TagPresenter
{
public BindingList<TagBase> TagCollection {get;}
public TagPresenter()
{
TagCollection = new BindingList<TagBase>();
}
}
public abstract class TagBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged {get;}
public void NotifyPropertyChanged(string _property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_property));
}
}
public class TagEntity : TagBase
{
public Command ChangeState {get;}
public TagEntity(string tag, BindingList<TagBase> parent)
{
ChangeState = new Command(new Action(() => {
NotifyPropertyChanged("Property");
}));
}
}