ASP.NET GridViewのItemTemplateタグ内で各明細毎にフッターレコードを作成する
1. はじめに
現在、ASP.NETの案件に携わっており、各明細行に対してフッターレコードを挿入した様なGridViewのレイアウト作成を依頼されました。
少し手こずってしまったので、備忘として記載します。
また、今回の案件ではGridViewを継承したカスタムコントロールを使用しなければならない規約でしたので、かなりゴリ推しで記述しています。。。。。
ご了承ください。
2. やりたいこと
列結合した行を各明細行の下に追加する様なイメージです。
通常のhtmlなら<td>にcolspan指定すれば良い、なんてことないレイアウトになります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
<table id="PersonTable" border="1" cellspacing="0" cellpadding="0">
<tr style="background-color:#6088C6;">
<th>ID</th>
<th>Name</th>
<th>Gender</th>
</tr>
<tr>
<td rowspan="2">001</td>
<td>Taro Tanaka</td>
<td>Male</td>
</tr>
<tr>
<td colspan="2">Remarks:Normal Employee</td>
</tr>
<tr>
<td rowspan="2">002</td>
<td>Yuki Suzuki</td>
<td>Female</td>
</tr>
<tr>
<td colspan="2">Remarks:Leader</td>
</tr>
</table>
</body>
</html>
3. DataGridコントロール内で実装する
というわけで実装してみました。
<%@ Page Title="Sample Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Sample .aspx.cs" Inherits="WebApplication1._Sample " %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:GridView ID="PersonView" runat="server"
autoGenerateColumns="false"
headerStyle-BackColor="#6088C6" OnRowDataBound="PersonView_RowDataBound">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:Label runat="server" Text="ID"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label id="IDLabel" runat="server" Text=<%# DataBinder.Eval(Container.DataItem, "ID").ToString() %>></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<asp:Label runat="server" Text="Name"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label id="NameLabel" runat="server" Text=<%# DataBinder.Eval(Container.DataItem, "Name").ToString() %>></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<asp:Label runat="server" Text="Gender"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label id="GenderLabel" runat="server" Text=<%# DataBinder.Eval(Container.DataItem, "Gender").ToString() %>></asp:Label>
</td></tr>
<tr id="DetailFooterRow">
<td colspan ="2">
<asp:Label id="RemarksCaptionLabel" runat="server" Text="Remarks:"></asp:Label>
<asp:Label id="RemarksLabel" runat="server" Text=<%# DataBinder.Eval(Container.DataItem, "Remarks").ToString() %>></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Content>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace WebApplication1
{
/// <summary>
/// Defaultページクラス
/// </summary>
public partial class _Sample : Page
{
/// <summary>
/// ロードイベント
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
//----------------------------------------
// [1] バインドデータ作成
//----------------------------------------
DataTable personTable = new DataTable("PersonTable");
//カラム設定
personTable.Columns.AddRange(new DataColumn[]
{
new DataColumn("ID", typeof(string))
,new DataColumn("Name", typeof(string))
,new DataColumn("Gender", typeof(string))
,new DataColumn("Remarks", typeof(string))
});
//データを追加
personTable.Rows.Add(new string[] { "001", "Taro Tanaka", "Male", "Normal Employee" });
personTable.Rows.Add(new string[] { "002", "Yuki Suzuki", "Female", "Leader" });
//----------------------------------------
// [2] GridViewにバインド
//----------------------------------------
this.PersonView.DataSource = new DataView(personTable);
this.PersonView.DataBind();
}
/// <summary>
/// 行バインドイベント
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void PersonView_RowDataBound(object sender, GridViewRowEventArgs e)
{
//DataBind行のみを対象
if (e.Row.RowType == DataControlRowType.DataRow)
{
//IDセルの行幅を設定
e.Row.Cells[0].RowSpan = 2;
}
}
}
}
上記のコーディングで下記の動的コードが生成されます。
<table cellspacing="0" rules="all" border="1" id="MainContent_PersonView" style="border-collapse:collapse;">
<tr style="background-color:#6088C6;">
<th scope="col">
<span>ID</span>
</th><th scope="col">
<span>Name</span>
</th><th scope="col">
<span>Gender</span>
</th>
</tr><tr>
<td rowspan="2">
<span id="MainContent_PersonView_IDLabel_0">001</span>
</td><td>
<span id="MainContent_PersonView_NameLabel_0">Taro Tanaka</span>
</td><td>
<span id="MainContent_PersonView_GenderLabel_0">Male</span>
</td></tr>
<tr id="DetailFooterRow">
<td colspan ="2">
<span id="MainContent_PersonView_RemarksCaptionLabel_0">Remarks:</span>
<span id="MainContent_PersonView_RemarksLabel_0">Normal Employee</span>
</td>
</tr><tr>
<td rowspan="2">
<span id="MainContent_PersonView_IDLabel_1">002</span>
</td><td>
<span id="MainContent_PersonView_NameLabel_1">Yuki Suzuki</span>
</td><td>
<span id="MainContent_PersonView_GenderLabel_1">Female</span>
</td></tr>
<tr id="DetailFooterRow">
<td colspan ="2">
<span id="MainContent_PersonView_RemarksCaptionLabel_1">Remarks:</span>
<span id="MainContent_PersonView_RemarksLabel_1">Leader</span>
</td>
</tr>
</table>
ポイントとしては<ItemTemplate>の最終項目直下に</td></tr>を記述し、その下部に<tr><td>を記述しています。
上記によって動的ソース生成時に無理やり<tr>要素を追加しています。
そして実際に表示されるページがこちらになります。
(手抜きで申し訳ありません。。。)
4. 懸念事項
今回はStyle系のプロパティの変更がなかった為、上記のロジックで問題ありませんでした。
しかし、GridViewのAlternatingRowStyle等のプロパティを指定する場合は注意が必要です。
上記のプロパティはあくまで、動的に生成される<tr>単位に設定されます。
その為、<tr>を無理矢理閉じてしまうとプロパティに指定したStyleが適用されません。
解決策としては、イベントのタイミングで設定可能であれば、対象の<tr>をHtmlTableRowクラスかTableRowクラスで設定してあげるか、cssでクラスを定義し、JavaScript等で実装するしかなさそうです。
(※筆者は未だ検証出来ておりません。)
Author And Source
この問題について(ASP.NET GridViewのItemTemplateタグ内で各明細毎にフッターレコードを作成する), 我々は、より多くの情報をここで見つけました https://qiita.com/kyaloway/items/d0b5118a18b7396fdd76著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .