473,320 Members | 1,953 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Handling events without explicitly defining a handler

Greetings,

I have a Windows form application that (naturally) instantiates all sorts of
objects. I have a base object that contains an event. Lots of other
objects inherit from this event. When the base object or any derived object
is instantiated I would like to automagically start listening for the event.
An example and a further explanation follows:

public delegate NeedFoodDelegate(object sender, EventArgs args);

public class Animail
{
public event NeedFoodDelegate OnNeedFood;

public void StartHunger()
{
if (OnNeedFood != null)
OnNeedFood(this, new EventArgs());
}
}

public class Cat : Animal
{
}

public class Dog : Animal
{
}

Now the winform application will be creating Cat, Dog, and Animal
frequently. I would like to have one event handler for ALL instances. It's
virtually impossible for me to explicitly define and event handler for each
object as Cat and Dog may be many layers deep in the object hierarchy.

I may be using the wrong design pattern all together to monitor the events
in all the object. I was thinking about using the MSMQ but these events and
notifications do not need to span multiple AppDomains so I figure MSMQ would
be over kill.

I hope I described this clearly.

Any and all suggestions are appreciated.

Thanks,
Jay

Mar 1 '06 #1
7 1795
On Wed, 1 Mar 2006 15:32:39 -0700, "Jay Douglas"
<ja****************@jaydouglas.com> wrote:
Greetings,

I have a Windows form application that (naturally) instantiates all sorts of
objects. I have a base object that contains an event. Lots of other
objects inherit from this event. When the base object or any derived object
is instantiated I would like to automagically start listening for the event.
An example and a further explanation follows:

public delegate NeedFoodDelegate(object sender, EventArgs args);

public class Animail
{
public event NeedFoodDelegate OnNeedFood;

public void StartHunger()
{
if (OnNeedFood != null)
OnNeedFood(this, new EventArgs());
}
}

public class Cat : Animal
{
}

public class Dog : Animal
{
}

Now the winform application will be creating Cat, Dog, and Animal
frequently. I would like to have one event handler for ALL instances. It's
virtually impossible for me to explicitly define and event handler for each
object as Cat and Dog may be many layers deep in the object hierarchy.

I may be using the wrong design pattern all together to monitor the events
in all the object. I was thinking about using the MSMQ but these events and
notifications do not need to span multiple AppDomains so I figure MSMQ would
be over kill.

I hope I described this clearly.

Any and all suggestions are appreciated.

Thanks,
Jay


I don't know if it's an answer, but one eventhandler could be assigned
to multiple events. When you instanciate all classes at the same
location, you could all give these events the same (local) handler all
you need to know (which is, in this case, already done) the
caller-object...

Hope it helps
Leon
Mar 1 '06 #2
Jay,
Now the winform application will be creating Cat, Dog, and Animal
frequently. I would like to have one event handler for ALL instances.
It's virtually impossible for me to explicitly define and event
handler for each object as Cat and Dog may be many layers deep in the
object hierarchy.

I hope I got you right, but for me, there seem to be a simple
possibility (when everything inherits from Animal):

Don't create events, as you are in the hierarchy, but create a virtual
method in the Animal class instead (events should be created, if a
complete other class wants to be notified about what is happening. If
you are in the hierarchy, then there is no real need for events...):

public class Animal
{
[...]

public virtual void OnNeedFood(...)
{
DoEatDefault();
}
}

and in the derived classes overwrite (if necessary) this method:

public class Dog : Animal
{
public override void OnNeedFood(....)
{
DoEatDogFood();
}
}
hope to help
Markus
Mar 2 '06 #3

Jay Douglas wrote:
Greetings,

I have a Windows form application that (naturally) instantiates all sorts of
objects. I have a base object that contains an event. Lots of other
objects inherit from this event.
Typo for 'from this base object', I'll assume.
When the base object or any derived object
is instantiated I would like to automagically start listening for the event.
Why the need for automagic; couldn't you just hook up the global event
handler whenever you create an Animal (or anything derived from it) ?

Or, you could have the constructors for all Animals accept an event
handling delegate, and pass the global event handler in each time you
create one?

Or (ugh), you could hardcode the global event handler into the
constructors (this is horrible).

Or, you could enforce that all Animal creation is done by a factory,
which hooks up the global event handler to all the Animals it produces.
Now the winform application will be creating Cat, Dog, and Animal
frequently. I would like to have one event handler for ALL instances.
That's not a problem - a method can be the *target* of as many events
as you want (eg think of a Minesweeper app - the method to handle
Button Clicks is gonig to be the target of the Click event of *every*
button!).
It's
virtually impossible for me to explicitly define and event handler for each
object as Cat and Dog may be many layers deep in the object hierarchy.
I don't really get what you mean by this last sentence.
I may be using the wrong design pattern all together to monitor the events
in all the object. I was thinking about using the MSMQ but these events and
notifications do not need to span multiple AppDomains so I figure MSMQ would
be over kill.


