views:

68

answers:

4

I created a control where other developers can create an instance and use. There is a button click in the control. How do I allow developers to plug in their own code in a certain part of my control? I am not sure if or how exactly to use a delegate or event in this scenario. Can someone help in the below example:

public class MyControl : CompositeControl
{
   ...
   void btnSubmit_Click(object sender, EventArgs e)
   {
      //DO SOMETHING
      if (success)
      {
         //CALL DEVELOPER'S LOGIC
      }
   }
}

In the developers code, how can they pass in their logic when the button click of the control is successful?

protected override void CreateChildControls()
{
    var ctlMyControl = new MyControl();

    //ADD SuccessCode() TO ctlMyControl
    //SO IT IS TRIGGERED ON SUCCESS
    //MAYBE SOMETHING LIKE:
    //ctlMyControl.SuccessEvent = SuccessCode()??

    this.Control.Add(ctlMyControl);
}

protected void SuccessCode()
{
    //DO SOMETHING
}

How to I update MyControl to allow this?

+1  A: 

You need to add an event to the control, like this:

void btnSubmit_Click(object sender, EventArgs e) {
    //DO SOMETHING
    if (success) {
        OnSomethingCompleted();
    }
}

///<summary>Occurs when the operation is successfully completed.</summary>
public event EventHandler SomethingCompleted;
///<summary>Raises the SomethingCompleted event.</summary>
internal protected virtual void OnSomethingCompleted() { OnSomethingCompleted(EventArgs.Empty); }
///<summary>Raises the SomethingCompleted event.</summary>
///<param name="e">An EventArgs object that provides the event data.</param>
internal protected virtual void OnSomethingCompleted(EventArgs e) {
    if (SomethingCompleted != null)
        SomethingCompleted(this, e);
}

In the form, you can add a handler to the event, like this:

myControl.SomethingCompleted += myControl_SomethingCompleted;

void myControl_SomethingCompleted(object sender, EventArgs e) {
    //Do things
}

For more information, see the documentation.

SLaks
I believe the signature for EventHandler is (object sender, EventArgs e) but your handler only has a signature of (EventArgs e). I don't think that will work as is??
Doug
@Doug: This does work. Read it more carefully; that's not a handler.
SLaks
@SLaks - Ha yes I did misread that - Thanks for the tip below btw, I did not realize there was a static "Empty" member of the EventArgs class.
Doug
A: 

You will need to declare the event, and if necessary create a custom event args class for passing information about the event.

Here is a blog post I wrote a while back that walks through the process.

Mitchel Sellers
A: 

Hi,

Since your event uses the default signature of type EventHandler, you just need to expose a public event of type EventHandler. So take a look at the code below.

Here is how you implement the new event!

public class MyControl : CompositeControl
{
   //New public event declaration of type EventHandler
   public event EventHandler Submit_OnClick;

   void btnSubmit_Click(object sender, EventArgs e)
   {
      //DO SOMETHING
      if (success)
      {
         //CALL DEVELOPER'S LOGIC

         //Code to raise the event only if there are subscribers.
         if (Submit_OnClick != null)
         {
           Submit_OnClick(this, new EventArgs());
         }
      }
   }
}

Here is how you use the new event!

protected override void CreateChildControls()
{
    var ctlMyControl = new MyControl();
      //Subscribed to the newly added event of your MyControl class
        ctlMyControl.Submit_OnClick += new EventHandler(SuccessCode);

    //ADD SuccessCode() TO ctlMyControl
    //SO IT IS TRIGGERED ON SUCCESS
    //MAYBE SOMETHING LIKE:
    //ctlMyControl.SuccessEvent = SuccessCode()??

    this.Control.Add(ctlMyControl);
}

//Modified the signature to be compliant with EventHandler type
protected void SuccessCode(object sender, EventArgs e)
{
    //DO SOMETHING
}

Enjoy!

Doug
`EventArgs.Empty`
SLaks
A: 

You should add an event to the your control.

Something like this:

public class MyControl : CompositeControl
{
       public event EventHandler Success;
       ...
       void btnSubmit_Click(object sender, EventArgs e)
   {   
       //DO SOMETHING
        if (success)
        {
             //CALL DEVELOPER'S LOGIC
             OnSuccess();
        }
   }

    private static void OnSuccess()
    {
         if(Success != null)
         {
              Success(this, EventArgs.Empty); //or you can pass event args you want. But you should use EventHandler<T> instead.
         }
    }
}

And than other developers can youse your control like this:

protected override void CreateChildControls()
{
    var ctlMyControl = new MyControl();

    ctlMyConstrol += SuccessCode;

    this.Control.Add(ctlMyControl);
}

protected void SuccessCode(object sender, EventArgs e)
{
    //DO SOMETHING
}

You can read more about events on MSDN.

Vyacheslav