まるまるこふこふ

数々の次元が崩壊し、全ての生命が塵と化すのを見てきた。私ほどの闇の心の持ち主でも、そこには何の喜びも無かった。

フォーム間でデータの受け渡しをクールに行う。

さいちゃんです。

C#Windowsアプリケーションを作ってると、


「ここでユーザーが情報を入力するための子フォーム開いて、入力されたデータを親フォームのGridViewに反映させたいな~」

「親フォームのデータを子フォームに表示させて、子フォームの内容をユーザーが編集したら親フォームで受け取りたいな~」


ってこと、あると思います!色々と方法はあるし、「フォーム間 値 受け渡し c#」みたいな検索ワードでググれば星の数ほど出てくるのですが、親フォームや子フォームにpublicなアクセサを撒き散らすことになるので、美しくないな~と思いました。なので作ってみました。

まずは親フォーム

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void submitButton_Click(object sender, EventArgs e)
        {
            //Form2に送るテキスト
            string sendText = SendTextBox.Text;

            //Form2から送られてきたテキストを受け取る。
            string receiveText = Form2.ShowMiniForm(sendText); //Form2を開く

            //Form2から受け取ったテキストをForm1で表示させてあげる。
            ReceiveTextBox.Text = receiveText;
        }
    }
}

親フォームが子フォームを開くためにやってるのは、

string receiveText = Form2.ShowMiniForm(sendText); //Form2を開く

だけです。子フォームに渡したい情報を引数に入れて、戻り値に子フォームから送られてきた
情報が入ってる。便利!直感的!



続きまして、肝心の子フォーム

Form2.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        private string[] argumentValues; //Form1から受け取った引数
        public string ReturnValue;       //Form1に返す戻り値

        public Form2(params string[] argumentValues)
        {
            //Form1から受け取ったデータをForm2インスタンスのメンバに格納
            this.argumentValues = argumentValues;

            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            //Form1から送られてきたテキストをForm2で表示
            this.ReceiveTextBox.Text = argumentValues[0];
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {
            //戻り値をセット
            this.ReturnValue = SendTextBox.Text;

            this.Close();
        }

        static public string ShowMiniForm(string s){

            Form2 f = new Form2(s);
            f.ShowDialog();
            string receiveText = f.ReturnValue;
            f.Dispose();

            return receiveText;
        }
    }
}

さてさてこのForm2クラス、フォームを表示させるには

Form2 f = new Form2(s);
f.ShowDialog();
string receiveText = f.ReturnValue;
f.Dispose();

って感じの手続きを行います。これはそんじょそこらに転がってる
フォームの開き方と一緒ですね。

これをラッパーしてるのが静的メソッドShowMiniForm()です。
静的メソッドなのでわざわざnewでインスタンス作らなくてもForm2.ShowMiniForm()で即Form2を開けます。


さて実際にアプリケーションを作る際は、この子フォームform2をゴチャゴチャカスタマイズしていくわけですが、親フォームから受け取ったデータはargumentValuesメンバに入ってるので、どのメソッドからでも参照できます。

また子フォームでやる事無くなって、親フォームにデータ渡して戻りたいなら、

this.ReturnValue = "ここに親フォームに渡したい情報を入れる"
this.Close();

でokです。


今回は引数、戻り値ともにstring型にしましたが、適当なコレクションの型にしてやると、より多くの情報を子フォームと親フォームで受け渡しできますよ。

また引数にthisを入れられるようにすると、子フォームから親フォームのTextBoxの内容やDataGridViewの中身を直接いじることも可能です。

その辺詳しくは
別のフォームのデータを取得、設定する: .NET Tips: C#, VB.NET
辺りも参照に。