The problem is that Delegate
s are immutable.
If you add a handler to an event, it creates a new Delegate
instance which contains the old handlers and the newly added handler. The old Delegate
is not modified and is discarded.
When I write, value.AnEvent += AnEvent
, it adds the Delegate
containing the current handlers (if any) to the inner class's event. However, changes to the outer class's event are ignored because they don't change the Delegate
instance that I added to the inner classes event. Similarly, if I remove a handler after setting the Inner
property, the handler isn't removed from the inner class's event.
There are two correct ways to do this.
I can make my own handler that invokes the wrapper's event, like this:
public event EventHandler AnEvent;
public OtherClass Inner {
get { /* ... */ }
set {
if(Inner != null)
Inner.AnEvent -= Inner_AnEvent;
//...
if(value != null)
value.AnEvent += Inner_AnEvent;
//...
}
}
void Inner_AnEvent(object sender, EventArgs e) {
var handler = AnEvent;
if (handler != null) handler(sender, e);
}
The other way is to make a custom event in the wrapper that adds its handlers to the inner class's event, like this:
EventHandler anEventDelegates
public OtherClass Inner {
get { /* ... */ }
set {
//...
if(value != null)
value.AnEvent += anEventDelegates;
//...
}
}
public event EventHandler AnEvent {
add {
anEventDelegates += value;
if (Inner != null) Inner.AnEvent += value;
}
remove {
anEventDelegates -= value;
if(Inner != null) Inner -= value;
}
}
Note that this is not entirely thread-safe.
I solved this problem myself and am posting the question & answer for the benefit of people with similar problems.