Делегировать с параметрами ... как параметр - PullRequest
6 голосов
/ 28 октября 2011

У меня есть этот метод с его делегатом, который используется для добавления текста в многострочный TextBox в GUI из любого потока в моем приложении WinForms:

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, "Привет, Worldo!") из любого потока, и графический интерфейс обновляется.Теперь есть какой-то способ передать делегат, который вызывает 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 # и плохо понимаю делегатов, поэтому, пожалуйста, помогите мне с фактическим синтаксисом, который будет работать.

Заранее спасибо!

1 Ответ

15 голосов
/ 28 октября 2011

Если вы используете 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, вы можете использовать анонимный метод вместо лямбда-выражения:

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!"); }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...