表格之间公共方法的访问

我试图在另一个Form2上访问Form1的公共方法,如下所示。 我在form1上有一个textbox6控件,并且有绑定它的公共方法。 但是我想用form2绑定它,如下所示。

Form1中

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Form2 f2 = new Form2(); f2.Show(); } public void amount_sum() { string connstr = " server=.;initial catalog=maa;uid=mah;pwd=mah"; SqlConnection con = new SqlConnection(connstr); con.Open(); string sql = " select sum(amount)as amount from method"; SqlDataAdapter dap = new SqlDataAdapter(sql, con); DataSet ds = new DataSet(); dap.Fill(ds); for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { textBox6.Text = Convert.ToString(ds.Tables[0].Rows[i]["amount"]); } } } 

窗体2

 private void button1_Click(object sender, EventArgs e) { Form1 f1 = new Form1(); f1.amount_sum(); this.Close(); } 

上面的方法调用是错误的。 请建议如何纠正它。

我想通过调用public方法从Form2的Button_Click事件处理程序绑定Form1的textBox6控件,当Form2关闭时,应该绑定Form1的textbox6 。 这可以通过从Form2调用公共方法吗?

在Form2中你有

 Form1 f1 = new Form1(); f1.amount_sum(); 

当您想要在表单之间传回答案时,这似乎是创建新Form1的常见错误。 new关键字就是这样,它创建一个新的Form1,调用方法,不显示表单,Form1的原始实例不受影响。

我将展示一些如何解决这个问题的步骤。

1 – 将Form1传递给Form2

您可以做的第一件事是简单地将现有的Form1传递给Form2,以便Form2知道它应该更新哪个Form1。

 public class Form2 { private readonly Form1 _form1; public Form2(Form1 form1) { _form1 = form1; } private void button1_Click(object sender, EventArgs e) { _form1.amount_sum(); // now this updates the existing form1 instance this.Close(); } } 

在Form1中

 private void button1_Click(object sender, EventArgs e) { Form2 f2 = new Form2(this); // pass this form1 instance to form2 f2.Show(); } 

这个问题的一个问题是在Form1和Form2之间创建了一个强大的耦合。 如果您在Form1中更改某些内容,则很容易打破Form2,反之亦然。

2 – 通过代表

我们可以简单地将委托传递给Form2可以运行的更新方法,而不是将整个Form1传递给Form2。 这会在Form1和Form2之间创建较少的耦合,如果从Form3调用Form2,则可以传入Form3的更新方法,而Form3将更新。 相同的Form2可以不经修改地重复使用。

 public class Form2 { private readonly Action _ammountUpdater; public Form2(Action ammountUpdater) { _ammountUpdater = ammountUpdater; } private void button1_Click(object sender, EventArgs e) { _ammountUpdater(); // now this updates the existing form1 instance this.Close(); } } 

在Form1中

 private void button1_Click(object sender, EventArgs e) { Form2 f2 = new Form2(this.amount_sum); // pass the update method to form2 f2.Show(); } 

现在你可以将amount_sum更改为private,因为它现在实际上是Form1的内部事务。

我会使你的amount_sum方法成为一个返回值的实用工具方法,例如:

 public static decimal GetTotalFoobarAmount() { // decimal is just a guess here // omitted: sql code return theAnswer; } 

然后,例如, 两个代码块都可以调用此方法。

 textBox6.Text = YourClass.GetTotalFoobarAmount().ToString(); 

作为一个附带好处,它还减少了UI和数据库之间的耦合,这通常被认为是一件好事。 如果查询需要当前来自表单的值,请在方法中创建这些参数。 另请注意,要返回单个值,您可能需要查看ExecuteScalar ; 它不会产生巨大的差异,但它比填充DataTable和循环单行更直接。

您也可以使用以下活动:

  public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Form2 f2 = new Form2(); f2.ButtonClickAction += f2_ButtonClickAction; f2.Show(); } void f2_ButtonClickAction() { amount_sum(); } 

窗体2:

  public Form2() { InitializeComponent(); } public event Action ButtonClickAction; private void button1_Click(object sender, EventArgs e) { Action a = ButtonClickAction; if (a != null) a(); this.Close(); } 

Marc Gravell的答案可能就足够了,但一般来说,如果你想在类的特定实例上调用实例方法,你不能只创建一个新方法并在该实例上调用它。 对于您的示例,您需要在已存在的Form1实例上调用该方法。 最好的方法是在Form1类型的Form2类上有一个成员变量。 您可以在Form2上定义构造函数或属性,它采用Form1类型的值并在其中设置成员变量。 当Form1创建Form2的实例时,它可以调用构造函数并传入this属性或将属性设置为this 。 然后,当在Form2上单击该按钮时,它可以调用已存储的Form1实例上的amount_sum()方法,而不是创建Form1的新实例。