マスターファイル利用時にもコントロールの ID でコントロールを取得する方法
ASP.NET にはサイト全体に一貫したデザインを適用するのに適したマスターファイルという仕組みがあります。
ここにロゴを、ここはサイドバー、ここはフッター、ここはメインコンテンツ・・・という割り振りだけをマスターファイルで行い、 それぞれのページでは、それぞれのページに特徴的な部分だけを実装する仕組みです。
マスターファイルはとても便利なのですが、構造的にやや複雑になります。そのため 「コントロール ID でコントロールを探す FindControl」 で説明した FindControl メソッドが動かない、などの問題が発生したりします。
ここではマスターファイルを利用しているときに、どのようにコントロール ID からコントロールを探せばよいか示します。
マスターファイル利用時にはコンテントプレースホルダーで FindControl
マスターファイル利用時には、Page オブジェクトに直接コントロールを追加するわけではないので、FindControl メソッドを 「コントロール ID でコントロールを探す FindControl」で説明した方法で呼び出してもコントロールの参照は取得できません。
マスターファイルに、コンテントプレースホルダーオブジェクトがぶら下がり、その下に個々の aspx で定義したテキストボックスがぶら下がる形になります。 従って、現在のコンテキストのハンドラがマスターファイルであるときは、次のようにします。
protected Control MyFindControl(string controlID, string placeHolderID = "cph1") {
var page = HttpContext.Current.Handler as Page;
if( page == null || string.IsNullOrEmpty( controlID ) ) {
return null;
}
Control c = page.FindControl( controlID );
if( c != null ) {
return c;
}
if( page.Master == null || string.IsNullOrEmpty( placeHolderID ) ) {
return null;
}
var ph = page.Master.FindControl( placeHolderID ) as ContentPlaceHolder;
if( ph == null ) {
return null;
}
return ph.FindControl( controlID );
}
ここでは現在のページで FindControl を実行して取得できない場合、 ページにマスターファイルが関連付いているかどうか調べています。
もし page.Master にオブジェクトがセットされていれば、そこで指定した ID を持つ ContentPlaceHolder オブジェクトを探し、それの FindControl メソッドを呼びます。
このようにすれば、マスターファイル上でも問題なくコントロールが拾えます。