I understand that one can raise an event in the class that the implementation declaration occurs, but I wish to raise the event at the base class level and have the derived class's event be raised:
public interface IFoo
{
event EventHandler<FooEventArgs> FooValueChanged;
void RaiseFooValueChanged(IFooView sender, FooEventArgs e);
}
[TypeDescriptionProvider(typeof(FooBaseImplementor))]
public abstract class FooBase : Control, IFoo
{
public virtual event EventHandler<FooEventArgs> FooValueChanged;
public void RaiseFooValueChanged(IFooView sender, FooEventArgs e)
{
FooValueChanged(sender, e);
}
}
I cannot have the FooValueChanged event abstract, because then the base class cannot raise the event. Current the code runs, but the call FooValueChanged(sender, e) throws a NullReferenceException because it doesn't call the derived class's event, only that of the base class.
Where am I going wrong?
I can have the event and the raiser both abstract, but then I need to remember to call FooValueChanged(sender, e) in every single derived class. I'm trying to avoid this while being able to use the Visual Studio designer for derived controls.
Note first, the event declaration that you are using is a short-hand notation in C#:
public event EventHandler Event;
public void RaiseEvent() {
this.Event(this, new EventArgs());
}
Is equivalent to:
private EventHandler backEndStorage;
public event EventHandler Event {
add { this.backEndStorage += value; }
remove { this.backEndStorage -= value; }
}
public void RaiseEvent() {
this.backEndStorage(this, new EventArgs());
}
Where backEndStorage is a multi-cast delegate.
Now you can rewrite your code:
public interface IFoo
{
event EventHandler<FooEventArgs> FooValueChanged;
void RaiseFooValueChanged(IFooView sender, FooEventArgs e);
}
[TypeDescriptionProvider(typeof(FooBaseImplementor))]
public abstract class FooBase : Control, IFoo
{
protected event EventHandler<FooEventArgs> backEndStorage;
public event EventHandler<FooEventArgs> FooValueChanged {
add { this.backEndStorage += value; }
remove { this.backEndStorage -= value; }
}
public void RaiseFooValueChanged(IFooView sender, FooEventArgs e)
{
this.backEndStorage(sender, e);
}
}
public class FooDerived : FooBase {
public event EventHandler<FooEventArgs> AnotherFooValueChanged {
add { this.backEndStorage += value; }
remove { this.backEndStorage -= value; }
}
}
So now when events are added on the derived class, they will actually be added to the backEndStorage of the base class, hence allowing the base class to call the delegates registered in the derived class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With