- PR -

マスターページ内のユーザーコントロールのViewを取得したい

1
投稿者投稿内容
未記入
ベテラン
会議室デビュー日: 2008/01/15
投稿数: 65
投稿日時: 2008-02-29 15:08
おせわになっております。

VS2005のWebサイトプロジェクトで、マスターページに設置したユーザーコントロール(ログインボックスを設置したユーザーコントロール)内のViewをApp_Code内のクラスから取得したいのですが、適当な方法をアドバイスして頂けないでしょうか。

ページはマスターページを使っていて、マスターページにログインボックスを設けています。
各ページでは未ログインであればログインボタンをデフォルトに、そうでなければ各ページごとにデフォルトボタンを設定したくて、各ページのPage_Loadでログインボタンを取得し、デフォルトボタンとして設定しています。

この処理の中でログインボタンを取得する処理を共通処理として纏め、App_Code内のクラスとして作成していますがユーザーコントロールが取得できない時に例外が発生しており、この対策が必要です。

例外は共通処理(App_Code内のクラス)の最後にある、次のコードで発生しています。

Return master.FindControl("LoginCtrl1").FindControl("LoginView1")

教えて頂きたいのは、この処理でLoginCtrl1が無くても例外が起きないようにする方法です。
本当は、まず最初にLoginCtrl1を取得し、結果を判定してLoginView1を取得する、という風にやりたいのですが、LoginCtrlがユーザーコントロールのため、

Dim LoginCtrl1 As LoginCtrl = master.FindControl("LoginCtrl1")

というコードが書けません。

やむを得ず
Dim LoginView1 As LoginView
Try
LoginView1 = master.FindControl("LoginCtrl1").FindControl("LoginView1")
Catch ex As Exception
LoginView1 = Nothing
End Try
Return LoginView1

と書き換えようと思うのですが、これ以外の方法は無いでしょうか?

※私はWebサイトプロジェクトで作成しているので
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=41762&forum=7
がまさに当たっているような感じですが、相当作りこみをしているので今更Webアプリケーションに作り変えることはできません。

くまっち
大ベテラン
会議室デビュー日: 2008/01/18
投稿数: 169
お住まい・勤務地: 茨城県のどこか。
投稿日時: 2008-02-29 16:14
引用:

Dim LoginCtrl1 As LoginCtrl = master.FindControl("LoginCtrl1")

というコードが書けません。


Dim LoginCtrl1 As Control = master.FindControl("LoginCtrl1")
もしくは
Dim LoginCtrl1 As UserControl = master.FindControl("LoginCtrl1")
というコードは書けますよね。
FindControl()メソッドの戻り値を考えてください。

[以下、提案]
思うのですけど、ページ側が探すのではなく、、、
・ユーザーコントロールがボタンを提供するプロパティを持ち
・マスターページもユーザーコントロールの提供するボタンを提供するプロパティを持つ
・ページは、マスターページの提供しているボタンを参照する

こうすれば、Controlsの中からFindControlで探さなくても済むと思うのですが。
未記入
ベテラン
会議室デビュー日: 2008/01/15
投稿数: 65
投稿日時: 2008-02-29 16:53
引用:

くまっちさんの書き込み (2008-02-29 16:14) より:
引用:

Dim LoginCtrl1 As LoginCtrl = master.FindControl("LoginCtrl1")

というコードが書けません。


Dim LoginCtrl1 As Control = master.FindControl("LoginCtrl1")
もしくは
Dim LoginCtrl1 As UserControl = master.FindControl("LoginCtrl1")
というコードは書けますよね。
FindControl()メソッドの戻り値を考えてください。




Dim LoginCtrl1 As Control = master.FindControl("LoginCtrl1")
と書くことでやりたかったことが実現できました。
ユーザーコントロールのクラスは LoginCtrlだったので勘違いしてしまいました。


引用:

[以下、提案]
思うのですけど、ページ側が探すのではなく、、、
・ユーザーコントロールがボタンを提供するプロパティを持ち
・マスターページもユーザーコントロールの提供するボタンを提供するプロパティを持つ
・ページは、マスターページの提供しているボタンを参照する

こうすれば、Controlsの中からFindControlで探さなくても済むと思うのですが。



確かにそうですね。

各めページで直接使っているユーザーコントロールは上記のようにプロパティを活用しているのですが、マスターページについては最初に覚えた方法がFindControlだったためにプロパティを使っていませんでした。
今度からはマスターページでもプロパティを使うようにします。

ありがとうございました。
未記入
ベテラン
会議室デビュー日: 2008/01/15
投稿数: 65
投稿日時: 2008-02-29 17:04
すみません。
指摘されたプロパティの方法では内のですが次のコードで解決したつもりになっていました。

Dim LoginCtrl1 As Control = master.FindControl("LoginCtrl1")
If LoginCtrl1 Is Nothing Then
Return Nothing
End If
Dim LoginView1 As LoginView
LoginView1 = LoginCtrl1.FindControl("LoginView1")
Return LoginView1

でも、もしかして

LoginView1 = LoginCtrl1.FindControl("LoginView1")

の部分もFindControlで無くても変換できるのでしょうか?
LoginCtrl1をLoginCtrlクラスにキャストしようと試みましたがLoginCtrlは定義されていないというエラーになってしまいます。
多分また私が知らないだけなんだと思いますが、やり方があれば教えて頂けないでしょうか?
くまっち
大ベテラン
会議室デビュー日: 2008/01/18
投稿数: 169
お住まい・勤務地: 茨城県のどこか。
投稿日時: 2008-03-01 00:06
>LoginCtrlは定義されていないというエラー
この部分に関しても同様です。

WebサイトではApp_Code内のクラスから.aspxや.ascxで定義されているクラスを
参照することが出来ません。
基本的にCLRにて定義されている型までしか扱えません。


私が「FindControl()メソッドの戻り値を考えてください」と申し上げたのは
FindControlメソッドの戻り値はControl型であり
FindControlsメソッドを使うだけなら、わざわざ派生したクラスにキャスト(*1)しなくても
Control型のまま扱えば良いのではないですか。
と、言うことです。
*1:これはアンボクシング(ダウンキャスト)になるので、使わないで済むなら使わないほうがいい。

App_Code内ではControl型として扱い
呼び元のPageにてLoginView型にキャストすれば良いのではないでしょうか。

ですので、このようにコストの高い作り(キャストやFind使用)より
キャストなど不要なプロパティによる提供を提案した次第です。
未記入
ベテラン
会議室デビュー日: 2008/01/15
投稿数: 65
投稿日時: 2008-03-04 10:21
ご丁寧な説明ありがとうございます。
意味を理解するのに時間がかかってしまいました。

なるべく共通処理内で全てを完結させたかったためApp_Code内のクラスから参照するようなコードになってしまいました。

「WebサイトではApp_Code内のクラスから.aspxや.ascxで定義されているクラスを
参照することが出来ません。」
というような制限があると判っていれば最初からWebアプリケーションとして作成したのですが、何も知らずに「Webサイトプロジェクトでプロジェクトを作成する」という説明を鵜呑みにしてました。

手元にある書籍は何故かWebアプリケーションでの解説が多く「何でだろう?」ぐらいに考えていましたがWebサイトは制限が多いからなんでしょうかね?
次回からはWebアプリケーションで開発したいと思います。
1

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