Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / March 2006

Tip: Looking for answers? Try searching our database.

Handling events without explicitly defining a handler

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jay Douglas - 01 Mar 2006 22:32 GMT
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
Markus - 02 Mar 2006 07:46 GMT
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
Larry Lard - 02 Mar 2006 11:14 GMT
> 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.

Signature

Larry Lard
Replies to group please

Jay Douglas - 02 Mar 2006 17:05 GMT
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

>> Greetings,
>>
[quoted text clipped - 46 lines]
>
> MSMQ is definitely not needed here.
Larry Lard - 02 Mar 2006 17:32 GMT
> Larry, Markus, Stoitcho,
>
[quoted text clipped - 17 lines]
> 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.

Signature

Larry Lard
Replies to group please

Markus - 02 Mar 2006 17:47 GMT
> 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
Stoitcho Goutsev (100) - 02 Mar 2006 14:25 GMT
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.

Signature

HTH
Stoitcho Goutsev (100)

> Greetings,
>
[quoted text clipped - 42 lines]
> Thanks,
> Jay

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.