.NET TIPS

[ASP.NET]DataGridコントロールでテンプレート列のセルの値を取得するには?

デジタルアドバンテージ
2003/11/21

 DataGridコントロールのセルに表示されているテキストの取得方法は、定義している列の種類によって異なることがある。まず次のサンプル・プログラムを見ていただきたい。

<%@ Page Language="C#" %>

<html>
<head>
  <script runat="server">
    void Page_Load(object sender, EventArgs e) {
      MyGrid.DataSource = new DateTime[] { DateTime.Now };
      MyGrid.DataBind();
    }
  </script>
</head>

<body>
  <form runat="server">
    <asp:DataGrid id="MyGrid"
        AutoGenerateColumns="false"
        runat="server" >
      <Columns>

        <asp:BoundColumn HeaderText="連結列" DataField="Year" />

        <asp:TemplateColumn HeaderText="テンプレート列">
          <ItemTemplate>
            <%# DataBinder.Eval(Container.DataItem, "Year") %>
          </ItemTemplate>
        </asp:TemplateColumn>

      </Columns>
    </asp:DataGrid>
  </form>
</body>
</html>
連結列とテンプレート列により同じフィールドを表示するC#のサンプル・プログラム(tmplcell.aspx)

 このプログラムでは、連結列とテンプレート列を使用してデータソースの同じフィールド「Year」を表示している。実行結果は次の画面のようになる。

サンプル・プログラムの実行画面

 ここまでは特に問題ない。次にデータ連結されたグリッドのセルに表示されているテキストの取得について考えてみよう。例えば、次の2行をサンプル・プログラム中の「MyGrid.DataBind();」の後に追加したとき、それぞれどのような値が表示されるだろうか?

Response.Write(MyGrid.Items[0].Cells[0].Text);
Response.Write(MyGrid.Items[0].Cells[1].Text);

 最初の行では、連結列により作成されたセルのテキストを表示しようとしており、これは正しく「2003」を出力する。問題は2行目で、この行は何も出力しない。これは、テンプレート列の場合には、セル(TableCellオブジェクト)のTextプロパティからそのテキストを取得できないということを示している。

テンプレート列のDataBoundLiteralControlオブジェクト

 セルのTextプロパティからテキストを取得できない理由は、次のように@PageディレクティブにTrace="true"属性を追加してからプログラムを実行し、ページを構成するコントロールのツリーを見れば分かる。

<%@ Page Language="C#" Trace="true" %>

サンプル・プログラムのコントロール・ツリー
@PageディレクティブにTrace="true"属性を追加すると表示される。
  連結列により作成されたTableCellオブジェクト
  テンプレート列によりTableCellオブジェクトの子コントロールとして作成されたDataBoundLiteralControlオブジェクト

 ツリーから分かるように、テンプレート列によるセルにはDataBoundLiteralControlクラス(System.Web.UI名前空間)のオブジェクトが含まれている。このオブジェクトは、DataGridコントロールでデータ連結式(<%# …… %>)を記述したときに作成される文字列表示のためのコントロールである。

 つまり、連結列ではTableCellオブジェクトのTextプロパティによりテキストが設定されているのに対して、テンプレート列ではTableCellオブジェクトの子コントロールとしてDataBoundLiteralControlオブジェクトが作成され、そのTextプロパティによってテキストが表示されるということだ。

 よって、上述した2番目のResponse.Writeメソッドは、正しくは次のように記述しなくてはならない。

DataBoundLiteralControl literal
  = (DataBoundLiteralControl)MyGrid.Items[0].Cells[1].Controls[0];
Response.Write(literal.Text);

 これは正しく「2003」を表示する。

Labelコントロールを使用したテンプレート列

 テンプレート列でDataBoundLiteralControlオブジェクトが作成されるのは、データ連結式を<ItemTemplate>要素に直接記述した場合である。

 テンプレート列で項目を表示するには、次のようなLabelコントロールを含んだテンプレート列を記述してもよい。

  <asp:TemplateColumn HeaderText="テンプレート列">
    <ItemTemplate>
      <asp:Label id="GridLabel"
          Text='<%# DataBinder.Eval(Container.DataItem, "Year") %>'
          runat="server" />
    </ItemTemplate>
  </asp:TemplateColumn>

 このようにテンプレート列にコントロールを埋め込む場合には、そのid属性によりコントロールに名前を付けられるので、次のようにしてFindControlメソッドによりコントロールにアクセスできる。

Label label = (Label)MyGrid.Items[0].FindControl("GridLabel");
Response.Write(label.Text);

 なお、テキスト表示だけならLabelコントロールの代わりにLiteralコントロールも使用可能である。End of Article

カテゴリ:Webフォーム 処理対象:DataGridコントロール
使用ライブラリ:DataGridコントロール
使用ライブラリ:DataBoundLiteralControlクラス(System.Web.UI名前空間)
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]DataGridコントロールの行に通し番号を付けるには?
[ASP.NET]DataGridコントロールの編集用テキストボックスをカスタマイズするには?
[ASP.NET]DataGridコントロールの各セルにアクセスするには?
[ASP.NET]DataGridコントロールのヘッダーを複数行にするには?
[ASP.NET]DataGridコントロールの同一列内のセルを結合するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

Insider.NET 記事ランキング

本日 月間
ソリューションFLASH