Концепция обратных вызовов (C #) - PullRequest
1 голос
/ 26 августа 2011

Привет, у меня есть форма (Форма A), в которой есть кнопка «Добавить», которая открывает форму для ввода текста (Форма B).После того, как вы ввели текст в форму B, вы нажимаете «OK» (btnOK).На этом этапе я хочу, чтобы форма A получила текст и что-то с ним сделала.

Из того, что я вижу, у меня есть два варианта:

1) Форма A передает функцию (делегат) в формуB, который выполняет его в функции btnOK_Click.

2) Я каким-то образом регистрирую метод в форме A с событием btnOK.Click.

Я на правильном пути и можете ли вы вспомнить какой-либорешения аналогичной проблемы, которую я могу прочитать, потому что у меня проблемы со статическими методами и событиями ...

Ответы [ 5 ]

6 голосов
/ 26 августа 2011

Если форма B является модальным окном, вы можете добавить свойство публичной строки в форму B.

Когда пользователь закрывает форму B, вы можете установить свойство для текста, который был введен пользователем. Затем, вернувшись в форму A, вы можете прочитать открытое свойство формы B, чтобы получить текст, введенный пользователем.

4 голосов
/ 26 августа 2011

Добавьте в форму B свойство, похожее на

public class FormB { ...
   public string Text
   {
      get { return textBox.Text; }
   }
   ...
}

Если вы показываете форму b, как показано ниже:

FormB b = new FormB();
WPF: if (b.ShowDialog() != true) return;
Winforms: if (b.ShowDialog(this) != DialogResult.Ok) return;

string txt = b.Text;

Итак, в основном вы показываете модальную форму b, где пользователь может вводить текст. После закрытия формы b.ShowDialog вернется из блокировки. В этот момент вы можете запросить свойство Text у b и получить строку. Свойство Text должно быть привязано к текстовому полю b с помощью некоторого метода.

Если вы не хотите показывать b модально, вы можете сделать это:

FormB b = new FormB();
b.Closed += new EventHandler(FormB_Closed);

b.Show();

private void FormB_Closed(object sender, EventArgs e)
{
    string text = ((FormB)sender).Text;

    ... do something
}
2 голосов
/ 26 августа 2011

Лучшим решением было бы поместить публичную собственность в форму B, содержащую нужный вам текст. Затем просто получите доступ к этому свойству из формы A после выхода из формы B.

1 голос
/ 26 августа 2011

Вы также можете создать подкласс формы ...

public class FormWithResult : Form
{
    protected object FormResult { get; set; }

    public DialogResult ShowDialog(out object result)
    {
        DialogResult dr = ShowDialog();
        result = FormResult;
        return dr;
    }

    public DialogResult ShowDialog(out object result, IWin32Window win)
    {
        DialogResult dr = ShowDialog(win);
        result = FormResult;
        return dr;
    }

    public void Return(object result)
    {
        FormResult = result;
        Close();
    }

}

Затем вы можете написать это для вызова модальной формы и получить результат

        popup p = new popup();
        object result;
        p.ShowDialog(out result);
        MessageBox.Show((string)result);

И в вашем всплывающем окнеформу, которую вы можете сделать:

        FormResult = textBox1.Text;
        Close();

ИЛИ

        Return(textBox1.Text);

Чтобы закрыть форму и вернуть значение.

Форма подклассов, конечно, также имеет недостатки, ноЯ выброшу это как другое решение.

С другой стороны, универсальная версия, в которой вы могли бы строго ввести возвращаемое значение, была бы намного лучше, если бы не было этого ограничения во время разработки: Visual Studio 2008 Winform дизайнер не можетзагрузить форму, которая наследуется от универсального класса

. Если вы хотите получить асинхронные результаты, очевидно, это необходимо настроить.Я предполагаю, что вы используете модальные всплывающие окна.

1 голос
/ 26 августа 2011

Я предпочитаю # 1 - прохождение делегата чисто и просто

class BInputValues {
    public String Field1 { get; set; }
    //...
};

partial class FormB {
    readonly Action<BInputValues> callback;

    public FormB(Action<BInputValues> callback) {
        this.callback = callback;
    }

    protected override void btnOK_Click(object sender, EventArgs e) {
        callback(new BInputValues {
            Field1 = Field1.Text, 
            //...
        });
    }
}

override void btnAdd_click() {
    var formb = new FormB(args => {
        // do something with args
    });
    formb.ShowModal();
}
...