CollectionChangedEventManager 不转发自定义集合的事件
CollectionChangedEventManager not forwarding event for custom collection
我有一个自定义 INotifyCollectionChanged
class,它基本上只是围绕标准 ObservableCollection
。每当某些东西是 added/removed 时,就会按预期引发 CollectionChanged
事件。但是,当我尝试使用 WeakEventListener
监听此事件时,监听器从未接收到该事件。为什么会发生这种情况,我该如何解决?
在下面的示例中,我希望抛出 NotImplementedException
,但测试用例成功(这清楚地表明事件确实引发了)。如果将集合更改为 ObservableCollection
而不是 Wrapper
,则会按预期抛出异常。
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);
}
}
可能相关但仍未得到答复:
Why WeakEventManager does not fire an event when the sender is not the nominal?
至于为什么,问题和this question一样。本质上,向事件管理器注册的源必须与事件的发送者相同。
作为此限制的解决方法,我只需要确保 Wrapper
发送事件,而不是直接在包装集合上使用事件。
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;
}
我有一个自定义 INotifyCollectionChanged
class,它基本上只是围绕标准 ObservableCollection
。每当某些东西是 added/removed 时,就会按预期引发 CollectionChanged
事件。但是,当我尝试使用 WeakEventListener
监听此事件时,监听器从未接收到该事件。为什么会发生这种情况,我该如何解决?
在下面的示例中,我希望抛出 NotImplementedException
,但测试用例成功(这清楚地表明事件确实引发了)。如果将集合更改为 ObservableCollection
而不是 Wrapper
,则会按预期抛出异常。
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);
}
}
可能相关但仍未得到答复:
Why WeakEventManager does not fire an event when the sender is not the nominal?
至于为什么,问题和this question一样。本质上,向事件管理器注册的源必须与事件的发送者相同。
作为此限制的解决方法,我只需要确保 Wrapper
发送事件,而不是直接在包装集合上使用事件。
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;
}