【C#】WindowsForm にチェックボックスを動的に配置してみる

2018年8月14日C#,開発

おはようございます。

今回はちょっと久しぶりにC#の話し。
あまり使いどころがあるかわかりませんが、
あるデータを元にチェックボックスを等間隔に動的配置する方法を試してみました。

スポンサーリンク

プロジェクト新規作成

今回は新規でプロジェクトを作成します。

Visual Studio を起動して、「ファイル」>「新規」からプロジェクトを作成してください。

画面の作成

画面作成中

「Label」、「TableLayoutPanel」、「Button」を配置します。
TableLayoutPanelによって、均等にチェックボックスを並べていくようになります。

プログラム

クラス追加

チェックボックスのデータを保持するクラスの追加

Option.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SampleCheckBoxDynamicArrangement
{
    /// <summary>
    /// 選択肢クラス
    /// </summary>
    class Option
    {
        /// <summary>
        /// チェックされているかどうか
        /// </summary>
        public Boolean IsChecked { set; get; }

        /// <summary>
        /// 表示テキスト
        /// </summary>
        public String Text { set; get; }

        /// <summary>
        /// 値
        /// </summary>
        public String Value { set; get; }

    }
}

 

メインの処理

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.Threading.Tasks;
using System.Windows.Forms;

namespace SampleCheckBoxDynamicArrangement
{
    public partial class Form1 : Form
    {
        private int toggleFlg = 0;

        /// <summary>
        /// 選択肢リスト
        /// </summary>
        private List<Option> options =new List<Option> {
            new Option{ IsChecked = false, Text = "チェック1", Value = "0"},
            new Option{ IsChecked = false, Text = "チェック2", Value = "1"},
            new Option{ IsChecked = false, Text = "チェック3", Value = "2"},
            new Option{ IsChecked = false, Text = "チェック4", Value = "3"},
            new Option{ IsChecked = false, Text = "チェック5", Value = "4"},
            new Option{ IsChecked = false, Text = "チェック6", Value = "5"},
            new Option{ IsChecked = false, Text = "チェック7", Value = "6"},
            new Option{ IsChecked = false, Text = "チェック8", Value = "7"},
            new Option{ IsChecked = false, Text = "チェック9", Value = "8"},
            new Option{ IsChecked = false, Text = "チェック10", Value = "9"}
        };
        
        /// <summary>
        /// 初期表示時の処理
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            AddCheckboxHorizontally();
        }

        /// <summary>
        /// チェックボックスを横方向に配置していく
        /// </summary>
        private void AddCheckboxHorizontally()
        {
            foreach (Option o in options)
            {
                CheckBox cb = createCheckBox(o);
                // 特に指定しなければ横に追加していく
                tableLayoutPanel1.Controls.Add(cb);
            }
        }

        /// <summary>
        /// チェックボックスを縦方向に配置していく
        /// </summary>
        private void AddCheckboxVertically() {

            int col = 0;
            int row = 0;
            int maxRow = 4;
            for(int idx = 0; idx < options.Count; idx++)
            {
                CheckBox cb = createCheckBox(options[idx]);
                if (row == maxRow)
                {
                    row = 0;
                    col++;
                }

                // 特に指定しなければ横に追加していく
                tableLayoutPanel1.Controls.Add(cb, col, row++);

            }
        }

        /// <summary>
        /// チェックボックスを作成.
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        private CheckBox createCheckBox(Option o)
        {
            CheckBox cb = new CheckBox();
            cb.Checked = o.IsChecked;
            cb.Text = o.Text;
            cb.Name = "chk_" + o.Value;
            cb.CheckedChanged += new EventHandler(CheckBoxCheckedChangeHandler);
            return cb;
        }

        /// <summary>
        /// チェックボックス状態変更ハンドラー.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckBoxCheckedChangeHandler(object sender, EventArgs e)
        {
            CheckBox cb = (CheckBox)sender;
            int index = int.Parse(cb.Name.Replace("chk_", ""));
            options[index].IsChecked = cb.Checked;
        }

        /// <summary>
        /// チェックボックスを削除する
        /// </summary>
        private void RemoveCheckBox()
        {
            for (int idx = tableLayoutPanel1.Controls.Count - 1; idx >= 0; idx--)
            {
                Control c = tableLayoutPanel1.Controls[idx];
                tableLayoutPanel1.Controls.Remove(c);
            }

        }

        /// <summary>
        /// 切替ボタンクリックイベント.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            RemoveCheckBox();
            if (toggleFlg == 0)
            {
                AddCheckboxVertically();
                toggleFlg = 1;
            } else
            {
                AddCheckboxHorizontally();
                toggleFlg = 0;
            }
        }

        /// <summary>
        /// 登録ボタンクリックイベント.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            int count = 0;
            foreach (Option o in options)
            {
                if (o.IsChecked)
                {
                    sb.Append(Environment.NewLine).Append(o.Text);
                    count++;
                }
            }
            sb.Insert(0, "チェックされたのは次の" + count + "件です。");

            if (count > 0)
            {
                MessageBox.Show(this, sb.ToString(), "チェック");
            }
            else
            {
                MessageBox.Show(this, "チェックされていません。", "チェック");
            }
            
        }
    }
}

起動してみる

起動直後
切替ボタン押下
いくつかチェックする
登録ボタン押下

縦、横に順番で並べることができました。

まとめ

動的に配置できれば、
選択肢に増減がある場合などに使えますね。

もっと上手い方法もあるかと思いますが、
今回はサクッと、選択肢のリストをグローバルで保持し、
チェックボックスのIDを利用してどこのチェックボックスがチェックされているかを判定しました。

ソース(プロジェクト)は、
初めて GitHub にアップしてみましたが、上げ方合ってるのかな。。

GitHub

何かの参考になれば。

ではでは。

 

スポンサーリンク


関連するコンテンツ

2018年8月14日C#,開発CheckBox,CSharp,プログラミング,動的に配置する

Posted by doradora