R. Ruiz.
R. Ruiz.

Reputation: 1693

Delegate with parameters... as a parameter

I have this method with its delegate that is used to append text to a multiline TextBox in the GUI from any of the threads in my WinForms application:

private delegate void TextAppendDelegate(TextBox txt, string text);
public void TextAppend(TextBox txt, string text)
{
  if(txt.InvokeRequired)
    txt.Invoke(new TextAppendDelegate(TextAppend), new object[] {txt, text });
  else
  {
    if(txt.Lines.Length == 1000)
    {
      txt.SelectionStart = 0;
      txt.SelectionLength = txt.Text.IndexOf("\n", 0) + 1;
      txt.SelectedText = "";
    }
    txt.AppendText(text + "\n");
    txt.ScrollToCaret();
  }
}

It works great, I just call TextAppend(myTextBox1, "Hi Worldo!") from any thread and the GUI is updated. Now, is there some way to pass a delegate that invokes TextAppend to one of my utility methods in another project without sending any reference to the actual TextBox, something that might look like this from the caller:

Utilities.myUtilityMethod(
    new delegate(string str){ TextAppend(myTextBox1, str) });

And in the callee, a definition similar to:

public static void myUtilityMethod(delegate del)
{
    if(del != null) { del("Hi Worldo!"); }
}

So that when this function is called, it invokes the TextAppend method with that string and the predefined TextBox the caller wants to use. Is this possible or am I crazy? I know there are way easier options like using interfaces or passing the TextBox and delegate, but I want to explore this solution because it seems more elegant and hides stuff from the callee. The problem is that I'm still too novice in C# and barely understand delegates, so please help me with the actual syntax that would work.

Thanks in advance!

Upvotes: 8

Views: 43912

Answers (1)

Thomas Levesque
Thomas Levesque

Reputation: 292345

Assuming you're using C# 3 (VS2008) or later:

Utilities.myUtilityMethod(str => TextAppend(myTextBox1, str));

...

public static void myUtilityMethod(Action<string> textAppender)
{
    if (textAppender != null) { textAppender("Hi Worldo!"); }
}

If you're using .NET 2.0, you can use an anonymous method instead of a lambda expression:

Utilities.myUtilityMethod(delegate(string str) { TextAppend(myTextBox1, str); });

If you're using .NET 1.x, you need to define the delegate yourself and use a named method:

delegate void TextAppender(string str);

void AppendToTextBox1(string str)
{
    TextAppend(myTextBox1, str);
}

...

Utilities.myUtilityMethod(new TextAppender(AppendToTextBox1));

...

public static void myUtilityMethod(TextAppender textAppender)
{
    if (textAppender != null) { textAppender("Hi Worldo!"); }
}

Upvotes: 15

Related Questions