プロが教える店舗&オフィスのセキュリティ対策術

いつもお世話になっております。
VB.NET で型名の比較について2点質問です。

フォームの初期化の場合に下記のようなコードで
コントロールに応じた初期化処理をしているのですが、
わざわざ文字列にしてそれを比較するのも余りスマートで
ないように見えまして、もう少しスマートな比較方法が
ないのかなと思うのですが、良い方法あるでしょうか?

Dim ctrl As System.Windows.Forms.Control

For Each ctrl In Me.Controls

Select Case ctrl.GetType().ToString
Case "System.Windows.Forms.TextBox"
ctrl.Text = ""

Case "System.Windows.Forms.ComboBox"
ctrl.Text = ""
CType(ctrl, System.Windows.Forms.ComboBox).Items.Clear()

Case "System.Windows.Forms.DateTimePicker"
CType(ctrl, System.Windows.Forms.DateTimePicker).Value = Now

Case "System.Windows.Forms.CheckBox"
CType(ctrl, System.Windows.Forms.CheckBox).Checked = False
End Select

Next


第二点は以下のようなイベントハンドラを考えるとして、sender には
System.Windows.Forms.Control の派生クラス(TextBox, CheckBoxなど)への参照が
渡されてくる予定のですが、渡されたものが本当にControlクラスの派生クラスなのか
を関数内で確認したいのです。どのようにしたら良いですか?

Private Sub Controls_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs)

A 回答 (3件)

#1です。




>senderは System.Objectなので
ふむふむ

>Addhandlerの設定によっては Control以外のクラスが来る可能性はあると思います。
そうですか?

受けで考えるのではなく、構造で考えた場合、キャストできないようなコントロールがもし存在していたら、イベントを発生ですら関連付けできないはずです。

関数の受けは確かにObjectですが、
>For Each l_objCtl In Me.Controls
で廻しているので、コントロールにキャスト可能なものしかイベントハンドラに関連付いてないと思うのですが。。。

Control 階層 (System.Windows.Forms)
http://www.microsoft.com/japan/msdn/library/defa …
このような各コントロールは、Controlへのキャストが可能です。

Control メンバ
http://www.microsoft.com/japan/msdn/library/defa …
キャストが可能であれば、コントロールが持っているイベントへの関連付けが可能だと思います。

どこかで
Call Controls_Enter(Nothing, New System.EventArgs)
とかで意図的に呼ばない限り、恐れている現象は発生しないと思います。


余談です。
Addhandlerでイベントを呼べるはずなのに、イベントが発生しないというのはあるかも知れません。。。
VB6時代によくサブクラス化を利用しておりましたが、VB側で発生させていないイベントが多々ありました。
そのVB魂を継承していたら、発生しないかもしれません。
    • good
    • 0

if TypeOf(ctrl) Is System.Windows.Forms.TextBox then


...
ElseIf TypeOf(ctrl) Is System.Windows.Forms.ComboBox Then
...
ElseIf TypeOf(ctrl) Is System.Windows.Forms.DateTimePicker Then
...
End If
    • good
    • 0
この回答へのお礼

ありがとうございます。
select case が使えないのは不便ですね。

お礼日時:2005/10/01 04:51

1.コントロール種別を得る


2.コントロール処理を判定
3.適した初期化処理を行う

これはVB6などではある手です。
.NETではあらかじめ、各種の初期化メソッドを同名で作成しておくで、判定を行う必要がなくなります。

質問2の意味がよくわかりませんでした。
>渡されたものが本当にControlクラスの派生クラス
逆に本物ではない物が来るのか知りたい^^;;


-----クラスを作成-----
Public Class cls初期化
  '各種の初期化処理
  Public Sub コントロール初期化(ByRef objCtl As ComboBox)
    objCtl.Text = ""
    objCtl.Items.Clear()
  End Sub
  Public Sub コントロール初期化(ByRef objCtl As DateTimePicker)
    objCtl.Value = Now
  End Sub
  Public Sub コントロール初期化(ByRef objCtl As CheckBox)
    objCtl.Checked = False
  End Sub


  '上記の初期化処理に存在しない場合は、ここに流れ着く
  Public Sub コントロール初期化(ByRef objCtl As Control)
    MsgBox(objCtl.Name.ToString & "(" & TypeName(objCtl) & ")は初期化対象外")
  End Sub
End Class


-----以下をフォームに追加-----
'イベント/Load/フォーム
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim l_obj初期化 As New cls初期化()
  Dim l_objCtl As Object

  For Each l_objCtl In Me.Controls
    '初期化を実行
    Call l_obj初期化.コントロール初期化(l_objCtl)

    'イベントを設定
    AddHandler CType(l_objCtl, System.Windows.Forms.Control).Enter, AddressOf Me.Controls_Enter
  Next
End Sub

'イベント/Enter/全てのコントロール
Private Sub Controls_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs)
  'フォーカスを得たコントロールを、フォームに表示
  Me.Text = "[" & sender.name.ToString & "(" & TypeName(sender) & ")] にフォーカスがあります"
End Sub
    • good
    • 0
この回答へのお礼

ありがとうございます。

>逆に本物ではない物が来るのか知りたい^^;;

senderは System.Objectなので
Addhandlerの設定によっては Control以外の
クラスが来る可能性はあると思います。

無条件で CTypeでコントロールクラスにキャスト
していると、キャスト失敗で例外を投げることも
あり得るんじゃないかと思っているのですが。

コンパイルでチェックできないのが厄介です。

お礼日時:2005/10/01 04:59

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!