コントロールを動的にフォームへ追加して使いたい
C#の記事
- C#でMySQLを使う - 1.開発環境インストール
- C#でMySQLを使う - 2.SELECT・画面表示
- C#でMySQLを使う - 3.追加更新と削除
- C#でのデータベースのデータのNULLかどうかの判定
- C#のdelegate(デリゲート)と=>(ラムダ式)はC言語の関数へのポインタに似た扱い
- 動的にコントロールを追加 - 1.ボタンクリック
- 動的にコントロールを追加 - 2.テキストボックスの参照【この記事】
前回はソースで動的にボタンコントロールをフォームへ追加して、クリックイベントを用いてみたんですが、今回はそれを応用して、さらにテキストボックスを動的に追加して、それらを参照します
テキストボックスを動的に追加して、それを参照してみる
新たにテキストボックスを追記してみる
ボタンの動的な追加ができたので、今度はテキストボックスを動的に追加して、それが他から参照できるかどうかをやってみました( ˙꒳˙ᐢ ) そのためには、テキストボックスを動的にソースから参照したときは、それぞれのテキストボックスをNameに識別名を割り当てないといけないことです。本来は設定ファイルやデータベースで受け持つけど、いきなり話が複雑になるので、今回は手法検証ということでプログラムにて。。。

