2019-08-28に投稿

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

あるデータを元にチェックボックスを等間隔に動的配置する方法を試してみました。

プロジェクト新規作成

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

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

何かの参考になれば。

ではでは。

 

Originally published at www.doraxdora.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

doraxdora

IT関係の仕事をしています/1985年生まれの東京在住/便利なサービスやツール漁りや料理などが好き/2017年~ブログやってます/自分でサービスとか作ってリリースしたい/何かありましたらお気軽にDMどうぞ

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント