WebSurfer's Home

Filter by APML

GridView, ListView でデータがない時もヘッダを表示

by WebSurfer 18. March 2026 18:21

ASP.NET Web Forms アプリの GirdView、ListView で、レコードが格納されてないデータソースがバインドされた時も、下の画像のようにヘッダ行を表示する方法を備忘録として書いておきます (デフォルトでは表示されません)。

GridView, ListView でデータがない時もヘッダを表示

以下に GridView と ListView のそれぞれの場合について書きます。上の画像を表示するのに使ったコードをこの記事の下の方に載せておきますのでそちらも参考にしてください。

(1) GridView

SqlDataSource のようなデータソースコントロールと組み合わせて使っていて、SqlDataSource がデータベースに SELECT クエリを投げても WHERE 句の条件が一致しないなどの理由でレコードを取得できない場合を考えます。

レコードを取得できなくても、SqlDataSource は空のデータソースを生成し、自動的にそれを GridView にデータバインドします。その場合は以下のように設定すれば上の画像のように表示されます。

データソースコントロールを使わないで自力でコードを書いて DataTable や List<T> を作成し、それを GridView の DataSource プロパティに設定して DataBind メソッドでバインドしている場合、ヘッダを表示するには空のデータソースを作ってバインドする必要がありますので注意してください。上の画像の GridView2 がそれで、コードはこの記事の下の方に載せましたので見てください。


(2) ListView

ListView には GridView の EmptyDataText のような便利なプロパティは存在しません。ListView.EmptyDataTemplate プロパティにデータが空の時表示したい html コードを書きます。

Visual Studio のデザイナを使って ListView のコードを生成させると、そのコードには EmptyDataTemplate が含まれるはずです。その中にヘッダと No data was returned. というメッセージ行の html コードを書いた結果が上の ListView の画像です。そのコードは下に載せましたので見てください。


上の画像を表示したコードは以下の通りです。

.aspx.cs

using System;
using System.Collections.Generic;

namespace WebForms1
{
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                // GridView2 はデータソースコントロールを使わない
                var data = new List<Hotel>();
                GridView2.DataSource = data;
                GridView2.DataBind();
            }
        }
    }

    public class Hotel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public decimal RoomCharge { get; set; }
    }
}

.aspx

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="WebForm2.aspx.cs"
    Inherits="WebForms1.WebForm2" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        table.style1 {
            border-style: solid;
            border-width: 2px;
            border-color: Silver;
            border-collapse: collapse;
        }

            table.style1 th {
                border-style: solid;
                border-width: 2px 1px 2px 1px;
                border-color: Silver;
                padding: 5px 8px;
                background-color: #6699FF;
                color: #FFFFFF;
            }

            table.style1 td {
                border-style: solid;
                border-width: 1px;
                border-color: Silver;
                padding: 2px 8px;
            }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <asp:SqlDataSource ID="SqlDataSource1" runat="server"
            ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
            ProviderName="<%$ ConnectionStrings:NorthwindConnectionString.ProviderName %>"
            SelectCommand="SELECT [CustomerID], [CompanyName], [Address], [City], 
                    [PostalCode], [Country] FROM [Customers] WHERE CustomerID='NoID'">
        </asp:SqlDataSource>

        <h3>GirdView</h3>

        <asp:GridView ID="GridView1" runat="server"
            AutoGenerateColumns="False"
            DataKeyNames="CustomerID"
            ShowHeaderWhenEmpty="True"
            DataSourceID="SqlDataSource1"
            EmptyDataText="No data was returned.">
            <Columns>
                <asp:BoundField DataField="CustomerID" HeaderText="CustomerID"
                    ReadOnly="True" SortExpression="CustomerID" />
                <asp:BoundField DataField="CompanyName" HeaderText="CompanyName"
                    SortExpression="CompanyName" />
                <asp:BoundField DataField="Address" HeaderText="Address"
                    SortExpression="Address" />
                <asp:BoundField DataField="City" HeaderText="City"
                    SortExpression="City" />
                <asp:BoundField DataField="PostalCode" HeaderText="PostalCode"
                    SortExpression="PostalCode" />
                <asp:BoundField DataField="Country" HeaderText="Country"
                    SortExpression="Country" />
            </Columns>
        </asp:GridView>

        <h3>GridView2</h3>
        <asp:GridView ID="GridView2" runat="server" 
            EmptyDataText="No data was returned." 
            ShowHeaderWhenEmpty="True"></asp:GridView>

        <h3>ListView</h3>

        <asp:ListView ID="ListView1" runat="server"
            DataKeyNames="CustomerID"
            DataSourceID="SqlDataSource1">
            <EmptyDataTemplate>
                <table class="style1">
                    <tr>
                        <th>CustomerID</th>
                        <th>CompanyName</th>
                        <th>Address</th>
                        <th>City</th>
                        <th>PostalCode</th>
                        <th>Country</th>
                    </tr>
                    <tr>
                        <td colspan="6">No data was returned.</td>
                    </tr>
                </table>
            </EmptyDataTemplate>
            <ItemTemplate>
                <tr style="">
                    <td>
                        <asp:Label ID="CustomerIDLabel" runat="server"
                            Text='<%# Eval("CustomerID") %>' />
                    </td>
                    <td>
                        <asp:Label ID="CompanyNameLabel" runat="server"
                            Text='<%# Eval("CompanyName") %>' />
                    </td>
                    <td>
                        <asp:Label ID="AddressLabel" runat="server"
                            Text='<%# Eval("Address") %>' />
                    </td>
                    <td>
                        <asp:Label ID="CityLabel" runat="server"
                            Text='<%# Eval("City") %>' />
                    </td>
                    <td>
                        <asp:Label ID="PostalCodeLabel" runat="server"
                            Text='<%# Eval("PostalCode") %>' />
                    </td>
                    <td>
                        <asp:Label ID="CountryLabel" runat="server"
                            Text='<%# Eval("Country") %>' />
                    </td>
                </tr>
            </ItemTemplate>
            <LayoutTemplate>
                <table id="itemPlaceholderContainer" runat="server" class="style1">
                    <tr runat="server" style="">
                        <th runat="server">CustomerID</th>
                        <th runat="server">CompanyName</th>
                        <th runat="server">Address</th>
                        <th runat="server">City</th>
                        <th runat="server">PostalCode</th>
                        <th runat="server">Country</th>
                    </tr>
                    <tr id="itemPlaceholder" runat="server">
                    </tr>
                </table>
            </LayoutTemplate>
        </asp:ListView>
    </form>
</body>
</html>

Tags: , , ,

ASP.NET

ListView に thead と tbody 追加

by WebSurfer 1. April 2024 13:11

ASP.NET Web Forms アプリ用の ListView コントロールからレンダリングされる html ソースの table 要素内に thead, tbody 要素を追加する方法を書きます。

Visual Studio のデザイナを使って ListView のテーブル形式のコードを自動生成させると aspx ファイルに以下のような LayoutTemplate が生成されます。まず、それに赤枠と青枠で示したような thead, tbody 要素を追記します。

aspx ファイル

さらに、自動生成されたコードでは親の table 要素に runat="server" 属性が付与されているのでそれを削除する必要があります。上の画像のコメントを見てください。

runat="server" 属性が付与されているとその要素はサーバーコントロールになります。親の table 要素がサーバーコントロールになると、ASP.NET が html ソースをレンダリングする際に追加した thead, tbody 要素は削除されてしまいますので。

結果の html ソースは以下のようになります。

結果の html ソース

runat="server" 属性を削除するとサーバー側のコードでその要素を操作(例えばプロパティを動的に設定するなど)できなくなりますが、それ以外の不都合はないと思います。

GridView の例は別の記事「GridView と thead, tbody, tfoot」に書きましたのでそちらを見てください。

Tags: , ,

ASP.NET

GridView, ListView で特定の行をハイライト

by WebSurfer 13. October 2016 23:35

GridView, ListView でデータを一覧表示する際、それにデータバインドされたデータソースに含まれる各行の特定の列のデータの値を調べ、その値に応じて当該行をハイライトする方法について書きます。

元は MSDN フォーラムのスレッド「ListViewでの一覧表示で、取得したデータに応じて背景色を変えたい」での話です。

そのスレッドで自分が回答したことなのですが、忘れかけていたので自分のブログに備忘録として書いておくことにしました。また、ついでに GridView での実装例も書いておきます。

