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

コントロールを名前で指定する方法

環境/言語:[VB2005]
分類:[.NET]

現在VB2003からVB2005への移行について調べています

コントロールを名前で指定している処理があって
VB2003では関数を作っているのですが、VB2005では標準の機能で可能
らしいのですがどう書けばいいのでしょうか?
2006/07/13(Thu) 08:43:11 編集(投稿者)
2006/07/13(Thu) 08:43:08 編集(投稿者)

Me.Controls.Find("textbox1", True)(0)
でコントロールの参照を返せるようになりました

今まで使っていた関数と比べると、1万回の参照で、
VB2005 Me.Controls.Find("textbox1", True)(0) 87.5
VB2005 FindControl2(Me, "TextBox1") 103.125
という結果になりました


-------------------------------------------------------------------------
Private Function FindControl2(ByVal parentCtl As Control, ByVal ctlName As String) As Control

Dim myPropertyInfo As System.Reflection.PropertyInfo
Dim myObject As Object

myPropertyInfo = parentCtl.GetType().GetProperty(ctlName _
, Reflection.BindingFlags.Instance _
Or Reflection.BindingFlags.NonPublic)

If Not myPropertyInfo Is Nothing Then

myObject = myPropertyInfo.GetValue(parentCtl, Nothing)
Return CType(myObject, Control)
End If
Return Nothing
End Function
2006/07/13(Thu) 04:57:32 編集(投稿者)

■No16607に返信(medakaさんの記事)

medakaさんの示されたFindControl2メソッドは、私のサイトの

DOBON.NET .NET Tips - フォームに配置されているコントロールを名前で探す
http://dobon.net/vb/dotnet/control/findcontrolbyname.html

かメールマガジン「.NETプログラミング研究 第30号」からきているのかもしれませんが、MSDNによるとControls.FindはNameプロパティで探すということなので、このようなリフレクションで探す方法とは全く異なります。それよりも、「.NETプログラミング研究 第30号」で紹介しているNameプロパティで探す方法と比較すべきではないでしょうか。
解決済み!
そうですね。メールマガジン30号は拝見しました。
For Eachでループしていますよね。
それがVB2005ではループせずにダイレクトに?Namaプロパティを指定して
参照できるという記事をどこかで読んだ気がしてそれを探してました

Me.Controls("textbox1").text="1"

みたいにしたかったのですがそれは無理みたいですね。
> Me.Controls("textbox1").text="1"
> みたいにしたかったのですがそれは無理みたいですね。

Me.Controls("Label1").Text = "aaa"で実際に動きますよ?
…試されましたか?
■No16634に返信(こど。さんの記事)
> > Me.Controls("textbox1").text="1"
>>みたいにしたかったのですがそれは無理みたいですね。
>
> Me.Controls("Label1").Text = "aaa"で実際に動きますよ?
> …試されましたか?

できました!ありがとうございます
先日試したときはNothingが返ってきたので諦めたのですが
何か間違ってたみたいです
ちなみに上に書いたのと同条件で速度テストしたところ82.5で
これが1番速いみたいです。
解決済み!
>>Me.Controls("Label1").Text = "aaa"で実際に動きますよ?
>
> できました!ありがとうございます
> 先日試したときはNothingが返ってきたので諦めたのですが
> 何か間違ってたみたいです

念のため。

Nameプロパティはコントロールと1対1ではありません。
なので重複している可能性(複数のコントロールに同じ文字列)がありますので注意が必要です。
デザインでCtrlを押しながらコピーしてみてください。
NameやTabIndexがコピー元と同じであることが確認できると思います。
解決済み!
> Nameプロパティはコントロールと1対1ではありません。
> なので重複している可能性(複数のコントロールに同じ文字列)がありますので注意が必要です。
んでもって、
Nameは仕様上は任意でデフォルトは空、単にデザイナでだけ空が禁止(無効です、のエラーになる。)されているだけなので、
コード上でNewして追加したようなコントロールだと、あえてセットしない限り空ですしね。

ただ、
> デザインでCtrlを押しながらコピーしてみてください。
> NameやTabIndexがコピー元と同じであることが確認できると思います。
は、ちょっと違います。
Ctrl+ドラッグアンドドロップをするとTabIndexの方は同じになりますが
Nameは同じにはなりません。
(ちなみにコピー後にペースト、だと、TabIndexも変わります。)

例えばラベルだと、必ずLabel1、Label2、って連番になります。
たとえNameが「a」ってものをコピーしても、次の「LabelN」になります。
(このデザイナの名前付けの挙動、開発環境の設定でいろいろ変えられたらいいのに…。)
解決済み!
> Ctrl+ドラッグアンドドロップをするとTabIndexの方は同じになりますが
> Nameは同じにはなりません。
> (ちなみにコピー後にペースト、だと、TabIndexも変わります。)

おぉ!勢いで書いてしまった。
フォローありがとうございます。

基本的に依存してはいけないプロパティですね。
使わないに越したことはありません。
解決済み!
■No16669に返信(まどかさんの記事)
> おぉ!勢いで書いてしまった。

Name プロパティは、実行時でないと "一意でない" 変更はできないですね。
逆に言えば、実行時には、"一意でない" 変更ができてしまえるプロパティです。

> 基本的に依存してはいけないプロパティですね。
> 使わないに越したことはありません。

そういえば、少し前に TabIndex に依存したコードについての質問があったような気がします。
(全力で止めましたが...)

Name に関してもそうです。
コンパイル解決できていないのですから、使うべきではないと思います。
(これは、こういうことがある度に発言していているので、ミニタコです...)

私的には、無節操に使われる 「遅延バインド」 と同じレベルです。
解決済み!

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