views:

55

answers:

4

Someone gave me this code that works great but I would really like to understand what is happening inside it, could somebody explain please? what is the meaning of each part of the code? The code is inside a custom control which has two labels inside a panel. Also I've seen some custom control events that use add/remove sytanx, what is that for? what is the difference with what is happening here?

Thanks in advance

public partial class UserControl1 : UserControl
{
public UserControl1()
{
    InitializeComponent();
}

public event EventHandler MyCustomClickEvent;

protected virtual void OnMyCustomClickEvent(EventArgs e)
{
    // Here, you use the "this" so it's your own control. You can also
    // customize the EventArgs to pass something you'd like.

    if (MyCustomClickEvent != null)
        MyCustomClickEvent(this, e);
}

private void label1_Click(object sender, EventArgs e)
{
    OnMyCustomClickEvent(EventArgs.Empty);
}
}
+3  A: 

See my comments below. Also for a more detailed event I blogged on this concept a while back where I go into more detail on the entire process.

public partial class UserControl1 : UserControl
{
//This is the standard constructor of a user control
public UserControl1()
{
    InitializeComponent();
}

//This defines an event called "MyCustomClickEvent", which is a generic
//event handler.  (EventHander is a delegate definition that defines the contract
//of what information will be shared by the event.  In this case a single parameter
//of an EventArgs object.
public event EventHandler MyCustomClickEvent;


//This method is used to raise the event, when the event should be raised, this method
//will check to see if there are any subscribers, if there are, it raises the event
protected virtual void OnMyCustomClickEvent(EventArgs e)
{
    // Here, you use the "this" so it's your own control. You can also
    // customize the EventArgs to pass something you'd like.

    if (MyCustomClickEvent != null)
        MyCustomClickEvent(this, e);
}

private void label1_Click(object sender, EventArgs e)
{
    OnMyCustomClickEvent(EventArgs.Empty);
}
}
Mitchel Sellers
+2  A: 

I'd recommend reading up on Events for C# on MSDN. This is covered in detail.

Basically, MyCustomClickEvent is an event. The OnMyCustomClickEvent method is used to raise the event, but is being done in a way that subclasses can also raise this event if required.

When you click on "label1", the OnMyCustomClickEvent method runs, which raises the event. Any delegates subscribed to the event will execute at that point.

Reed Copsey
A: 

Concerning the add/remove, this is a "manual" implementation of events. The following two snippets do the same thing.

Automatic implementation:

public event EventHandler MyEvent;

Manual implementation:

private EventHandler _myEvent;

public event EventHandler MyEvent
{
    add { _myEvent += value; }
    remove { _myEvent -= value; }
}

This is exactly the same idea as automatic properties where:

public string Property { get; set; };

Does exactly the same as:

private string _property;

public string Property
{
    get { return _property; }
    set { _property = value; }
}

The difference between these snippets is that with the manual implementations, you get more control. Examples are:

  • Implement logic in the add/get and remove/set;
  • Get access to the fields which allows you to set e.g. [NonSerializable];
  • Put the values in e.g. a Dictionary.

The Form class e.g. does the latter to keep the number of fields in the Form class down.

Pieter
Thanks Pieter! it is actually the code you gave me, just trying to understand better
VerizonW
No problem. Though about voting/accepting this answer?
Pieter
Why is the method protected virtual?
VerizonW
Well, that's largely due to convention, as is the way the parameters of the method are defined. You will (almost) always see these methods being defined as protected virtual because this gives an inheriting class the option of overriding the method instead of having to register the event. When creating a child class, it's preferred to override the method instead of adding events in the constructor.
Pieter
A: 

You mentioned seeing the add/remove syntax for events in some custom control examples. Most likely those examples are using the UserControl class' Events property to store event handlers, such as in the following example:

    public event EventHandler MyEvent
    {
        add
        {
            Events.AddHandler("MyEvent", value);
        }
        remove
        {
            Events.RemoveHandler("MyEvent", value);
        }
    }

The idea there is that usually a consumer of a control is not going to want to handle every single event that the control exposes. If each event is defined as a "field" event (as in your example), then each event will take up a chunk of memory even if there are no subscribers for that event. When you have a complex page constructed of hundreds of controls, each of which may have dozens of events, the memory consumption for unused events is not insignificant.

This is why the System.ComponentModel.Component class (the base class of the System.Windows.Forms.Control class) has an Events property, which is basically a dictionary to store event handler delegates. This way each event is implemented more like a property than a field. The add/remove handlers for each event store or remove delegates from the Events dictionary. If an event is not used, then there just isn't an entry in the Events dictionary for it, and no additional memory is consumed for that event. It's a trade-off of doing slightly more work (having to look up the event handler) to save slightly more memory.

EDIT: fixed my answer to pertain to Windows Forms, rather than ASP.NET, althought the concepts are the same.

Dr. Wily's Apprentice