[C#]LabelなどGUIコントロールの動的生成コードを一瞬で作る方法

VisualStudioでWinFormを使って画面を作る際、通常はボタンやテキストボックスなどのGUIパーツ(コントロール)を画面から設定していきます。
ツールボックスからパーツをドラッグして、プロパティから各種設定を行うのが通常のパターンですね。


時にはこのコントロールを動的に作成したい場合があります。各コントロールは単なるクラスなので、このような場合でも、動的生成したいコントロールのクラスをnewしてプロパティをセットするプログラムを書けば問題なく動的生成が行えます。

ですが、動的にコントロールを作る場合、何のプロパティをセットしたら自分が思ったような設定になるのか、試行錯誤するのが結構大変です。

このような場合は下記の手順で作業すると、簡単かつ速くコントロールを動的生成するコードを書けます。

コントロールを動的生成するメソッドの作り方


まずは、VisualStudioから、今までどおりコントロールを作ります。
今回は、LabelをForm上に置き、背景色やサイズ、ラベルテキストなどを修正しました。



プロパティのペインで見ると、黒字になっている項目が変更している箇所です。


上の画像だとちょっと見づらいですが、下記のプロパティを変えています。

Name
BackColor
BoarderStyle
Location
Size
TabIndex
Text
TextAlign




次に、ソリューションエクスプローラに表示されているファイル一覧からForm1.Designer.csをダブルクリックしてソースを表示させます。


ファイル中にあるInitializeComponent()メソッドの中を見ると、先ほど設定したlabelの設定内容がC#のプログラムとして表示されています。

namespace Project1
{
    partial class Form1
    {
        /// <summary>
        /// 必要なデザイナー変数です。
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        ...
 
        #region Windows フォーム デザイナーで生成されたコード
        /// <summary>
        /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディターで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
 
            // 
            // label1
            // 
            this.label1.BackColor = System.Drawing.Color.MistyRose;
            this.label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.label1.Location = new System.Drawing.Point(12, 9);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(40, 40);
            this.label1.TabIndex = 3;
            this.label1.Text = "65535";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
 
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(256, 256);
            this.Controls.Add(this.label1);
            ...
        }
        #endregion
 
        private System.Windows.Forms.Label label1;
    }
}



今回はnameをlabel1として作ったので、label1に関する定義だけを抽出してメソッドにします。
今回の例では分かりやすいよう、以下のように名前をlabel1からmyLabelに変えてみました。

private System.Windows.Forms.Label myLabel;
 
private void createCustomLabel()
{
    this.myLabel = new System.Windows.Forms.Label();
 
    this.myLabel.BackColor = System.Drawing.Color.MistyRose;
    this.myLabel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
    this.myLabel.Location = new System.Drawing.Point(12, 9);
    this.myLabel.Name = "myLabel";
    this.myLabel.Size = new System.Drawing.Size(40, 40);
    this.myLabel.TabIndex = 3;
    this.myLabel.Text = "65535";
    this.myLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
 
    this.Controls.Add(this.myLabel);
}



メソッド化が終わったら、元のlabel1はFormから削除してしまいます。


次に、このメソッドをコールします。
たとえば、ボタンがクリックされたらラベルを生成したいのであれば、以下のような感じになります。

private void button1_Click(object sender, EventArgs e)
{
    createCustomLabel();
}



プログラムを実行し、ボタンをクリックすると、想定どおりボタンクリックをトリガにラベルが動的生成されます。


もう少し補足


コントロールにイベントハンドラを指定したい場合も、同じようにイベントハンドラを設定してからForm1.Designer.csをコピペすればOKです。
以下のような感じで、イベントハンドラの追加処理が記載されているはずです。

private void InitializeComponent()
{
    ...
    this.label1.Click += new System.EventHandler(this.label1_Click);
}




実行してみてもうまく表示されない場合は、他のパーツの裏に隠れているだけの可能性があります。下記のメソッドを書くと問題の切り分けになるかもしれません。

myLabel.BringToFront();




コントロールを動的生成させる場所を変更したい場合は、Controls.Addの処理を書き換えます。
Formの直下に生成するのではなく、Formに貼り付けたPanel内に生成したい場合は、以下のような感じにします。

this.Controls.Add(this.myLabel);
↓
panel1.Controls.Add(this.myLabel);




複数のラベルを動的に作りたい場合は、変数を配列やListにすればOKです。

private System.Windows.Forms.Label myLabel;private List<System.Windows.Forms.Label> newLabel = new ...;



関連記事

コメントを残す

メールアドレスが公開されることはありません。