C#事件解析

Simple custom event handling

February 17th, 2009

Goto commentsLeave a comment

 (6 votes, average: 4.17 out of 5)

The event model in C# is based on idea of publisher and subscribers. Each publisher can have more subscribers subscribed to each event. Publisher will do some logic and publish an event to all subscribers. Subscribers will do their logic reacting to raised event. In C#, any object can publish a set of events to which other applications can subscribe. When the publishing class raises an event, all the subscribed applications are notified. Example of this behaviour can be that the application will subscribe to event which will be raised from database connection control when the connection is lost. Main application will know, that this happened and can react on that event –reconnect, show alert message, etc.

Conventions

The following important conventions are used with events:

  • Event Handlers in the .NET Framework return void and take two parameters.
  • The first paramter is the source of the event; that is the publishing object.
  • The second parameter is an object derived from EventArgs.
  • Events are properties of the class publishing the event.
  • The keyword event controls how the event property is accessed by the subscribing classes.

    Example

    Lets say that we have Product class which has Name property. When the name is changed we want ot change this name in Label as well. We don't know from where this name can be changed. We will "convert" product class into event publisher and the window where is the label will subscribe to this event.

    First step will be to create the event and method which will fire this event.

    view plaincopy to clipboardprint?

  1. public class Product  
  2. {  
  3.   public string Name { getset; }  
  4.   // Delegate  
  5.   public delegate void PropertyChangeHandler (object sender,  EventArgs data);  
  6.   // The event  
  7.   public event PropertyChangeHandler PropertyChange;  
  8.   // The method which fires the Event  
  9.   protected void OnPropertyChange (object sender,  EventArgs data)  
  10.   {  
  11.     // Check if there are any Subscribers  
  12.     if (PropertyChange!= null)  
  13.     {  
  14.       // Call the Event  
  15.       PropertyChange (this, data);  
  16.     }  
  17.   }  
  18. }  

We created delegate which encapsulates any method that takes these attributes, this delegate must be implemented by all subscribers. Now we need one small change to the class. That will be to fire the event, when Name property is changed. It can be nice to pass information about this change to subscribers with what have been changed and to have old value and new value. For this we will create PropertyChangeEventArgs class which will be derived from EventArgs.

view plaincopy to clipboardprint?

  1. public class PropertyChangeEventArgs : EventArgs  
  2. {  
  3.   public string PropertyName { getinternal set; }  
  4.   public object OldValue { getinternal set; }  
  5.   public object NewValue { getinternal set; }  
  6.   public PropertyChangeEventArgs(string propertyName, object oldValue, object newValue)  
  7.   {  
  8.     this.PropertyName = propertyName;  
  9.     this.OldValue = oldValue;  
  10.     this.NewValue = newValue;  
  11.   }  
  12. }  
  13.     
  14. public class Product  
  15. {  
  16.   private string name;  
  17.   public string Name {  
  18.     get  
  19.     {  
  20.       this.name;  
  21.     }  
  22.     set  
  23.     {  
  24.       Object old = this.name;  
  25.       this.name = value;  
  26.       OnPropertyChange(thisnew PropertyChangeEventArgs("Name", old, value));  
  27.     }  
  28.   }  
  29.     
  30.   // Delegate  
  31.   public delegate void PropertyChangeHandler (object sender,  PropertyChangeEventArgs data);  
  32.   // The event  
  33.   public event PropertyChangeHandler PropertyChange;  
  34.   // The method which fires the Event  
  35.   protected void OnPropertyChange (object sender,  PropertyChangeEventArgs data)  
  36.   {  
  37.     // Check if there are any Subscribers  
  38.     if (PropertyChange!= null)  
  39.     {  
  40.       // Call the Event  
  41.       PropertyChange (this, data);  
  42.     }  
  43.   }  
  44. }  

Now we are done with the Product class (publisher) and can subscribe to the OnPropertyChange event.

view plaincopy to clipboardprint?

  1. protected void Page_Init(object sender, EventArgs e)  
  2. {  
  3.   this.Product = new Product();  
  4.   this.Product.OnPropertyChange += new Product.PropertyChangeHandler(PropertyHasChanged);  
  5. }  
  6. protected void Page_Load (object sender, EventArgs e)  
  7. {  
  8.   this.Product.Name = "New name";  
  9. }  
  10.     
  11. public void PropertyHasChanged (object sender,  PropertyChangeEventArgs data)  
  12. {  
  13.   if(data.PropertyName == "Name")  
  14.   {  
  15.     this.ProductLabel.Text = (string)data.NewValue + " was " + (string)data.OldValue;  
  16.   }  
  17. }  

In the Init event we created product instance and subscribe to OnPropertyChange event of Product class. In Load phase we changed name of that product. This operation fired PropertyChange and this was send to all subscribers. This calls PropertyHasChanged method with all informations.

Donwload example: Download

下图为事件生成处理的总流程:

你可能感兴趣的:(properties,C#,application,Class,events,attributes)