C# Delegates and Event Handling

17,757 views
17,327 views

Published on

4 Comments
7 Likes
Statistics
Notes
No Downloads
Views
Total views
17,757
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
378
Comments
4
Likes
7
Embeds 0
No embeds

No notes for slide

C# Delegates and Event Handling

  1. 1. C#  Event  Handling   Jussi  Pohjolainen  Tampere  University  of  Applied  Sciences  
  2. 2. Method  call  Directly  using System; public class MyClass { public void Method() { Console.WriteLine("Method() begin"); Console.WriteLine("Method() end"); } } public class Test { static void Main(string[] args) { MyClass myObject = new MyClass(); myObject.Method(); } }
  3. 3. About  Delegates  •  A  delegate  lets  you  pass  a  funcCon  as  a   parameter!  •  “Anonymous”  invocaCon  •  You  can  call  a  method  X()  and  define  the  X  to   be  whatever  during  runCme!  
  4. 4. Basic  idea  behind  Delegate:   A  delegate  will  allow  us  to  specify  what  the  func4on  well  be  calling  looks  like  without  having   to  specify  which  func4on  to  call!  
  5. 5. Examples  •  public delegate void MyDelegate(); –  MyDelegate  encapsulates  any  method  with  no   parameters  and  no  return  •  public delegate int ButtonClicked(object o1, object o2); –  BuPonClicked  encapsulates  any  method  with   return  type  int  and  two  object  parameters  •  Just  like  a  declaraCon  of  a  method!  
  6. 6. using System;// Declaration of the delegatepublic delegate void MyDelegate();class TestDelegate{ public static void MyMethod() { Console.WriteLine("Delegate calling!"); } public static void Main() { // Instantiation. MyDelegate encapsulates the method! MyDelegate myDelegate = new MyDelegate(MyMethod); // Invocation.. calls MyMethod! myDelegate(); }}
  7. 7. using System; // Declaration of the delegate public delegate void MyDelegate(); class TestDelegate { public static void MyMethod() { Console.WriteLine("Delegate calling!"); } public static void Main() { // Instantiation. MyDelegate encapsulates the method! MyDelegate myDelegate = new MyDelegate(MyMethod); // Invocation.. calls MyMethod! myDelegate(); // MyDelegate extends class System.Delegate! Console.WriteLine( myDelegate.ToString() ); Console.WriteLine( myDelegate.GetInvocationList().Length ); } }
  8. 8. // Declaration of the delegatepublic delegate void MyDelegate();class TestDelegate{ public static void A() { Console.WriteLine("A()"); } public static void B() { Console.WriteLine("B()"); } public static void Main() { MyDelegate myDelegate1 = new MyDelegate(A); MyDelegate myDelegate2 = new MyDelegate(B); myDelegate1(); // A() myDelegate2(); // B() }}
  9. 9. // Declaration of the delegatepublic delegate string MyDelegate(string someParameter);class TestDelegate{ public static string A(string s) { Console.WriteLine("A()"); return s; } public static void Main() { MyDelegate myDelegate = new MyDelegate(A); Console.Write( myDelegate("hello") ); // A() hello }}
  10. 10. // Declaration of the delegate public delegate string MyDelegate(string someParameter); class TestDelegate { public static string A(string s) { Console.WriteLine("A()"); return s; } public static void Main() { MyDelegate myDelegate = new MyDelegate(A); someMethod(myDelegate); } Passing  object   public static void someMethod( MyDelegate md ) { Console.Write( md("hello") ); // A() hello } }
  11. 11. // MULTICASTING// A multicast delegate maintains a list of functions that will// all be called when the delegate is invoked.// Declaration of the delegatepublic delegate void MyDelegate();class TestDelegate{ public static void A() { Console.WriteLine("A()"); } public static void B() { Console.WriteLine("B()"); } public static void Main() { MyDelegate myDelegate = new MyDelegate(A); myDelegate += new MyDelegate(B); myDelegate(); // A() B() }}
  12. 12. public delegate void MyDelegate(); class TestDelegate { public static void A() { Console.WriteLine("A()"); } public static void B() { Console.WriteLine("B()"); } public static void Main() { MyDelegate myDelegate = A; myDelegate += B; myDelegate(); // A() B() } }
  13. 13. System.Delegate  •  Delegate  types  are  derived  from  System.Delegate   or  MulCcastDelegate  (subclass  of  Delegate)     public static void Main() { MyDelegate myDelegate = A; myDelegate += B; myDelegate(); // A(), B() int invocationCount = myDelegate.GetInvocationList().GetLength(0); Console.Write(invocationCount); // 2 }
  14. 14. EVENTS  
  15. 15. About  Events  •  NoCficaCon  system  •  Usually  in  GUI:  buPon  clicked  -­‐>  something   happens  •  Events  are  declared  using  delegates  
  16. 16. In  Java  •  In  Java:   –  buPon.addAcConListener(  someObjectThatImple mentsAcConListener  );  •  In  C#   –  buPon.ClickedEvent  +=  MyEventHandler;  
  17. 17. Listener  class Listener{ public void MyMethod1() { System.Console.WriteLine("MyMethod1"); } public void MyMethod2() { System.Console.WriteLine("MyMethod2"); } public void MyMethod3() { System.Console.WriteLine("MyMethod3"); }}
  18. 18. public delegate void MyEventHandler();class GUIWindow{ public event MyEventHandler ClickedEvent; // Declare a method that triggers the event: public void ClickHasHappened() { ClickedEvent(); // Calls now MyMethod1, MyMethod2 and MyMethod3 } static void Main() { GUIWindow window = new GUIWindow(); Listener listener = new Listener(); // Subscribe to the event by associating the handlers with the event: window.ClickedEvent += new MyEventHandler(listener.MyMethod1); window.ClickedEvent += new MyEventHandler(listener.MyMethod2); window.ClickedEvent += new MyEventHandler(listener.MyMethod3); // Trigger the event: window.ClickHasHappened(); }}
  19. 19. About  event  •  What  happens  here?   –  public event MyEventHandler ClickedEvent;  •  Events  are  a  special  kind  of  mulCcast  delegate   that  can  only  be  invoked  from  within  the   class  or  struct  where  they  are  declared  (the   publisher  class  
  20. 20. class GUIWindow{ // Declare the event of type MyEventHandler. Event handlers // for TriggerIt must have the same signature as MyEventHandler. public event MyEventHandler ClickedEvent; // Declare a method that triggers the event: public void ClickHasHappened() { ClickedEvent(); // Calls now MyMethod1, MyMethod2 and MyMethod3 } static void Main() { GUIWindow window = new GUIWindow(); Listener listener = new Listener(); // Subscribe to the event by associating the handlers with the event: window.ClickedEvent += new MyEventHandler(listener.MyMethod1); window.ClickedEvent += new MyEventHandler(listener.MyMethod2); window.ClickedEvent += new MyEventHandler(listener.MyMethod3); // Trigger the event: window.ClickHasHappened(); window.ClickedEvent(); // Works! Inside GUIWindow class!! }}
  21. 21. class GUIWindow{ // Declare the event of type MyEventHandler. Event handlers // for TriggerIt must have the same signature as MyEventHandler. public event MyEventHandler ClickedEvent; // Declare a method that triggers the event: public void ClickHasHappened() { ClickedEvent(); // Calls now MyMethod1, MyMethod2 and MyMethod3 }}class App{ static void Main() { GUIWindow window = new GUIWindow(); Listener listener = new Listener(); // Subscribe to the event by associating the handlers with the event: window.ClickedEvent += new MyEventHandler(listener.MyMethod1); window.ClickedEvent += new MyEventHandler(listener.MyMethod2); window.ClickedEvent += new MyEventHandler(listener.MyMethod3); // Trigger the event: window.ClickHasHappened(); window.ClickedEvent(); // DOES NOT WORK! Outside of class GUIWindow! }}
  22. 22. CreaCng  the  Listener  Method  •  Usually  listener  method:   –  public delegate void MyEventHandler(object sender, EventArgs e);•  Listener  receives  informaCon:   –  Who  is  the  publisher?  (Sender)   –  What  kind  of  arguments  did  the  sender  pass?  
  23. 23. App  class App{ static void Main() { GUIWindow window = new GUIWindow(); Listener listener = new Listener(); // Subscribe to the event by associating the handlers with the event: window.ClickedEvent += new MyEventHandler(listener.MyMethod1); window.ClickedEvent += new MyEventHandler(listener.MyMethod2); window.ClickedEvent += new MyEventHandler(listener.MyMethod3); // Trigger the event: window.ClickHasHappened(); }}
  24. 24. Listener  class Listener{ public void MyMethod1(object sender, EventArgs e) { System.Console.WriteLine("Sender {0}, MyMethod1", sender.ToString()); } public void MyMethod2(object sender, EventArgs e) { System.Console.WriteLine("Sender {0}, MyMethod2", sender.ToString()); } public void MyMethod3(object sender, EventArgs e) { System.Console.WriteLine("Sender {0}, MyMethod3", sender.ToString()); }}
  25. 25. Publisher  public delegate void MyEventHandler(object sender, EventArgs e);class GUIWindow{ public event MyEventHandler ClickedEvent; public void ClickHasHappened() { if(ClickedEvent != null) ClickedEvent(this, null); Sender  GUIWindow,  MyMethod1   } Sender  GUIWindow,  MyMethod2  } Sender  GUIWindow,  MyMethod3  
  26. 26. Event  Model  •  The  following  example  followed  the  guidelines   for  .NET  event  model.  •  To  raise  a  event,  two  elements  are  included   –  Sender   –  Data  •  .NET  Framework  has  defined  following  delegate   in  class  library!   public delegate void EventHandler( Object sender, EventArgs e )
  27. 27. App,  now  Using  EventHandler  class App{ static void Main() { GUIWindow window = new GUIWindow(); Listener listener = new Listener(); // Subscribe to the event by associating the handlers with the event: window.ClickedEvent += new EventHandler(listener.MyMethod1); window.ClickedEvent += new EventHandler(listener.MyMethod2); window.ClickedEvent += new EventHandler(listener.MyMethod3); // Trigger the event: window.ClickHasHappened(); } EventHandler  is  } a  delegate  from   class  library!  
  28. 28. Listener,  exactly  the  same  class Listener{ public void MyMethod1(object sender, EventArgs e) { System.Console.WriteLine("Sender {0}, MyMethod1", sender.ToString()); } public void MyMethod2(object sender, EventArgs e) { System.Console.WriteLine("Sender {0}, MyMethod2", sender.ToString()); } public void MyMethod3(object sender, EventArgs e) { System.Console.WriteLine("Sender {0}, MyMethod3", sender.ToString()); }}
  29. 29. Publisher  // We don’t need this!// public delegate void MyEventHandler(object sender, EventArgs e);class GUIWindow{ public event EventHandler ClickedEvent; public void ClickHasHappened() { if(ClickedEvent != null) Sender  GUIWindow,  MyMethod1   ClickedEvent(this, null); Sender  GUIWindow,  MyMethod2   } Sender  GUIWindow,  MyMethod3  }
  30. 30. Passing  Data  •  The  listener  receives  two  things   –  Sender   –  Data  •  Data  is  passed  as  a  subclass  of  EventArgs  
  31. 31. Data  public class CustomEventArgs : EventArgs{ public CustomEventArgs(string s) { msg = s; } private string msg; public string Message { get { return msg; } }}
  32. 32. Pass  InformaCon  class GUIWindow{ public event EventHandler ClickedEvent; public void ClickHasHappened() { if(ClickedEvent != null) ClickedEvent(this, new CustomEventArgs("Click!")); }}
  33. 33. Listener  class Listener{ public void MyMethod1(object sender, EventArgs e) { System.Console.WriteLine("Event: {0}", e.ToString()); } …} Problem!  We  can’t  call  any  CustomEvent  method,  since   the  parameter  is  a  type  of  EventArgs.  So  this  does  not  work:     System.Console.WriteLine("Event: {0}", e.Message);    
  34. 34. Listener  class Listener{ public void MyMethod1(object sender, CustomEventArgs e) { System.Console.WriteLine("Event: {0}", e.Message); } …} Let’s  change  the  listener.  But  now  the  problem  is  that  the  used  delegate   from  class  library  was  in  the  form  of     public  delegate  void  EventHandler(object  sender,  EventArgs  e);    
  35. 35. EventHandler  with  Generics  class GUIWindow{ public event EventHandler<CustomEventArgs> ClickedEvent; public void ClickHasHappened() { if(ClickedEvent != null) ClickedEvent(this, new CustomEventArgs("Click!")); }} We  can  define  the  second  parameter!  
  36. 36. EventHandler  with  Generics  class App{ static void Main() { GUIWindow window = new GUIWindow(); Listener listener = new Listener(); // Subscribe to the event by associating the handlers with the event: window.ClickedEvent += new EventHandler<CustomEventArgs>(listener.MyMethod1); window.ClickedEvent += new EventHandler<CustomEventArgs>(listener.MyMethod2); window.ClickedEvent += new EventHandler<CustomEventArgs>(listener.MyMethod3); // Trigger the event: window.ClickHasHappened(); }}
  37. 37. And  this  is  also  possible..  class App{ static void Main() { GUIWindow window = new GUIWindow(); Listener listener = new Listener(); // Subscribe to the event by associating the handlers with the event: window.ClickedEvent += listener.MyMethod1; window.ClickedEvent += listener.MyMethod2; window.ClickedEvent += listener.MyMethod3; // Trigger the event: window.ClickHasHappened(); }}

×