- PR -

ユーザーコントロールのGetTypeについて

投稿者投稿内容
ゆっきー
ベテラン
会議室デビュー日: 2006/04/21
投稿数: 65
投稿日時: 2006-06-06 11:03
VB.NETでWEBアプリケーションの作成をしています。
ページのコントロールを引数として、特定のコントロールの表示を切り替える関数を作成していますが、ページ内のユーザーコントロールのタイプとGetTypeで取得したユーザーコントロールのタイプ名が異なっていてうまくいきません。タイプ名を直接記述せずにうまくタイプを合わせるやり方があれば、アドバイスよろしくお願いします。

コードは以下の通りです。
Public Sub ReadOnlyControl(ByVal Controls As ControlCollection)

Dim Ctrl As Control
Dim strType As String

Try
For Each Ctrl In Controls
strType = Ctrl.GetType.ToString

Select Case strType
Case GetType(UcDisplayListItem).ToString
'ユーザーコントロール
Dim uc As UcDisplayListItem = CType(Ctrl, UcDisplayListItem)
uc.Visible = True

End Select

If Ctrl.HasControls() Then
Call ReadOnlyControl(Ctrl.Controls)
End If
Next

Catch ex As Exception

Throw (ex)

End Try

End Sub

ウォッチで取得した値は以下の通りです。
GetType(UcDisplayListItem).ToString→"プロジェクト名.UcDisplayListItem"
strType→"ASP.UcDisplayListItem_ascx"
がんふぃーるど
ベテラン
会議室デビュー日: 2006/06/05
投稿数: 58
お住まい・勤務地: さいたま
投稿日時: 2006-06-06 12:04
Ctrl.GetType.ToStringのところをCtrl.GetType.BaseType.ToStringにしてみて下さい。

これはASP.NETが分離コードファイルとASPXをマージしてコンパイルすることに起因します。
ASP.xxx_aspxやASP.xxx_ascxなどはASP.NETが、実行時にコンパイルした際に出来上がるクラス名です。
これらのクラスは元々のユーザコントロールやページの分離コードを継承しているので、BaseTypeを見ると元のクラス名が取得できます。
ゆっきー
ベテラン
会議室デビュー日: 2006/04/21
投稿数: 65
投稿日時: 2006-06-06 15:41
返答ありがとうございます!
がんふぃーるどさんの言われたとおり、以下で取得することができました。

strType = Ctrl.GetType.BaseType.ToString

ユーザーコントロールは継承されたコントロール扱いになっていたとは知りませんでした。
大変助かりました!
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2006-06-06 16:30
TypeOf...Is を使うわけにはいかないんですか?
わざわざ型名の文字列という限定された情報だけを取り出して比較する理由がないのであれば、こっちの方がいいですね。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-06-06 22:33
本題とは関係ないですが。。。
推奨される書き方
コード:
Public Sub ReadOnlyControl(ByVal Controls As ControlCollection)
    For Each Ctrl As Control In Controls
        If TypeOf Ctrl Is UcDisplayListItem Then
            'ユーザーコントロール
            Dim uc As UcDisplayListItem = CType(Ctrl, UcDisplayListItem)
            uc.Visible = True
        Else If TypeOf Ctrl Is 他のコントロール Then
            ....
        End If
    Next
End Sub


 TypeOf キーワードを使えば、派生元をたどって検証してくれます。
 そうすると、Select 文が使えないので、If 文で処理することになります。
 Throw ex とすると、ここから例外が投げられます。例外が発生した本当の箇所がわからなくなるので、Throw だけにします。
 しかし、特に何もしないなら、Catch してはいけません
 変数の有効範囲(スコープ)は、極力小さくします。Ctrl は、For Each 文の中でだけ参照できればいいので、For Each 文で宣言します(VB 7.1 から可能になった)。


 なお、私は IStateChangable インターフェイスを定義して、各ユーザ コントロールに実装させました。これにより、ここの処理は次のようになります。
 ユーザ コントロールごとに判定をする必要がなくなります。
 ユーザ コントロールを包含するコントロールは、ReadOnly にするために何が必要かを知る必要はなく、単に「ReadOnly は True」と知らしめるだけです。
 ユーザ コントロールの実装が変わり、ReadOnly にする方法が変わったとしても、ユーザ コントロールを修正するだけです。
コード:
    For Each Ctrl As Control In Controls
        If TypeOf Ctrl Is IStateChangable Then
            Dim istate As IStateChangable = CType(Ctrl, IStateChangable)
            istate.ReadOnly = True
        Else If TypeOf Ctrl Is 他のコントロール Then
            ....
        End If
    Next


ゆっきー
ベテラン
会議室デビュー日: 2006/04/21
投稿数: 65
投稿日時: 2006-06-07 09:17
一郎さん、Jittaさんアドバイスありがとうございます。
IF文を使うと分岐がたくさんできてしまうので、「Select Case」を使うために単純にGetTypeにしていました。
まだまだ勉強がたりませんね。さっそくIStateChangableについても調べて実装してみます。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-06-07 09:33
引用:

ゆっきーさんの書き込み (2006-06-07 09:17) より:

一郎さん、Jittaさんアドバイスありがとうございます。
IF文を使うと分岐がたくさんできてしまうので、「Select Case」を使うために単純にGetTypeにしていました。


これは何度も言ってきていることですが、「型は '型' であって '文字列' ではない」です。
System::Type.Name による比較は、あくまで文字列の比較検証であり、型の比較検証ではないのです。

# そもそも、型の検証自体、ないに越したことはないんですけどね。

それと、Select Case でも '一応は' できます。
見た目は簡素化できているように見えますが...w

コード:

    Select Case True
        Case TypeOf sender Is TextBox : 'TODO : ここにコードを挿入
        Case TypeOf sender Is Label   : 'TODO : ここにコードを挿入
        Case TypeOf sender Is Button  : 'TODO : ここにコードを挿入
    End Select


さて、評価の回数はどうでしょう...?
詳しくは MSIL を解析してみてください。

引用:

まだまだ勉強がたりませんね。さっそくIStateChangableについても調べて実装してみます。


念のためですが、これは、Jitta さんが定義したインターフェイスの型です。
このスレッドにある情報以外で、調べることはありません。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2006-06-07 09:43
Jittaさん、お早うございます。

ここ↓だけ反応。
引用:

 そうすると、Select 文が使えないので、If 文で処理することになります。



こんな手もあります。
コード:

Select Case True
Case TypeOf Ctrl Is IStateChangable
....
Case TypeOf Ctrl Is 他のコントロール
....
Case Else
....
End Select



#被った…。しかも著しく出遅れ…。

[ メッセージ編集済み 編集者: きくちゃん 編集日時 2006-06-07 09:45 ]

スキルアップ/キャリアアップ(JOB@IT)