Reputation: 1693
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
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