1

I seem to be going no-where fast with passing a method name as a string and assigning it to a delegate.

I want to have a class that assigns a dynamic method from a parameter but can't work out how to do it.

    private delegate void ProgressMsg(string msg);
    private ProgressMsg AddMsg;

    public Progress(string FormName, string AddMsgMethodName, bool close, bool hide)
    {
        // set properties
        this.Hide = hide;
        this.Close = close;

        // Open form if not open
        this.Frm = Application.OpenForms[FormName];
        if (this.Frm == null)
        {
            // instatiate form
            this.Frm = (Form)Assembly.GetExecutingAssembly().CreateInstance(Assembly.GetExecutingAssembly().GetName().Name + "." + FormName);

            // show form
            this.Frm.Show();
        }

        // assign delegate
        this.AddMsg = new ProgressMsg(AddMsgMethodName);

        // Hide form
        this.Frm.Visible = !Hide;


    }

How can I pass the name of a form, and the method to call and then assign to the delegate the method from the form?

3 Answers 3

4
this.AddMsg = (ProgressMsg)Delegate.CreateDelegate(typeof(ProgressMsg), this.Frm, AddMsgMethodName);
Sign up to request clarification or add additional context in comments.

1 Comment

Great thanks. Always like it when the code can be reduced like that :-) That first line was a little difficult to read for me anyhow!
2

In .Net 4.5 you can use the CallerMemberNameAttribute to get the name of the calling method. I use this all the time with INotifyPropertyChanged. This way I can write this:

private string _name;
public string Name
{
    get { return this._name; }
    set
    {
        if (this._name != value)
        {
            this._name = value;
            this.OnPropertyChanged(); //no argument passed
        }
    }
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberNameAttribute]string propertyName = "")
{ //propertyName will be set to "Name"
    if (this.PropertyChanged != null)
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

See here for more

Comments

1

You can use reflection. The following code assumes that the method in question always takes exactly one parameter of type string.

var method = this.Frm.GetType().GetMethod(AddMsgMethodName,
      new Type[] { typeof(string) });

this.AddMsg = (ProgressMsg)Delegate.CreateDelegate(typeof(ProgressMsg), this.Frm, method);

5 Comments

I'm getting a casting (or lack of) error? Cannot implicitly convert type 'System.Delegate' to 'Progress.ProgressMsg'. An explicit conversion exists (are you missing a cast?)
I explicitly cast it and it seems to be OK. this.AddMsg = (ProgressMsg) Delegate.CreateDelegate(typeof(ProgressMsg), method);
Thanks, that was doing my head in. I'm very fuzzy when it comes to delegates, If I have to hard code the method to call, why am I not simply calling it? - I'm missing some point for sure, and just hope it comes with time.
You don't need the first line as you can simply provide the method name instead of the MethodInfo as a parameter for CreateDelegate. See my answer. You won't have to specify parameter types for the delegate as well then.
@RobertS.: Nice catch, +1 from me. I'll leave my answer here, since it's more robust with respect to multiple overloads.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.