このブログの別の記事「GridView, ListView に合計表示」のコードをベースにしていますので、そちらも見てください。

その記事では、Microsoft が提供するサンプルデータベース Northwind の Orders というテーブルのレコードのうち、[CustomerID] が ALFKI という顧客の注文の [OrderID], [OrderDate], [Freight] フィールド一覧を表示しています。

Orders テーブルには出荷日を示す [ShippedDate] というフィールドが含まれています。ここでは、[ShippedDate] を調べて、ある日付より後に出荷されたレコードの行の背景色をハイライトしてみます。なお、ListView / GridView には [ShippedDate] フィールドは表示しません。

ListView での例

以下の画像は 1998/1/1 より後に出荷された注文のレコードをハイライトしたものです。

ListView

紹介した MSDN フォーラムのスレッドで書いたとおりですが、上のように表示するための具体的な方法を以下に書きます。

  1. SqlDataSource の SELECT クエリに [ShippedDate] を追加します。
  2. ListView の ItemTemplate 内の tr 要素をサーバーコントロールに変更して id を付与します。具体的には runat="server" id="datarow" という 2 つの属性を追加します(id 名は任意)。
  3. 例えば、1998/1/1 より後に出荷されたレコードを黄色でハイライトする場合、[ShippedDate] が 1998/1/1 より後のアイテムの中から FindControl メソッドで上記 2 でサーバーコントロールにした tr 要素を探し、それに style 属性を追加します。コードは以下のようになります。
protected void ListView1_ItemDataBound(object sender, 
        ListViewItemEventArgs e)
{
  if (e.Item.ItemType == ListViewItemType.DataItem)
  {
    ListViewDataItem lvdi = (ListViewDataItem)e.Item;
    DataRowView drv = (DataRowView)lvdi.DataItem;
    total = total + (decimal)drv["Freight"];

    // 以下が追加した部分
    DateTime date = new DateTime(1998, 1, 1, 0, 0, 0);
    if ((DateTime)drv["ShippedDate"] > date)
    {
      HtmlControl tr = (HtmlControl)lvdi.FindControl("datarow");
      if (tr != null)
      {
        tr.Attributes.Add("style", "background-color:yellow;");
      }
    }
  }
}

GridView での例

上の ListView の場合と同様に、1998/1/1 より後に出荷された注文のレコードをハイライトしたものです。

GridView

上のように表示するための具体的な方法は以下の通りです。

  1. SqlDataSource の SELECT クエリに [ShippedDate] を追加します。(ListView の場合と同様)
  2. ListView の場合とは異なり、GridView のコードには手を加える必要はありません。GridView の RowDataBound イベントで GridViewRow を取得し、それの CssClass プロパティにスタイルを設定できますので。
  3. 上の ListView の場合と同様に、1998/1/1 より後に出荷されたレコードを黄色でハイライトする場合、[ShippedDate] を調べて 1998/1/1 より後であれば、当該行の GridViewRow オブジェクトを取得し、その CssClass プロパティを設定します。コードは以下のようになります。
protected void GridView1_RowDataBound(object sender, 
        GridViewRowEventArgs e)
{        
  if (e.Row.RowType == DataControlRowType.DataRow)
  {
    DataRowView drv = (DataRowView)e.Row.DataItem;
    total = total + (decimal)drv["Freight"];

    // 以下が追加した部分
    DateTime date = new DateTime(1998, 1, 1, 0, 0, 0);
    if ((DateTime)drv["ShippedDate"] > date)
    {
      e.Row.CssClass = "style1";
    }
    // ここまで
  }
  else if (e.Row.RowType == DataControlRowType.Footer)
  {
    e.Row.Cells[1].Text = "Freight Total";
    e.Row.Cells[2].Text = String.Format("${0:N2}", total);

    e.Row.Cells[1].ColumnSpan = 2;
    e.Row.Cells.RemoveAt(0);            
  }        
}

e.Row.CssClass = "style1"; のところの style1 は別途定義してソースに追加してください。インラインで <title> 要素の下に書くなら以下のようにします。

<style type="text/css">
    .style1
    {
        background-color: yellow;
    }
</style>

Tags: , ,

ASP.NET

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。ブログ2はそれ以外の日々の出来事などのトピックスになっています。

Calendar

<<  July 2026  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar