2

以下のように、別のフォームForm2でForm1のパブリックメソッドにアクセスしようとしています。私はtextbox6form1を制御していて、それをバインドするためのパブリックメソッドがあります。しかし、私はそれを以下のように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"]);
        }    
    }
}

Form2

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

上記のメソッド呼び出しは間違っています。修正方法を提案してください。

publicメソッドを呼び出してForm1のtextBox6コントロールをForm2のイベントハンドラーからバインドしたいのですが、Form2を閉じると、Form1のコントロールをバインドする必要があります。Form2からpublicメソッドを呼び出すことでそれは可能ですか?Button_Clicktextbox6

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

これに関する1つの問題は、Form1とForm2の間に強い結合が作成されることです。Form1で何かを変更すると、Form2を壊したり、その逆を行ったりするのは簡単です。

2-代理人を渡す

Form1全体をForm2に渡す代わりに、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();
    }

Form2:

    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クラスにメンバー変数を設定することです。Form1型の値を取り、その中にメンバー変数を設定するコンストラクターまたはプロパティをForm2で定義できます。Form1がForm2のインスタンスを作成するとき、コンストラクターを呼び出して、プロパティをに渡すthisか、プロパティをに設定できますthis。次に、Form2でボタンをクリックすると、Form1の新しいインスタンスを作成する代わりに、amount_sum()すでに保存されているForm1インスタンスのメソッドを呼び出すことができます。

于 2010-11-14T08:33:02.087 に答える