DOBON.NET DOBON.NETプログラミング掲示板過去ログ

コントロール配列

分類:[.NET]

はじめまして、どらごらです。
「VB6以前のコントロール配列は無くなった」ってのはMSDNやGoogleで調べれば
すぐ出てきます。たいていのサンプルは(MSDNやどぼんさんのTipsでもですが...)
   testButtons(0) = Button1
   testButtons(1) = Button2
   testButtons(2) = Button3
   testButtons(3) = Button4
   testButtons(4) = Button5
※どぼんさんのtipsページから引用
となっています。
が、DelphiのFindComponentの様なコントロール(コンポーネント)名から
そのインスタンスを取り出す方法ってないのでしょうか?
※FindControlはWebフォームみたいですし...

たとえば上の例ですと
Dim tmpButton as Button
tmpButton = FindConponent("Button3")
tmpButton.Text = "OK"
みたいにしたいのです。
#タイトルは質問内容にあったものにしましょう。

■No584に返信(どらごらさんの記事)
> が、DelphiのFindComponentの様なコントロール(コンポーネント)名から
> そのインスタンスを取り出す方法ってないのでしょうか?
> ※FindControlはWebフォームみたいですし...

ありません。
VB6のコントロール配列をVB.NETでコントロールの配列として実現するのと同じ要領で、
Hashtableにすべてのコントロールをコントロール名をキーにして
登録しておけばそういうこともできます。

効率無視でよければ、Controlsコレクションの各コントロールを列挙して、
そのNameプロパティと調べたい名前とを地道に比較するロジックでそういう
メソッドを自作するという手もあります。

あるいはコントロール名ではなくコントロールのインスタンスを参照しているフィールドを
リフレクションで探すという手もありそうです。

#私はあまり必要性を感じませんがどういう場面で役立つんでしょう?
■No584に返信(どらごらさんの記事)
> はじめまして、どらごらです。
> 「VB6以前のコントロール配列は無くなった」ってのはMSDNやGoogleで調べれば
> すぐ出てきます。たいていのサンプルは(MSDNやどぼんさんのTipsでもですが...)
> testButtons(0) = Button1
> testButtons(1) = Button2
> testButtons(2) = Button3
> testButtons(3) = Button4
> testButtons(4) = Button5
> ※どぼんさんのtipsページから引用
> となっています。
> が、DelphiのFindComponentの様なコントロール(コンポーネント)名から
> そのインスタンスを取り出す方法ってないのでしょうか?
> ※FindControlはWebフォームみたいですし...
>
> たとえば上の例ですと
> Dim tmpButton as Button
> tmpButton = FindConponent("Button3")
> tmpButton.Text = "OK"
> みたいにしたいのです。
>

無いので、私は作りました。
本当に使ってくれるのであれば、ソースを提供します。
■No585に返信(よねKENさんの記事)
> #タイトルは質問内容にあったものにしましょう。
 すみません。わかりにくかったですか。。。

> ■No584に返信(どらごらさんの記事)
>>が、DelphiのFindComponentの様なコントロール(コンポーネント)名から
>>そのインスタンスを取り出す方法ってないのでしょうか?
>>※FindControlはWebフォームみたいですし...
> ありません。
 やっぱないのですか。

> #私はあまり必要性を感じませんがどういう場面で役立つんでしょう?

たとえば9個のチェックボックスが下記の通り並んであるとします。(X,Y)

  chkbox11 chkbox21 chkbox31
  chkbox12 chkbox22 chkbox32
  chkbox13 chkbox23 chkbox33

すべてのチェックボックスに値が入っているかを調べる場合
Dim X, Y as Integer
Dim tmpChkbox as Checkbox

For X = 1 To 3
  For Y = 1 To 3
    tmpChkbox = FindControl("chkbox" & CStr(X) & CStr(Y))
    ...
  Next Y
Next X

の様な書き方ができると、楽だからです。
実際WebフォームではFindControlがあるわけですし、
Windowsフォームではないのかな?/私の見落としかな?
と思って、質問いたしました。

  P.S.
私は個人レベルでVB→Delphiに移った人間です。
DelphiではVBのコントロール配列の代わりに、FindComponentを利用するというのが定石です。
しかし仕事レベルでVB.NETを使用していますが、VBにコントロール配列がなくなったのなら
その代わりとして、FindComponentかFindControl見たいなものがあると思ったのです。
2003/09/05(Fri) 23:14:01 編集(投稿者)

■No588に返信(どらごらさんの記事)
> ■No585に返信(よねKENさんの記事)
>>#タイトルは質問内容にあったものにしましょう。
>  すみません。わかりにくかったですか。。。

わかりにくかったというより、
質問の話の導入としてコントロール配列は話題にでますが、質問の本題はあくまで
「コントロール(コンポーネント)名からそのインスタンスを取り出す方法」
なので、コントロール配列はあまり関係ないかなと思いました。

> たとえば9個のチェックボックスが下記の通り並んであるとします。(X,Y)
>
> chkbox11 chkbox21 chkbox31
> chkbox12 chkbox22 chkbox32
> chkbox13 chkbox23 chkbox33
>
> すべてのチェックボックスに値が入っているかを調べる場合
> Dim X, Y as Integer
> Dim tmpChkbox as Checkbox
>
> For X = 1 To 3
> For Y = 1 To 3
> tmpChkbox = FindControl("chkbox" & CStr(X) & CStr(Y))
> ...
> Next Y
> Next X
>
> の様な書き方ができると、楽だからです。

旧VBにおけるControlsコレクションの使い方が該当しますね。
旧VBのコントロール配列を使えばこの使い方は必須ではないです。

.NETのControlsコレクションは、残念ながら数値のインデックスでの指定だけになってます。
Nameプロパティが必須ではなくなっているからかもしれません。
(""でもOKなので名前があるとは限らない)

> 実際WebフォームではFindControlがあるわけですし、
> Windowsフォームではないのかな?/私の見落としかな?
> と思って、質問いたしました。

Webのコントロールは最終的にINPUTタグなのでNAME属性が
省略されることがないから可能なのかもしれません。

> P.S.
> 私は個人レベルでVB→Delphiに移った人間です。
> DelphiではVBのコントロール配列の代わりに、FindComponentを利用するというのが定石です。
> しかし仕事レベルでVB.NETを使用していますが、VBにコントロール配列がなくなったのなら
> その代わりとして、FindComponentかFindControl見たいなものがあると思ったのです。

納得しました(^^)
  • 題名: Re[4]: コントロール配列
  • 著者: こど。
  • 日時: 2003/09/06 20:51:41
  • ID: 593
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
■No588に返信(どらごらさんの記事)

'いくらでも他の方法はあると思いますが、
'質問された方が例記しているコードを大体そのままで実現するには、「Collection」を使用します。
'このクラスは、名称とオブジェクトをペアで管理でき、しかも名称をキーにオブジェクトを返すメソッドを持っています。
'連想配列として使用できます。

'そして、デザイナで配置したコントロールは全て、オブジェクト名とプロパティ「Name」の中身が一致します。
'コントロールの動的生成がないのであれば、Formの持つコントロールコレクション(=番号でしかアクセスできない)を
'Collectionに転送してやれば全てのコントロールのコレクションを用意できます。
'コントロールの動的生成がある場合、周辺処理がすごいことになります。(私はやっているのですが。色々面倒です・・・。)

'───────────────────────────
'(Private ctrlSet As New Collection()の前提で・・・)
'【 InitializeComponent() 呼び出しの後に初期化を追加します。】の後ろに・・・
Dim tmpObj As System.Windows.Forms.Control
'ループで全部コレクションに追加
For Each tmpObj In Me.Controls
    ctrlSet.Add(tmpObj, tmpObj.Name)
Next
'を記述します。

'メモリもったいないかな・・・。
'あらかじめ、こういった使い方をする対象のコントロールが限定されているのであれば、
'それだけを入れた方がいいですよ。

'───────────────────────────
'で、目的のコードは以下のようになります。
Dim X, Y As Integer
Dim tmpChkbox As System.Windows.Forms.CheckBox

For X = 1 To 3
    For Y = 1 To 3
    '名前で取り出して、チェックボックスに変換して受け取る。
        tmpChkbox = CType(ctrlSet("chkbox" & CStr(X) & CStr(Y)), System.Windows.Forms.CheckBox)
        '...
    Next Y
Next X
'こんなん、どうでしょうか。
  • 題名: Re[2]: コントロール配列
  • 著者: どらごら
  • 日時: 2003/09/08 10:34:06
  • ID: 599
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
こんにちは、どらごらです。

皆さんレスポンスありがとうございました。

Collectionを利用したやり方で実装したいと思います。

ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板