回调的概念(C#)

时间:2011-08-26 16:38:06

标签: c# windows delegates callback

您好我有一个表格(表格A),其中有一个“添加”按钮,弹出一个文字输入表格(表格B)。在表格B中输入文本后,按“确定”(btnOK)。在这一点上,我希望表单A获取文本并使用它做一些事情。

从我看到的我有两个选择:

1)表单A将函数(委托)传递给表单B,表单B在btnOK_Click函数中执行它。

2)我以某种方式在表单A中使用btnOK.Click事件注册一个方法。

我是否在正确的轨道上,你能想到我能读到的类似问题的任何解决方案,因为我遇到了静态方法和事件的麻烦......

5 个答案:

答案 0 :(得分:6)

如果表单B是模态窗口,则可以向表单B添加公共字符串属性。

当用户关闭表单B时,您可以将该属性设置为用户输入的文本。然后,回到表单A,您可以阅读表单B的公共属性以获取用户输入的文本。

答案 1 :(得分:4)

添加一个属性以形成类似于

的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将从阻止返回。此时,您可以请求b的Text属性并检索字符串。 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 :(得分:2)

更好的解决方案是在表单B上放置一个包含所需文本的公共属性。然后,只需在表格B退出后从表格A访问该属性。

答案 3 :(得分:1)

我更喜欢#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();
}

答案 4 :(得分:1)

你也可以创建一个Form的子类......

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();

OR

        Return(textBox1.Text);

关闭表单并返回值。

Subclassing Form当然也有缺点,但我会把它作为另一种解决方案。

作为一方而言,如果在设计时不是这种限制,那么您可以强烈键入返回值的通用版本会更好:Visual Studio 2008 Winform designer fails to load Form which inherits from generic class

如果您希望异步结果显然需要进行调整。我假设您正在使用Modal弹出窗口。