摘要

當 GridView 繫結的 DataSource 資料筆數為 0 時,會依 EmptyDataTemplate 及 EmptyDataText 的設定來顯示無資料的狀態。若我們希望 GridView 在無資料時,可以顯示欄位標題,有一種作法是在 EmptyDataTemplate 中手動在設定一個標題列,不過這種作法很麻煩。GridView 控制項可不可以直接透過屬性設定就可以在無資料顯示欄位標題呢?答案是肯定的,本文將擴展 GridView 控制項來達成此需求。

擴展 GridView 控制項

我們繼承 GridView 命名為 TBGridView,新增一個 EmptyShowHeader 屬性,來設定無資料時是否顯示欄位標題。覆寫 CreateChildControls 方法,當 Mybase.CreateChildControls 傳回 0 時,表示 DataSource 無資料,此時就呼叫 CreateEmptyTable 方法來建立無資料只顯示標題的表格。

在 CreateEmptyTable 方法中,會複製 Columns 的集合,來輸出所有欄位的標題列。接下來會在標題列下方新增一列合併的資料列,用來顯示無資料時的顯示文字,即顯示 EmptyDataText 屬性值。

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Drawing

Namespace WebControls
    < _
    Description("TBGridView 控制項"), _
    ToolboxData("<{0}:TBGridView runat=server></{0}:TBGridView>") _
    > _
    Public Class TBGridView
        Inherits GridView
        Private FEmptyShowHeader As Boolean = True

        ''' <summary>
        ''' 無資料時是否顯示欄位標題。
        ''' </summary>
        Public Property EmptyShowHeader() As Boolean
            Get
                Return FEmptyShowHeader
            End Get
            Set(ByVal value As Boolean)
                FEmptyShowHeader = value
            End Set
        End Property


        ''' <summary>
        ''' 建立子控制項。
        ''' </summary>
        ''' <param name="dataSource">控制項的資料來源。</param>
        ''' <param name="dataBinding">true 指示子控制項繫結至資料,否則為 false。</param>
        ''' <returns>建立的資料列數目。</returns>
        Protected Overrides Function CreateChildControls(ByVal DataSource As System.Collections.IEnumerable, ByVal DataBinding As Boolean) As Integer
            Dim iRowCount As Integer
            Dim oTable As Table

            iRowCount = MyBase.CreateChildControls(DataSource, DataBinding)
            If Me.EmptyShowHeader AndAlso (iRowCount = 0) Then
                oTable = CreateEmptyTable()
                Me.Controls.Clear()
                Me.Controls.Add(oTable)
            End If
            Return iRowCount 
        End Function

        ''' <summary>
        ''' 建立無資料只顯示標題的表格。
        ''' </summary>
        Private Function CreateEmptyTable() As Table
            Dim oTable As Table
            Dim oGridViewRow As GridViewRow
            Dim oCell As TableCell
            Dim iCount As Integer
            Dim e As GridViewRowEventArgs

            oTable = MyBase.CreateChildTable()
            iCount = Me.Columns.Count - 1

            '建立標題列
            oGridViewRow = MyBase.CreateRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal)
            Dim oFields(iCount) As DataControlField
            Me.Columns.CopyTo(oFields, 0)               '取得目前定義 Columns 複本
            Me.InitializeRow(oGridViewRow, oFields)     '資料列初始化 
            e = New GridViewRowEventArgs(oGridViewRow)
            Me.OnRowCreated(e)                          '引發 RowCreated 事件
            oTable.Rows.Add(oGridViewRow)

            '建立空白的資料列
            oGridViewRow = New GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal)
            oCell = New TableCell()
            oCell.ColumnSpan = oFields.Length
            oCell.Width = Unit.Percentage(100)
            oCell.Text = Me.EmptyDataText
            oCell.HorizontalAlign = UI.WebControls.HorizontalAlign.Center
            oGridViewRow.Cells.Add(oCell)
            oTable.Rows.Add(oGridViewRow)

            Return oTable
        End Function

    End Class
End Namespace

測試程式

我們拖曳一個 TBGridView 控制項至頁面上,設定 EmptyShowHeader="True"。

 

<bee:TBGridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
            EmptyShowHeaer="True" EmptyDataText="沒有資料錄可顯示。" AllowPaging="True" DataKeyNames="EmployeeID" CellPadding="4" ForeColor="#333333" GridLines="None">

執行程式,當 GridView 有資料時的畫面如下

image

而當 GridView 無資料時,就會顯示欄位列及無資料的顯示文字(EmptyDataText)。

image


DotBlogs Tags: GridView 伺服器控制項

