Reputation: 4769
I have a parent abstract class with several children classes. Eventually, I would like the progress done in the children classes to be shown via a progress bar in the GUI.
What I currently have done right now, which I am realizing will not work, is the event method definition declared in the parent class as a virtual method which each child class will overwrite. So something like :
public abstract class Parent
{
public event EventHandler someEvent;
protected virtual void OnSomeEvent(object sender, EventArgs e)
{
EventHandler eh= someEvent;
if (eh!= null)
{
eh(this, e);
}
}
}
And my child classes have something like :
protected override void OnSomeEvent(object sender, EventArgs e)
{
base.OnSomeEvent(sender, e);
}
and the event is raised somewhere in the child class.
However, seeing as the parent class is abstract, I will not be able to listen to the event from my GUI because I can not create an instance of an abstract class.
Am I completely off course and/or is there another method of doing this?
Upvotes: 3
Views: 15993
Reputation: 17139
You can attach to the event from the child instance.
public abstract class Parent
{
public event Action Something;
public void OnSomething()
{
if (Something != null)
{
Something();
}
}
}
public class Child : Parent
{
}
Child c = new Child();
c.Something += () => Console.WriteLine("Got event from child");
c.OnSomething();
> Got event from child
You can even declare it as a Parent
type that contains a child:
Parent c2 = new Child();
c2.Something += () => Console.WriteLine("Got event from Parent type");
c2.OnSomething();
> Got event from Parent type
An abstract class is just a code template that gets copied into every class that inherits from it (to put it simply). Think of it like, all of your Child
classes contain an identical copy of the code that exists in Parent
.
Note that this will also produce a unique event handler for each instance of Child
. Having a static event handler for all Child
s that derive from Parent
would look like this, and requires no code in Child
:
public abstract class Parent
{
public static event Action Something;
public static void OnSomething()
{
if (Something != null)
{
Something();
}
}
}
Then, you could do something like this, for example:
Parent.Something += () => Console.WriteLine("This will be invoked twice.");
Child c = new Child();
Child c2 = new Child();
c.OnSomething();
c2.OnSomething();
> This will be invoked twice.
> This will be invoked twice.
Both of those objects/event calls will invoke the same event handler even though they come from separate children.
Upvotes: 3
Reputation: 19221
First thing to not, because someEvent
does not specify static
, every instance of the child class will have its own someEvent
. This means you aren't getting a unified view, but a diversified one. This is useful for responding to a button being pressed, since you don't want to respond the same way when they click the background.
Typically rather than using a class hierarchy, you would use composition to handle this kind of situation. For example, adding the following class to yours:
public class ParentContainer
{
private List<Parent> watched = new List<Parent>();
public void Add(Parent watch)
{
watched.Add(watch);
watch.SomeEvent += Handler;
}
private void Handler(object sender, EventArgs args)
{
//Do something
}
}
Upvotes: 0