マスターファイル利用時にもコントロールの 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 メソッドを呼びます。

このようにすれば、マスターファイル上でも問題なくコントロールが拾えます。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 ASP.NET 入門