2015-03-26 3 views
1

У меня есть пользовательский класс INotifyCollectionChanged, который по существу просто обертывается вокруг стандарта ObservableCollection. Всякий раз, когда что-то добавляется/удаляется, событие CollectionChanged возникает, как ожидалось. Однако, когда я пытаюсь прослушать это событие, используя WeakEventListener, слушатель никогда не получает событие. Почему это происходит и как я могу это исправить?CollectionChangedEventManager не переадресовывает событие для пользовательской коллекции

В нижеприведенном примере я ожидаю, что будет выброшен 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?

ответ

1

Относительно того, почему этот вопрос так же, как в 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; 
}