I have a custom INotifyCollectionChanged
class, which essentially just wraps around the standard ObservableCollection
. Whenever something is added/removed, the CollectionChanged
event is raised as expected. However, when I try to listen to this event using a WeakEventListener
, the listener never receives the event. Why is this happening and how do I fix this?
In below sample, I'd expect a NotImplementedException
to be thrown, but the test case succeeds (which clearly indicates that the event is truly raised). If you change the collection to be an ObservableCollection
instead of a Wrapper
, the exception does get thrown as expected.
public class Test : IWeakEventListener
{
private class Wrapper : INotifyCollectionChanged
{
private readonly ObservableCollection<string> _internal
= new ObservableCollection<string>();
public void Add(string s)
{
_internal.Add(s);
}
public event NotifyCollectionChangedEventHandler CollectionChanged
{
add { _internal.CollectionChanged += value; }
remove { _internal.CollectionChanged -= value; }
}
}
public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
throw new NotImplementedException();
}
[Test]
public void CustomCollectionTest()
{
//change to new ObservableCollection<string>() and the exception gets thrown
var collection = new Wrapper();
var raised = false;
collection.CollectionChanged += (o, e) => raised = true;
CollectionChangedEventManager.AddListener(collection, this);
collection.Add("foobar");
Assert.True(raised);
}
}
Possibly related but still unanswered:
Why WeakEventManager does not fire an event when the sender is not the nominal?
As to why, the issue is the same as in this question . Essentially, the source registered with the event manager has to be the same as the sender of the event.
As a workaround for this limitation, I just have to make sure that the Wrapper
sends the event, rather than directly using the event on the wrapped collection.
private class Wrapper : INotifyCollectionChanged
{
private readonly ObservableCollection<string> _internal
= new ObservableCollection<string>();
public Wrapper()
{
_internal.CollectionChanged += OnInternalChanged;
}
public void Add(string s)
{
_internal.Add(s);
}
private void OnInternalChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var toRaise = CollectionChanged;
if (toRaise != null)
toRaise(this, e);
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.