MSMQ is definitely not needed here.

--
Larry Lard
Replies to group please

Mar 2 '06 #4
Jay,

You can declare the event static in the base class, thus all the objects in
the hierarchy will share the same event.

Another solution is to implement a system of services similiar to the one
that VS has, but for small applications that could be overkill.

Simplification of this design with services is to declare the services as
classes that expose static events and static methods to fire those events.
Any object that wants to listen for some service event can go ahead and
subscribe for a static event of a service class e.g.
NutritionService.HungruAnimal += .....

than eny animal that becomes hungry can fire the event e.g.
NutritionService.NeedFood(this, EventArgs.Emtpy) ;

Hope you got the idea.

--
HTH
Stoitcho Goutsev (100)
"Jay Douglas" <ja****************@jaydouglas.com> wrote in message
news:Ok**************@TK2MSFTNGP12.phx.gbl...
Greetings,

I have a Windows form application that (naturally) instantiates all sorts
of objects. I have a base object that contains an event. Lots of other
objects inherit from this event. When the base object or any derived
object is instantiated I would like to automagically start listening for
the event. An example and a further explanation follows:

public delegate NeedFoodDelegate(object sender, EventArgs args);

public class Animail
{
public event NeedFoodDelegate OnNeedFood;

public void StartHunger()
{
if (OnNeedFood != null)
OnNeedFood(this, new EventArgs());
}
}

public class Cat : Animal
{
}

public class Dog : Animal
{
}

Now the winform application will be creating Cat, Dog, and Animal
frequently. I would like to have one event handler for ALL instances.
It's virtually impossible for me to explicitly define and event handler
for each object as Cat and Dog may be many layers deep in the object
hierarchy.

I may be using the wrong design pattern all together to monitor the events
in all the object. I was thinking about using the MSMQ but these events
and notifications do not need to span multiple AppDomains so I figure MSMQ
would be over kill.

I hope I described this clearly.

Any and all suggestions are appreciated.

Thanks,
Jay

Mar 2 '06 #5
Larry, Markus, Stoitcho,

I totally explained my design issue incorrectly. Lack of sleep does that to
a person =/

Okay, I have multiple controls and forms that instantiate Animal and objects
the derive from animal. A mock form and control hierarchy follows:

Form1 (Main form loaded)
+ Animail List UserControl
+ Animail Edit UserControl
Form2 (Instantiated by Form1)
+ Animal List UserControl
+ Animail Edit UserControl
Zero to many controls may be instantiated in various control containers. A
control container may contain any of the controls.
What I need to monitor is if ANY form or control instantiates an Animal
object. The reason I need to monitor the instantiation of the Animal object
globally is to refresh the data from the database that created the object in
the first place.

To drill a little deeper in to my objective, the data store may change at
any time. (Allowing for offline/online/redundancy data access). Animal
will utilize an IUpdateable interface that will contain [int
IUpdateable.UpdateTimeDelay] and [void IUpdateable.UpdateData()]. If I
could monitor all of these Animal objects in one location then naturally my
code will be more normalized.
Any ideas are suggestions are greatly appreciated.
Again, Thanks!
Jay


"Larry Lard" <la*******@hotmail.com> wrote in message
news:11**********************@z34g2000cwc.googlegr oups.com...

Jay Douglas wrote:
Greetings,

I have a Windows form application that (naturally) instantiates all sorts
of
objects. I have a base object that contains an event. Lots of other
objects inherit from this event.


Typo for 'from this base object', I'll assume.
When the base object or any derived object
is instantiated I would like to automagically start listening for the
event.


Why the need for automagic; couldn't you just hook up the global event
handler whenever you create an Animal (or anything derived from it) ?

Or, you could have the constructors for all Animals accept an event
handling delegate, and pass the global event handler in each time you
create one?

Or (ugh), you could hardcode the global event handler into the
constructors (this is horrible).

Or, you could enforce that all Animal creation is done by a factory,
which hooks up the global event handler to all the Animals it produces.
Now the winform application will be creating Cat, Dog, and Animal
frequently. I would like to have one event handler for ALL instances.


That's not a problem - a method can be the *target* of as many events
as you want (eg think of a Minesweeper app - the method to handle
Button Clicks is gonig to be the target of the Click event of *every*
button!).
It's
virtually impossible for me to explicitly define and event handler for
each
object as Cat and Dog may be many layers deep in the object hierarchy.


I don't really get what you mean by this last sentence.
I may be using the wrong design pattern all together to monitor the
events
in all the object. I was thinking about using the MSMQ but these events
and
notifications do not need to span multiple AppDomains so I figure MSMQ
would
be over kill.


