C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

「コントロールの配列を作成する」について

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■87198 / inTopicNo.1)  「コントロールの配列を作成する」について
  
□投稿者/ めばる (1回)-(2018/04/22(Sun) 23:08:26)

分類:[C#] 

VS2017C#を使い
こちらのサイトでいろいろ勉強させていただいております。
タイトルの件で、サンプルを参考に8個のテキストボックスを追加しました。
textBox1〜textBox8までのNameプロパティも設定しました。また、イベントハンドラーも設定できました。
さて、この後ですが、たとえばtextBox1を参照しようとしても、「textBox1という名前は存在しません」となります。
フォームを表示する前にコードを書こうとしても、実際には存在しないのでその通りなのかもしれませんが
追加したtextBoxに対していろいろ操作するにはどのようにすればよいのでしょうか。
的外れな質問かもしれませんが、よろしくお願いします。
引用返信 編集キー/
■87199 / inTopicNo.2)  Re[1]: 「コントロールの配列を作成する」について
□投稿者/ 魔界の仮面弁士 (1654回)-(2018/04/23(Mon) 00:45:13)
No87198 (めばる さん) に返信
> こちらのサイトでいろいろ勉強させていただいております。
> タイトルの件で、サンプルを参考に8個のテキストボックスを追加しました。
こちらのページでしょうか。
http://jeanne.wankuma.com/tips/csharp/control/arraycontrol.html

(1) 冒頭の『プライベートなフィールドとして配列を定義する』の変数
(ここでは myTextBoxes )を宣言していますか?

(2) その変数を初期化・設定するためのコードを、どこに書いていますか?
→ Form1_Load で設定している場合は、そのイベントハンドラが
  Form1 の Load イベントに割り当てられており、ただしく呼び出されているかを確認してください。
→ Form1 のコンストラクタ内で設定している場合には、それらの初期化処理が
  InitializeComponent を呼び出した「後」で行われているかを確認してください。

(3) その初期化処理の中で、『10 個の配列を確保する』を真似て、
 「8個」分の配列領域をその変数に 1 度だけ割り当てていますか?
→ this.myTextBoxes = new TextBox[8];


> textBox1〜textBox8までのNameプロパティも設定しました。

その "textBox1" という名前の変数は、どこで宣言していますか?


【a】先のサンプルを真似て、「this.myTextBoxes[i] = new TextBox();」などとセットしている場合:

→ textBox1 という名前の変数は宣言していないので、名前を変数としてアクセスすることはできません。
 この場合は名前でアクセスするのではなく、myTextBoxes[0].Text = "test"; のように、
 フィールド変数 myTextBoxes を通じて インデックスでアクセスすることができます。

→ ちなみに Name プロパティは、管理上は検索用の名前という程度のものなので、
 このような使い方の場合には、設定してもあまり意味はありません。Name プロパティというのは、
 デザイン時には「変数名」の名前と同義ですが、自身で動的に生成しているときにはあまり意味が無く、
  TextBox textBox1 = (TextBox)this.Controls["textBox1"];
 の様に、.Controls 内から該当する名前のコントロールを探す際に使う程度のものです。

→ もしも Form 上に直接載せていた場合は this.Controls["textBox1"] で探せますが、
 Panel 等に乗せていた場合には、panel1.Controls["textBox1"] などのように探すことになります。
 もしくは、
  TextBox textBox1 = this.Controls.Find("textBox1", true).OfType<TextBox>().FirstOrDefault();
 などのように、Find メソッドを使って子孫階層のコレクションすべてを探すこともできます。



【b】上記 (2) の処理を記した Form1 コンストラクタ あるいは Form1_Load イベント内で
 「TextBox textBox1 = new TextBox();」などと変数宣言し、それにインスタンスを渡している場合

→ イベント内に記述した変数は「ローカル変数」となります。この場合、その変数を使えるのは
 それを宣言したブロック内のみに制限されます。別のイベント等でも使いたい場合には、
 イベントの外側で「private TextBox textBox1;」などと宣言して「フィールド変数」に変更してください。



【c】textBox1〜8 はコードで生成しているわけではなく、普通にフォームデザイナ上で生成している場合

→ この場合は通常、this.textBox1.Text = "test"; などのようにしてアクセスできるはずです。
 もしもデザイナ上で生成したコントロールなのに、名前でアクセスできない場合には、デザイン時に
 そのコントロールの「GenerateMember」というデザイン時プロパティを、True から False に
 変更していないかを確認しておいてください。

→ なお、デザイナで生成した変数を配列として扱う場合は、それぞれの textBox を、
  myTextBoxes[0] = textBox1;
  myTextBoxes[1] = textBox2;
    :
  myTextBoxes[7] = textBox8;
 などとして、準備した配列の中にひとつひとつ代入する必要があります。
 代入した後は、myTextBoxes[0].Text = "test"; などのようにしてアクセスできます。



一応補足しておくと……デザイン時に textBox1〜textBox8 を貼り付けた場合、
Form1.designer.cs ファイル内を開いてみると、それらのコントロールが
 private System.Windows.Forms.TextBox textBox1;
のように、TextBox 型フィールド変数として定義されていることを確認できるはずです。
なのでデザイン時に貼っておいたコントロールは、「this.textBox1.Text = "test";」などと書けるわけです。

ただし、デザイン時に貼っておいたコントロールでも、GenerateMember を False にした場合は
それらの変数はフィールド変数として宣言されず、InitializeComponent メソッド内の
ローカル変数として宣言される仕様です。そのため、InitializeComponent メソッド以外では
そのコントロールを直接操作することができなくなります。

とはいえ、デザイン時に GenerateMember を False にしていたとしても、Name プロパティは
セットされるようになっているので、先述の通り、.Controls.Find のメソッドなどを通じて
呼び出すことは一応可能です。
引用返信 編集キー/
■87201 / inTopicNo.3)  Re[2]: 「コントロールの配列を作成する」について
□投稿者/ めばる (3回)-(2018/04/23(Mon) 21:47:09)
魔界の仮面弁士 様

ご丁寧な説明ありがとうございました。
基本的なことを確認できました。
お蔭様で当初の目的を達成することができました。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