• ベストアンサー

参照型の比較方法で質問

いつもお世話になっております。 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)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.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/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemwindowsformscontrolclasshierarchy.asp このような各コントロールは、Controlへのキャストが可能です。 Control メンバ http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemwindowsformscontrolmemberstopic.asp キャストが可能であれば、コントロールが持っているイベントへの関連付けが可能だと思います。 どこかで Call Controls_Enter(Nothing, New System.EventArgs) とかで意図的に呼ばない限り、恐れている現象は発生しないと思います。 余談です。 Addhandlerでイベントを呼べるはずなのに、イベントが発生しないというのはあるかも知れません。。。 VB6時代によくサブクラス化を利用しておりましたが、VB側で発生させていないイベントが多々ありました。 そのVB魂を継承していたら、発生しないかもしれません。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • todo36
  • ベストアンサー率58% (728/1234)
回答No.2

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

kamuatatsu
質問者

お礼

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

すると、全ての回答が全文表示されます。
回答No.1

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

kamuatatsu
質問者

お礼

ありがとうございます。 >逆に本物ではない物が来るのか知りたい^^;; senderは System.Objectなので Addhandlerの設定によっては Control以外の クラスが来る可能性はあると思います。 無条件で CTypeでコントロールクラスにキャスト していると、キャスト失敗で例外を投げることも あり得るんじゃないかと思っているのですが。 コンパイルでチェックできないのが厄介です。

すると、全ての回答が全文表示されます。

関連するQ&A