Winフォームアプリで、イベントを学びましょう(応用)

2022年7月26日

ここでは、基本編で学んだことを実際にコード化したもので確認します

進むには、まずここをしっかり確認しておいてください

実行結果

実行結果から見てもらいます
クリックすると、各フォームのメソッド(イベントハンドラ)が実行され、背景色が変更されます
これは、イベントの仕組みで実現しています
いくつフォームを追加作成しても動作します
イベント以外でも作成可能ですが、メソッド間を行ったり来たりでなかなかまとまらないと思いますし、関係性が複雑になるでしょう。イベントとの違いも考えながら見てください

実際のフォーム設計とコード

フォーム設計

コード

Form1.cs

最初に表示されるフォーム

メインのフォームから各フォームのメソッドを呼び出すときの違い

イベントを使うと、メインのフォームにメソッド呼び出しの具体的なコードが書く必要がありません。
メソッド呼び出しで同じことをする場合、必要なメソッドの数だけ呼び出し文が必要になります。
配列やListにして繰り返し文で複数のメソッドを呼び出すようにしても、結局は必要な数だけメインフォームの側で対処する必要があります。また、動的に(実行中に)呼び出すメソッドを追加したり削除したりすることもできません。

using System;
using System.Windows.Forms;

namespace ChangeFormColorEvent
{
    public delegate void ChangeFormColorEventHandler();

    public partial class Form1 : Form
    {
        public static event ChangeFormColorEventHandler ChangeFormColor;

        public Form1()
        {
            InitializeComponent();

            Form form2 = new ColorForm();
            form2.Show();

            Form form3 = new ColorForm();
            form3.Show();
            
            Form form4 = new ColorForm();
            form4.Show();

            // フォームを作って表示するだけならこれでもいい
            for (int i = 0; i < 3; i++)
            {
                new ColorForm().Show();
            }
        }

        ///
        private void button1_Click(object sender, EventArgs e)
        {
            ChangeFormColor.Invoke();
        }
    }
}

ColorForm.cs

プロジェクトにWinフォームを追加、名前をColorFormとしています

using System;
using System.Drawing;
using System.Windows.Forms;

namespace ChangeFormColorEvent
{
    public partial class ColorForm : Form
    {
        public ColorForm()
        {
            InitializeComponent();

            Form1.ChangeFormColor += Form1_ChangeFormColor;
        }

        Random random = new Random();

        /// <summary>
        /// 背景色をランダムに変える
        /// </summary>
        private void Form1_ChangeFormColor()
        {
            // KnownColorは列挙型ですが、int設定では、今回はこの範囲がいいでしょう
            int color = random.Next(28, 168);

            SetBackColor(color);
        }

        /// <summary>
        /// 背景色を整数で設定
        /// </summary>
        /// <param name="color">28から167。KnownColor列挙型のよさそうな範囲です</param>
        private void SetBackColor(int color)
        {
            // KnownColorは列挙型なので、intを列挙型に変換します
            KnownColor enumValue = (KnownColor)Enum.ToObject(typeof(KnownColor), color);

            // KnownColor列挙型をColor型に変換して背景色に設定
            BackColor = Color.FromKnownColor(enumValue);

            ShowColorName(enumValue);
        }

        /// <summary>
        /// 色の名前を表示
        /// </summary>
        /// <param name="enumValue">色の列挙型</param>
        private void ShowColorName(KnownColor enumValue)
        {
            label1.Text = enumValue.ToString();
            label1.BackColor = Color.White;
        }
    }
}