我有这个方法及其委托,用于从我的WinForms应用程序中的任何线程将文本附加到GUI中的多行TextBox:
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();
}
}
它工作得很好,我只是从任何线程调用TextAppend(myTextBox1,“Hi Worldo!”)并更新GUI。现在,有没有办法将调用TextAppend的委托传递给另一个项目中的一个实用程序方法而不发送任何对实际TextBox的引用,这可能是调用者看起来像这样:
Utilities.myUtilityMethod(
new delegate(string str){ TextAppend(myTextBox1, str) });
在被叫方中,定义类似于:
public static void myUtilityMethod(delegate del)
{
if(del != null) { del("Hi Worldo!"); }
}
因此,当调用此函数时,它会调用带有该字符串的TextAppend方法以及调用者想要使用的预定义TextBox。这可能还是我疯了?我知道有更简单的选项,如使用接口或传递TextBox和委托,但我想探索这个解决方案,因为它似乎更优雅,并隐藏来自被调用者的东西。问题是我在C#中仍然是新手并且几乎不了解代理,所以请帮助我使用实际的语法。
提前致谢!
答案 0 :(得分:14)
假设您正在使用C#3(VS2008)或更高版本:
Utilities.myUtilityMethod(str => TextAppend(myTextBox1, str));
...
public static void myUtilityMethod(Action<string> textAppender)
{
if (textAppender != null) { textAppender("Hi Worldo!"); }
}
如果您使用的是.NET 2.0,则可以使用匿名方法而不是lambda表达式:
Utilities.myUtilityMethod(delegate(string str) { TextAppend(myTextBox1, str); });
如果您使用的是.NET 1.x,则需要自己定义委托并使用命名方法:
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!"); }
}