0

I am writing a usercontrol (winforms) which accept images from clipboard, do some manipulations and then allow user to upload it and get back URL of image.

I want user of that control to write his/her own code to upload. I have a Upload button in usercontrol, i want to call user written code on click of that button and pass image object.

I have tried with delegates but with delegate, user have to invoke it. But i want user should not invoke it, instead it should be called on click of upload button in my control.

I have read following but they didn't help
Pass Method as Parameter using C#
How can I pass a method name to another method and call it via a delegate variable?

Is there any way i can allow user to overwrite upload method in the form where control is being used, so he can write his own code or something else? Can someone point me to right direction?

Community
  • 1
  • 1
SamTech
  • 1,305
  • 2
  • 12
  • 22

1 Answers1

0

You have two main options for achieving this, either by requiring the user of the control to provide an upload method that is called by your control when the Upload button is clicked, or you can require that the control is sub-classed, and the Upload method implemented.

Method 1 - Providing a delegate to be called upon upload:

public partial class MyControl
{
    // Define a delegate that specifies the parameters that will be passed to the user-provided Upload method
    public delegate void DoUploadDelegate(... parameters ...);

    private readonly DoUploadDelegate _uploadDelegate;

    public MyControl(DoUploadDelegate uploadDelegate)
    {
        if (uploadDelegate == null)
        {
            throw new ArgumentException("Upload delegate must not be null", "uploadDelegate");
        }
        _uploadDelegate = uploadDelegate;
        InitializeComponent();
    }

    // ...

    // Upload button Click event handler
    public void UploadButtonClicked(object sender, EventArgs e)
    {
        // Call the user-provided upload handler delegate with the appropriate arguments
        _uploadDelegate(...);
    }
}

Method 2 - Require the upload method to be overridden:

public abstract partial class MyControl
{
    private readonly DoUploadDelegate _uploadDelegate;

    protected MyControl()
    {
        InitializeComponent();
    }

    // ...

    // The method that users of the control will need to implement
    protected abstract void DoUpload(... parameters ...);

    // Upload button Click event handler
    public void UploadButtonClicked(object sender, EventArgs e)
    {
        // Call the overridden upload handler with the appropriate arguments
        DoUpload(...);
    }
}

For the latter option, a user would need to sub-class the control before being able to use it, as follows:

public class MyConcreteControl : MyControl
{
    protected override void DoUpload(... parameters ...)
    {
        // User implements their own upload logic here...
    }
}
Iridium
  • 23,323
  • 6
  • 52
  • 74
  • Hi Iridium, your first method works well. Thanks! I was trying to do same but with property. I declared a property to set delegate pointer but that was not working. Your trick is working fine. – SamTech Dec 12 '12 at 20:02
  • @SamTech You can certainly use a property to hold the delegate, however there's no guarantee that the property will actually be set. By requiring it as a parameter in the constructor, the necessity is made explicit. I would suggest also checking the constructor's uploadDelegate is not null, and throwing an exception if it is (I omitted this when writing the answer, but have now added it). – Iridium Dec 12 '12 at 20:32