SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ITemplateでコントロールのプレゼンテーションを分離する

ITemplateでコントロールのプレゼンテーションを分離する(前編)

見た目の変更に柔軟に対応できるカスタムコントロールの作成


  • このエントリーをはてなブックマークに追加

ダウンロード 変更前 (2.4 KB)
ダウンロード 変更後 (2.7 KB)

ASP.NETでカスタムの複合コントロールを作る際、コードの中にプレゼンテーションに依存する部分を入れてしまうと、見た目を変更したい時に毎回コードの変更が必要になってしまい、保守が困難です。そこで本稿では、カスタムコントロールのプレゼンテーションを、ITemplateを用いて分離する方法を解説します。

  • このエントリーをはてなブックマークに追加
完成図
完成図

はじめに

 ASP.NETでカスタムの複合コントロールを作る場合、通常はCreateChildControlで子供のコントロールを自身にぶらさげていきます。

 しかし、C#のコードの中にプレゼンテーションに依存する部分を入れてしまうと、見た目を変更したい時に毎回コードの変更が必要になってしまい、保守が困難です。

 この問題を解決するために、ASP.NETにはカスタムコントロールのプレゼンテーションを分離する、ITemplateという仕組みがあります。

 本稿では、チェックボックスとテキストボックスが連携するカスタムコントロールをITemplate化することで、この仕組みを見ていきます。

対象読者

 ASP.NETでカスタムコントロールの作成を十分に理解している方。

必要な環境

 Microsoft Visual Web Developer 2005で確認しています。ASP.NET 1.0以降の環境なら、配置の変更だけで対応できるはずです。

変更前のソリューション構成

変更前
変更前

 このように、「App_Code」下にCheckTextというカスタムコントロールがあります。

 このコントロールはチェックボックスとテキストボックスを持ち、チェックボックスがチェックされるとテキストボックスのenable/disableがトグルします。

 このコードは、以下に示すようにレイアウトに関することがハードコードされてしまっています。

CreateChildControls 変更前
protected override void CreateChildControls()
{
    _box = new CheckBox();
    _text = new TextBox();
    _box.AutoPostBack = true;
    _text.Enabled = false;
    _box.CheckedChanged += new EventHandler(box_CheckedChanged);
    Controls.Add(_box);
    Controls.Add(_text);
}

 これは、カスタムコントロールでなければ、aspx側に次のように記述すべき内容です。

本来のレイアウト
<asp:CheckBox ID="checkBox" runat="server" AutoPostBack="true" />
<asp:TextBox ID="textBox" runat="server" Enabled="false" />

 このようになっていれば、チェックボックスをテーブルに入れたり、スタイルを当てたりと、自由に扱うことができますが、現状のつくりではCreateChildControlsを変更して、読みづらいコードを書かなくてはなりません。

ITemplate化に必要な作業(aspx側)

 それではITemplate化に必要な作業を見ましょう。

変更後のaspx
<MU:CheckText runat="server">
    <Template>
       <asp:CheckBox ID="checkBox" runat="server" AutoPostBack="true" />
       <asp:TextBox ID="textBox" runat="server" Enabled="false" />
    </Template>
</MU:CheckText>

 CheckTextの中に好きなタグ(この場合は「Template」という名前のタグ)を作り、その内部に通常のaspxのようにタグを記述します。

 こうしておくと、ASP.NETは自動生成したITemplateというものをCheckTextコントロールの同名のプロパティ(つまりTemplate)にセットしてくれます。

 また、C#側からCheckBoxTextBoxが取得できるように、IDをふっておきます。

ITemplate化に必要な作業(cs側)

 aspx側に合わせてcs側も変更します。

 まずはクラス定義にINamingContainerを追加します。

クラス定義 変更後
public class CheckText : WebControl, INamingContainer

 次にaspxで決めたタグ名(今回はTemplate)に対応するITemplate型のpublic propertyを定義します。

ITemplateプロパティ定義
private ITemplate _template;

[TemplateContainer(typeof(CheckText))]
public ITemplate Template
{
    set { _template = value; }
}

 TemplateContainerは自分自身のクラス名を指定します。このセッタがASP.NETから呼ばれます。何をするかは自由ですが、ここでは_templateというローカル変数に代入することにしましょう。

 後はCreateChildControlsを次のように書き直します。

CreateChildControls 変更後
protected override void CreateChildControls()
{
    _template.InstantiateIn(this);
    _box = (CheckBox) FindControl("checkBox");
    _text = (TextBox) FindControl("textBox");
    _box.CheckedChanged += new EventHandler(box_CheckedChanged);
}

 このように、_template.InstantiateIn(this)を呼ぶと、aspx側に記述されたコントロールがthisの下に展開されます。

 そこから先は通常のControls.Add()と同様にFindControlで取得することができます。

プレゼンテーションを変更してみる

 それではせっかくテンプレート化したので、表示を変更してみましょう。

 元のページは次のような物です。

変更前のページ
変更前のページ

 これをtableでレイアウトしましょう。これは、aspxを次のように変更するだけで行うことができます。

変更後のaspx
<MU:CheckText runat="server">
  <Template>
    <table border="1">
      <tr>
        <td>check!</td>
        <td>
          <asp:CheckBox ID="checkBox" runat="server" AutoPostBack="true" />
        </td>
      </tr>
      <tr>
        <td colspan="2">
          <asp:TextBox ID="textBox" runat="server" Enabled="false" />
        </td>
      </tr>
    </table>
  </Template>
</MU:CheckText>

 変更後は次のように表示されます。プレゼンテーションとロジックが分離されているのが分かると思います。

変更後ページ
変更後ページ

まとめ

 ITemplateを使用することでコントロールのプレゼンテーションを分離することができます。プレゼンテーションをクライアントに任せることにより、通常のコントロールよりも保守性と再利用性を高める事ができます。

 後編では、今回解説をせずに導入したTemplateContainerアトリビュートとINamingContainerについて解説します。TemplateContainerの理解はカスタムコントロールに限らず、既存のASP.NETコントロールであるRepeaterクラスやDataGridクラスを真に理解するのにも欠かせません。ご期待ください。

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
ITemplateでコントロールのプレゼンテーションを分離する連載記事一覧
この記事の著者

mumurik(ムムリク)

最近の本業はASP.NET上でのパッケージアプリケーション開発。WebControlとjsのコードが半分づつくらい。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/425 2006/09/22 09:54

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング