CodingC#- Custom Events

 

Press Ctrl+Enter to quickly submit your post
Quick Reply  
 
 
  
 From:  Dan (HERMAND)  
 To:  ALL
35958.1 

Okay - I've decided to try and enter the world of OOP, and I've decided to learn C#. There's no reason for this other than personal development. I started learning last week, and up until now Google has been good, but I think I need this one spelling out to me.

 

Firstly - I don't quite 'get' custom event handling. I can kinda make it work, but I don't understand it fully - in terms of events, delegates and handlers.

 

Secondly - and this is the bit I think I really need spelling out to me. I want to fire an event every time an object is created. That seems easy enough - just put it in the constructor.

 

I just don't know how to handle it - the examples I've looked at seem to show handling events PER object, but this needs to be global.

 

in other words, by purely running

 

MyClass test = new MyClass();
MyClass test2 = new MyClass();
MyClass test3 = new MyClass();

 

in the form, I might get the output

 

"New MyClass Created - ID is 1"
"New MyClass Created - ID is 2"
"New MyClass Created - ID is 3"

 

I'm told that classes shouldn't really interface with the GUI (and as I wanna try some multi threaded stuff later, this is a definite) I really need to understand how to make this work with events.

 

Ta for any help.

0/0
 Reply   Quote More 

 From:  Dan (HERMAND)  
 To:  Dan (HERMAND)     
35958.2 In reply to 35958.1 

I've ended up doing it by creating a static class to house my CustomEvents. It feels like a good solution, as I only need to define the event handler once in the forms I want to use it. It also means I can put all my custom events together. It looks like this:

 

static class CustEventHandler
{

 

public delegate void NewCallDataEventHandler();

 

public static event NewCallDataEventHandler NewCallEvent;

 

public static void NewCall(int NewCallID)
{
NewCallID = 10;
if (NewCallEvent != null)
{
NewCallEvent();
}
}
}

 

And CustEventHandler.NewCall(); is ran from the other classes constructor. Obviously I haven't passed any values to the event, but I will.

0/0
 Reply   Quote More 

 From:  Ally  
 To:  Dan (HERMAND)     
35958.3 In reply to 35958.2 
It's a little difficult to go any further than the code you've posted without knowing exactly what you're trying to achieve, but you shouldn't need to use a static class to do this. The basic code you've got there could be inherited in each class- for no better reason (that I know of, Rendle can probably correct me) than it's good to learn about inheritance!

So taking your code, it'd be something like:
csharp code:
 
public class CustEventHandler
{
 
public delegate void NewCallDataEventHandler();
 
public event NewCallDataEventHandler NewCallEvent;
 
public void NewCall(int NewCallID)
{
NewCallID = 10;
if (NewCallEvent != null)
{
NewCallEvent();
}
}
}


Then:
csharp code:
 
public class MyNewClass : CustEventHandler {
 public MyNewClass() {
  this.NewCall(10);
 }
}
 


Or something like that. It's 3am. Urgh.
0/0
 Reply   Quote More 

 From:  THERE IS NO GOD BUT (RENDLE)  
 To:  Dan (HERMAND)     
35958.4 In reply to 35958.2 
You are right that if you want to raise an event on the creation of an object then you need a static event. The event should be contained in the class itself, though, to adhere to the OOP encapsulation principle.

Also, it's not a great idea to fire events from constructors for various reasons that live in deep, dark caves in the CLR. The way around this is to only allow instances to be created from a factory method.

Something like this (picking up a couple of other points along the way):

c# code:
// Derived from EventArgs class
class FooCreatedEventArgs : EventArgs
{
  // Field marked readonly can only be set in constructor/initializer
  private readonly Foo foo;
 
  public FooCreatedEventArgs(Foo foo)
  {
    this.foo = foo;
  }
 
  public Foo Foo { get { return this.foo; } }
}
 
class Foo
{
  // Use the generic EventHandler delegate rather than declaring your own
  public static event EventHandler<FooCreatedEventArgs> Created;
 
  // Event-raising method marked private, can't be called from other classes
  private static void OnCreated(Foo foo)
  {
    // Thread-safe pattern for raising events
    var handler = Created;
    if (handler != null)
      handler(null, new FooCreatedEventArgs(foo));
  }
 
  // Private constructor, prevents creating instances with new operator
  // except from within this class
  private Foo()
  {
    // All constructor code
    // ...
  }
 
  // Factory method creates instances and fires event
  public static Foo Create()
  {
    var foo = new Foo();
 
    OnCreated(foo);
 
    return foo;
  }
}
 
class Program
{
  static void Main(string[] args)
  {
    Foo.Created += HandleFooCreated;
    var foo1 = Foo.Create();
  }
 
  static void HandleFooCreated(object sender, FooCreatedEventArgs e)
  {
    Console.WriteLine("A new Foo! Halloo!");
  }
}
 


Any questions?

Happy now?

0/0
 Reply   Quote More 

 From:  Dan (HERMAND)  
 To:  ALL
35958.5 
Excellent stuff, both - thank you very much!
0/0
 Reply   Quote More 

Reply to All    
 

1–5

Rate my interest:

Adjust text size : Smaller 10 Larger

Beehive Forum 1.5.2 |  FAQ |  Docs |  Support |  Donate! ©2002 - 2024 Project Beehive Forum

Forum Stats