Feedback

  • 佩妮 ~ 2008/9/22 下午 02:47 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    Dear Jeff 大大...

    於你這篇『http://blog.blueshop.com.tw/jeff377/archive/2008/05/22/55085.aspx』...

    您有回覆說:【伺服器控制項是需要寫在一個獨立的組件中,它是會出現在左邊的工具列中拖曳到 WebForm 使用的,無法直接把程式碼寫在 WebForm 中。
    你可能需要先去買關於伺服器控制項的書籍,先自行入門,了解一下伺服器控制項的製作方式,不然你很難看得懂那些程式。 】

    因為我想直接運用在web...但好像不行這樣子做...

  • 佩妮 ~ 2008/9/22 下午 03:02 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    Dear Jeff大大你好:

    很想請教您...

    關於有【Namespace WebControls】的寫法...

    因為我看到您這三篇...就有兩篇有用到...

    很想學起來...但不懂那個是什麼...

    可否麻煩您指點...謝謝您...

  • jeff377 2008/9/24 下午 07:59 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    to 佩妮 ~ :
    Namespace WebControls 只是命名空間,跟你看的程式沒有直接關係,它的作用只是把所有相關的類別歸類在同一個命名空間,比較好找到相關的類別。例如跟資料庫相關的類別大都在 System.Data 命名空間之下。
    那幾篇都是「伺服器控制項」,所謂的「伺服器控制項」就是工具箱拖曳到頁面中都那些控制項,都屬於伺服器控制項。它的好處就是可以在多個專案中重覆使用,就如同我們使用 VS 中現成的 GridView、FormView 控制項一樣。不過市面上這類書籍非常少,所以大都只能由網路上找到相關資料。

  • hatelove 2008/10/26 上午 01:06 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    請問一下jeff大大,CreateEmptyTable()裡,第69、70行,為什麼需要在call一次Me.OnRowCreated(e) ?

    如果沒有call,會有什麼影響呢?

  • hatelove 2008/10/26 上午 01:11 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    另外,能否請jeff大有空的時候,分享或指導一下,

    自訂GridView Pager的部分,往往在開發時,會面臨GridView分頁需要高度客製化,我自己設計的分頁實在是效率有點糟糕,隱藏的問題一堆。

  • jeff377 2008/10/26 上午 08:23 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    to hatelove :
    呼叫 Me.OnRowCreated(e) 是為了引發 RowCreated 事件,讓開發人類可以在此事件再去做處理。

  • marco 2008/11/18 下午 10:40 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    jeff大大你好:依照上述作法,我在表頭上加了一個textbox, 如果datasource是沒有資料時<br>CType(TBGridView1.HeaderRow.FindControl("TextBox1"), TextBox).Text,會說找不到TextBox1元件呢??謝謝。

  • jeff377 2008/11/19 上午 10:52 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    to marco :
    要看你 FindControl 的時機點在那,要確認已經建立該控制項後,使用 FindControl 才找到該掏制項。

  • marco 2008/11/19 下午 07:59 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    我在headerrow加一個新增按鈕, 在click事件中作FindControl,如果在有資料時是可以的,但當沒資料時,HeaerRow是nothing?那我要哪個時機作FindControl呢?謝謝

  • jeff377 2008/11/19 下午 08:06 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    to marco :
    你是要在無資料時,有新增鈕可以按對吧。正確的作法是去改 CommandField 即可,參考下面文章的作法。

    擴展 CommandField 類別 - Header 加入新增鈕

  • marco 2008/11/19 下午 10:36 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    Jeff 大大:
    我想在Header增加一欄可以新增資料的Row。所以不止有新增,並有欄位新增資料。在有資料時,Header可以出現這個欄位。但無資料時,就沒辦法出現這個headerRow,感謝利用你的方法,當沒資料時,headerow出現了,但我自定的textbox會發現用findcontrol是找不到元件。我作錯了什麼地方呢?

  • jeff377 2008/11/20 上午 09:39 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列

    to marco :
    建立的控制項不可能找不到,只有可能 FindControl 的時機點或階層不對才有可能無法找到。
    在 GridView 新增的資料列的動作,比較好的方式不是寫在 GridView  中,而是使用 DataControlField 去處理。因為若某個欄位是使用 TemplateField,你怎麼知道在新增資料列時該欄位要怎麼呈現編輯控制項呢?所以由繼承原 GridView 的欄位類別(如 BoundField) 是比最好的方式。

  • GN 2009/5/30 下午 03:08 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列


    請問你有沒有用GridView新增的相關文章,我去找了一下有看到用Footer的做法,不知你有什麼看法?

  • King 2009/10/19 下午 06:21 回覆

    # re: 擴展 GridView 控制項 - 無資料時顯示標題列


    請教Namespace的程式碼是要放在那?
    在ASP中要如何引用呢?

標題 *
名稱 *
Email (將不會被顯示)
Url
回應
登入後使用進階評論
Please add 7 and 3 and type the answer here: