C#: Raising an inherited event
I am assuming I cannot access these events the same as other inherited members?
Precisely. It's customary to provide a protected function OnXyz
or RaiseXyz
for each event in the base class to enable raising from inherited classes. For example:
public event EventHandler Loading;
protected virtual void OnLoading() {
EventHandler handler = Loading;
if (handler != null)
handler(this, EventArgs.Empty);
}
Called in the inherited class:
OnLoading();
What you have to do , is this:
In your base class (where you have declared the events), create protected methods which can be used to raise the events:
public class MyClass
{
public event EventHandler Loading;
public event EventHandler Finished;
protected virtual void OnLoading(EventArgs e)
{
EventHandler handler = Loading;
if( handler != null )
{
handler(this, e);
}
}
protected virtual void OnFinished(EventArgs e)
{
EventHandler handler = Finished;
if( handler != null )
{
handler(this, e);
}
}
}
(Note that you should probably change those methods, in order to check whether you have to Invoke the eventhandler or not).
Then, in classes that inherit from this base class, you can just call the OnFinished or OnLoading methods to raise the events:
public AnotherClass : MyClass
{
public void DoSomeStuff()
{
...
OnLoading(EventArgs.Empty);
...
OnFinished(EventArgs.Empty);
}
}
You can only access an event in the declaring class, as .NET creates private instance variables behind the scenes that actually hold the delegate. Doing this..
public event EventHandler MyPropertyChanged;
is actually doing this;
private EventHandler myPropertyChangedDelegate;
public event EventHandler MyPropertyChanged
{
add { myPropertyChangedDelegate += value; }
remove { myPropertyChangedDelegate -= value; }
}
and doing this...
MyPropertyChanged(this, EventArgs.Empty);
is actually this...
myPropertyChangedDelegate(this, EventArgs.Empty);
So you can (obviously) only access the private delegate instance variable from within the declaring class.
The convention is to provide something like this in the declaring class..
protected virtual void OnMyPropertyChanged(EventArgs e)
{
EventHandler invoker = MyPropertyChanged;
if(invoker != null) invoker(this, e);
}
You can then call OnMyPropertyChanged(EventArgs.Empty)
from anywhere in that class or below the inheritance heirarchy to invoke the event.