2

我正在尝试在另一个表单 Form2 上访问 Form1 的公共方法,如下所示。我textbox6在 form1 上有一个控件,并且有绑定它的公共方法。但我想通过form2来绑定它,如下所示。

表格1

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

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

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

4

4 回答 4

11

在 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 的 update 方法,而 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为私有,因为它现在确实是Form1的内部事务。

于 2010-11-14T08:37:32.033 回答
3

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

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

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

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

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

于 2010-11-14T08:16:24.443 回答
2

您也可以使用事件:

    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();
    }
于 2010-11-14T08:43:09.963 回答
1

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

于 2010-11-14T08:33:02.087 回答