MSMQ is definitely not needed here.

--
Larry Lard
Replies to group please

Mar 2 '06 #6

Jay Douglas wrote:
Larry, Markus, Stoitcho,

I totally explained my design issue incorrectly. Lack of sleep does that to
a person =/

Okay, I have multiple controls and forms that instantiate Animal and objects
the derive from animal. A mock form and control hierarchy follows:

Form1 (Main form loaded)
+ Animail List UserControl
+ Animail Edit UserControl
Form2 (Instantiated by Form1)
+ Animal List UserControl
+ Animail Edit UserControl
Zero to many controls may be instantiated in various control containers. A
control container may contain any of the controls.
What I need to monitor is if ANY form or control instantiates an Animal
object. The reason I need to monitor the instantiation of the Animal object
globally is to refresh the data from the database that created the object in
the first place.
OK this sounds like it would be best handles by static members in
Animal, that get manipulated by the Animal constructor (all the derived
constructors will eventually call up to the base constructor). This
means that users of the Animals don't know or care about this internal
detail, which is good
To drill a little deeper in to my objective, the data store may change at
any time. (Allowing for offline/online/redundancy data access). Animal
will utilize an IUpdateable interface that will contain [int
IUpdateable.UpdateTimeDelay] and [void IUpdateable.UpdateData()]. If I
could monitor all of these Animal objects in one location then naturally my
code will be more normalized.


How about if class Animal contains a static collection of Animals, to
which Animals get added (by the constructor) when they are created, and
removed from when they are destroyed (by Disposal I suppose is the way
to go, although I guess finalization would provide less of a code
burden on users)? (Hmm, I suppose this means that it will have to be a
collection of weak references rather than normal references, otherwise
the Animals would never die).

Then when something happens, you can just go through this collection
and ask each Animal to update itself if required.

--
Larry Lard
Replies to group please

Mar 2 '06 #7
OK this sounds like it would be best handles by static members in
Animal, that get manipulated by the Animal constructor (all the derived
constructors will eventually call up to the base constructor). This
means that users of the Animals don't know or care about this internal
detail, which is good

Something similar came to my mind, just look at the following code:
using System;

namespace Test
{
public class ListenerHelper
{
private static readonly ListenerHelper instance =
new ListenerHelper();

public static ListenerHelper Instance
{
get { return instance; }
}

public event EventHandler ListenForCreations;

public void Fire(object sender)
{
if (ListenForCreations != null)
ListenForCreations(sender, null);
}
}
public abstract class Animal
{
public Animal()
{
Console.WriteLine("I am generally an Animal");
ListenerHelper.Instance.Fire(this);
}
}

public class Dog : Animal
{
public Dog(string name)
{
Console.WriteLine("I am a dog, my name is " + name);
}
}

public class MainClass
{
public static void Main()
{
ListenerHelper.Instance.ListenForCreations +=
new EventHandler(CreationListener);
new Dog("bello");
}

private static void CreationListener(object sender, EventArgs e)
{
Console.WriteLine("Creation Listener: " +
sender.GetType().ToString());
}

}

}
hth and that I got you right this time ;-)
Markus

Mar 2 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: JPRoot | last post by:
Hi I use the following syntax to have events inherited from base to child classes which works nicely (virtual and override keyword on events). But I am wondering if it is a "supported" way of using...
4
by: Pierke | last post by:
Hey guys out there, I really need your help, i am building up a web site, so for security reasons i need to do "some things" before the user log off, and i indeed do it. Now the matter is that...
2
by: luca | last post by:
I'm trying to build a Server Control, it's a calendar to manage sellers appointments (don't answer me to use and custumize Calendar Control because unluckily it's not possible for this specific...
12
by: scsharma | last post by:
Hi, I am working on creating a webapplication and my design calls for creating main webform which will have menu bar on left hand side and a IFrame which will contain all the forms that are shown...
12
by: Jack Russell | last post by:
My unstanding of all VB up to and including vb6 is that an event could not "interrupt" itself. For instance if you had a timer event containing a msgbox then you would only get one message. ...
16
by: anonymous.user0 | last post by:
The way I understand it, if I have an object Listener that has registered as a listener for some event Event that's produced by an object Emitter, as long as Emitter is still allocated Listener...
5
by: Daniel | last post by:
Hey guys When you hook an event (c# 2.0 syntax): myEvent += MyMethodToFire; You need to also unsubscribe it to avoid a resource leak so that the object it is in gets garbage collected like so...
1
by: Fred Chateau | last post by:
Can exceptions only be handled in a protected block? For example, can I globally catch and handle any exception generated from an ASP.NET page without placing the entire Page_Load event handler...
11
by: MikeT | last post by:
This may sound very elementary, but can you trap when your object is set to null within the object? I have created a class that registers an event from an object passed in the constructor. When...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.