9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

WinForms での、フォーム間でのデータの受け渡し方法

Last updated at Posted at 2021-08-03

GUIを勉強し始めた頃に悩んだので、記録としてここに残します。

方法① サブフォームから、メインフォームの公開プロパティに値をセットする。

この場合、サブフォームがメインフォームのpublicプロパティにアクセスする必要があるので、
サブフォームがメインフォームへの参照を持つ必要があります。
※サブフォームにpublicプロパティを作って、メインフォームがアクセスしても同じ。

public class MainForm : Form
{
    public string PublicProperty { get; set; }

    public void ShowSubForm()
    {
        var form = new SubForm()
        {
            ParentForm = this;
        };
        form.Show();
    }
}

public class SubForm : Form
{
    public Form ParentForm { get; set; }

    private void SetValueMethod()
    {
        ParentForm.PublicProperty = "テキスト";
    }
}

方法② データ受け渡し用のクラスを介して受け渡しする。

この方法なら、メインフォームとサブフォームが互いに参照することなく、データを受け渡し出来ます。

public static class DataClass
{
    public static string StringValue { get; set; }
}

public class MainForm : Form
{
    private string PrivateStringProperty { get; set; }

    public void GetValueMethod()
    {
        PrivateStringProperty = DataClass.StringValue;
    }
}

public class SubForm : Form
{
    public void SetValue()
    {
        DataClass.StringValue = "テキスト";
    }
}

方法③ イベントを使って渡す。

イベントを使う方法は、方法④ イベントを使って、DBを仲介してデータを受け渡しする時に便利。

public class MainForm : Form
{
    private string PrivateStringProperty { get; set; }

    public void ShowSubForm()
    {
        var form = new SubForm()
        {
            ParentForm = this;
        };
        form.DataPassEvent += SubForm_DataPassEvnet;
        form.Show();
    }

    private void SubForm_DataPassEvnet(object sender, DataPassEventArgs e)
    {
        PrivateStringProperty = e.StringData;
    }
}

public class SubForm : Form
{
    public delegate void DataEventHandler(DataPassEventArgs e);
    //このイベントをメインフォームでListenする。
    public event DataEventHandler DataPassEvent;

    private string StringDate;

    public void SetValue()
    {
        //ここでデータを加工したりする処理をして・・・
        //空白でない時だけ、イベントを起こしたりも出来る。
        if(!string.IsNullOrWhiteSpace(StringDate))
        {
            DataPassEvent?.Invoke(new DataPassEventArgs(StringData));
        }
    }
}

public class DataPassEventArgs : EventArgs
{
    public string StringData { get; set; }

    public DataPassEventArgs(string data)
    {
        StringData = data;
    }
}


方法④ イベントを使って、DBを仲介してデータを受け渡しする。

①サブフォームでDB更新 → ②DB更新した事をイベントとして通知 → ③メインフォームがDBのデータを参照
という流れ。
今回の場合は、データはDBにあるので、独自のEventArgsで渡す必要はありません。
必要であれば、更新したレコードの主キー等、渡す必要があるデータを渡すEventArgsを作ります。

public class MainForm : Form
{
    public void ShowSubForm()
    {
        var form = new SubForm();
        form.DatabaseUpdateCompleted += SubForm_DatabaseUpdateCompleted;
        form.Show();
    }

    private void SubForm_DatabaseUpdateCompleted(object sender, EventArgs e)
    {
        //データベースからデータを取得する処理。
    }
}

public class SubForm : Form
{
    public event EventHandler DatabaseUpdateCompleted;

    public void UpdateDatabase()
    {
        //ここでデータベースにレコードをInsertしたりUpdateしたりして・・・
        //その後、イベント起動。
        DatabaseUpdateCompleted?.Invoke(null, new EventArgs());
    }
}

方法⑤ データ受け渡し用クラスで、データ変更イベントを起動して他のフォームに変更を通知する。

①サブフォームでDataClassのデータ更新 → ②DataClassがデータ変更イベントを起動 → ③イベントをListenしているメインフォームがデータを受け取る。
という流れ。

namespace Test
{
    public class MainForm : Form
    {
        static void Main(string[] args)
        {
            Application.Run(new MainForm());
        }

        public MainForm()
        {
            //データ管理用クラスの、データ変更イベントをListenする。
            DataClass.DataPassEvent += DataClass_DataPassEvent;

            //サブフォーム内に実装した、データを変更するメソッドを呼び出す。
            //下記メソッドはどのクラスから呼び出してもいいが、今回は2つしかクラスがないので、このクラスで呼び出す。
            new SubForm().Method();
        }

        private static void DataClass_DataPassEvent(DataChangeEventArgs e)
        {
            //データ変更前後の値を表示する。
            //メッセージBOXは4回表示され、表示結果は以下
            //------------------------------------------
            //①変更前は で 変更後は あいうえお
            //②変更前は あいうえお で 変更後は かきくけこ
            //③変更前は かきくけこ で 変更後は さしすせそ
            //④変更前は さしすせそ で 変更後は たちつてと
            //------------------------------------------
            MessageBox.Show($"変更前は { e.OldStringData } で 変更後は { e.NewStringData } ");
        }
    }

    public class SubForm : Form
    {
        //データ管理用クラスのデータを変更する。
        public void Method()
        {
            DataClass.StringValue = "あいうえお";
            DataClass.StringValue = "かきくけこ";
            DataClass.StringValue = "さしすせそ";
            DataClass.StringValue = "たちつてと";
        }
    }

    //データ管理用クラス
    public static class DataClass
    {
        public delegate void DataEventHandler(DataChangeEventArgs e);
        //このイベントをメインフォームとサブフォームでListenする。
        public static event DataEventHandler DataPassEvent;

        private static string oldValue;
        private static string newValue;

        public static string StringValue
        {
            get { return newValue; }
            set
            {
                //データ変更前後の値が違っていれば・・・
                if (oldValue != value)
                {
                    //元々あった値をoldValueに退避
                    oldValue = newValue;
                    //newValueにセットし・・・
                    newValue = value;
                    //データ変更イベントを起動する。
                    DataPassEvent?.Invoke(new DataChangeEventArgs(oldValue, newValue));
                };
            }
        }
    }

    //変更前後の値を渡す為のEventArgs
    public class DataChangeEventArgs : EventArgs
    {
        public string OldStringData { get; set; }
        public string NewStringData { get; set; }

        public DataChangeEventArgs(string oldData, string newData)
        {
            OldStringData = oldData;
            NewStringData = newData;
        }
    }
}
9
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?