今度は新たに「buttonCheckEntry」をボタン追加しました!このボタンをクリックすると、動的に追加したテキストフォームの内容を拾ってくれるようにソースコードを作ります(動的にテキストフォームを作成する前はグレーアウトします)。
usingSystem;usingSystem.Drawing;usingSystem.Text;usingSystem.Windows.Forms;namespaceMyTrainingCsFrm1{publicpartialclassForm1:Form{// フォーム呼び出しで作成するボタン(Windowsフォームのボタン - Buttonを継承する)privateKazumi75Button[]manyButtons;// フォーム呼び出しで作成するテキストボックスとその識別名privateTextBox[]manyTextBoxes;privatestring[]txtbxNm;// 配列の要素数(ここでは8個)privateconstintElementNum=8;publicForm1(){InitializeComponent();this.manyButtons=null;this.manyTextBoxes=null;this.txtbxNm=null;}// フォームを呼び出すボタンprivatevoidformCallButton_Click(objectsender,EventArgse){if(this.manyButtons!=null||this.manyTextBoxes!=null){MessageBox.Show("すでに表示されています");return;}// ボタンの各メッセージはここであらかじめ設定するstring[]msgs=newstring[ElementNum];msgs[0]="浦賀";msgs[1]="鎌倉";msgs[2]="三崎";msgs[3]="観音崎";msgs[4]="横須賀中央";msgs[5]="城ヶ島";msgs[6]="七里ガ浜";msgs[7]="馬堀";// テキストボックスの各識別名はここであらかじめ設定するthis.txtbxNm=newstring[ElementNum];this.txtbxNm[0]="txbUraga";this.txtbxNm[1]="txbKamakura";this.txtbxNm[2]="txbMisaki";this.txtbxNm[3]="txbKannonzaki";this.txtbxNm[4]="txbYokosuka";this.txtbxNm[5]="txbJogashima";this.txtbxNm[6]="txbShichirigahama";this.txtbxNm[7]="txbMabori";// ボタン(Windowsフォームのボタンを継承する)とテキストボックスの作成this.manyButtons=newKazumi75Button[ElementNum];this.manyTextBoxes=newTextBox[ElementNum];// ボタンとテキストボックスの各要素に対するプロパティ設定とフォーム配置for(inti=0;i<this.manyButtons.Length;i++){// インスタンス作成this.manyButtons[i]=newKazumi75Button();this.manyTextBoxes[i]=newTextBox();// ボタンの名前とテキストのプロパティを設定this.manyButtons[i].Name="OriginalButton"+i;this.manyButtons[i].Text="ボタン"+i;// テキストボックスの名前とテキストのプロパティを設定this.manyTextBoxes[i].Name=txtbxNm[i];this.manyTextBoxes[i].Text="("+(i+1)+"つ目に何か入れてね)";// ボタンクリック時に参照するリストボックスを指定this.manyButtons[i].targetLbox=listBox1;// ボタンクリック時のメッセージを設定this.manyButtons[i].buttonMsg=msgs[i];// ボタンのサイズと配置this.manyButtons[i].Size=newSize(100,20);this.manyButtons[i].Location=newPoint(10,10+i*22);// テキストボックスのサイズと配置this.manyTextBoxes[i].Size=newSize(150,20);this.manyTextBoxes[i].Location=newPoint(120,10+i*22);// フォームへの追加this.Controls.Add(this.manyButtons[i]);this.Controls.Add(this.manyTextBoxes[i]);// クリック時のボタンごとのイベント動作を作成するthis.manyButtons[i].eventMaking();}// フォーム呼び出し後は、テキストボックスの内容確認ボタンを有効化するbuttonCheckEntry.Enabled=true;}// 動的に呼び出したテキストボックスの内容を確認するボタンprivatevoidbuttonCheckEntry_Click(objectsender,EventArgse){StringBuildersb=newStringBuilder();// テキストボックスを識別名で探し、その内容を取得するfor(inti=0;i<ElementNum;i++){sb.Append("["+i+"]");// フォーム上の識別名に該当するコントロールを探すControl[]txtboxctrls=this.Controls.Find(this.txtbxNm[i],false);for(intj=0;j<txtboxctrls.Length;j++){// 取得したテキストボックスの内容を文字列取得TextBoxtbox=(TextBox)txtboxctrls[j];sb.Append(tbox.Text);}// 最終要素以外の場合は「/」で区切るif(i<ElementNum-1){sb.Append(" / ");}}// メッセージを表示するMessageBox.Show("入力したものは…"+sb.ToString()+" です。");}}}まずは本来データベースや設定ファイルで取得すべき、識別名をテキストボックスに設定する箇所
this.txtbxNm=newstring[ElementNum];this.txtbxNm[0]="txbUraga";this.txtbxNm[1]="txbKamakura";this.txtbxNm[2]="txbMisaki";this.txtbxNm[3]="txbKannonzaki";this.txtbxNm[4]="txbYokosuka";this.txtbxNm[5]="txbJogashima";this.txtbxNm[6]="txbShichirigahama";this.txtbxNm[7]="txbMabori";this.manyTextBoxes[i].Name=txtbxNm[i];このことをしなければ、まずテキストボックスを参照することができません。なぜならボタンbuttonCheckEntryのクリックイベントでは、識別名をFindすることで、該当するテキストボックスを検索するからです。
Control[]txtboxctrls=this.Controls.Find(this.txtbxNm[i],false);Findメソッドの引数は、それぞれ識別名、子要素を探すかのフラグ。ここではテキストフォームだけを使うので、それ以下の子要素は意識しないのでfalseで。要素が見つかれば、上記のtxtboxctrlsの要素数は0より大きい(1以上)になります。
これも成功しました。
最後は要素数を動的に変えて対応できるかもチェックします
要素数を動的に変えてみる
// 配列の要素数(ここでは11個)privateconstintElementNum=11; …(中略)…string[]msgs=newstring[ElementNum];msgs[0]="浦賀";msgs[1]="鎌倉";msgs[2]="三崎";msgs[3]="観音崎";msgs[4]="横須賀中央";msgs[5]="城ヶ島";msgs[6]="七里ガ浜";msgs[7]="馬堀";msgs[8]="走水";msgs[9]="逗子";msgs[10]="葉山";this.txtbxNm=newstring[ElementNum];this.txtbxNm[0]="txbUraga";this.txtbxNm[1]="txbKamakura";this.txtbxNm[2]="txbMisaki";this.txtbxNm[3]="txbKannonzaki";this.txtbxNm[4]="txbYokosuka";this.txtbxNm[5]="txbJogashima";this.txtbxNm[6]="txbShichirigahama";this.txtbxNm[7]="txbMabori";this.txtbxNm[8]="txbHashirimizu";this.txtbxNm[9]="txbZushi";this.txtbxNm[10]="txbHayama";最後は要素数を8→11に増やして、そうするとボタンを11個に増やし、テキストボックスも11個識別しなければならなくなるので、上記のように修正します。
これも11個のテキストボックスを正しく識別できました!!(˶ ・ᴗ・ )੭⚐⚑
次回
今回はデータベースのマスタだの設定ファイルだのといっぺんに話を混ぜると疲れるので、動的にコントロールを追加する方法に絞って記事にしてみましたが、次はデータベースのマスタデータから動的にコントロールを追加することに挑戦してみます( ˙꒳˙ᐢ )

