Show gridview footer on empty grid?
Asked Answered
K

6

12

just wanted to know what is the best and easiest way to show a gridview footer for data entry even when the gridview is empty ?

Kirkpatrick answered 9/8, 2010 at 5:39 Comment(0)
P
16

Set your datasource to the type of object you're binding to the GridView with one object filled with empty values, then hide that DataRow.

EDIT: Since you're using a datatable...

DataTable dt = new DataTable();

// Define all of the columns you are binding in your GridView
dt.Columns.Add("AColumnName");
...
...

DataRow dr = dt.NewRow();
dt.Rows.Add(dr);

myGridView.DataSource = dt;
myGridView.DataBind();
Pliers answered 9/8, 2010 at 5:42 Comment(2)
I am using a datatable, do you have any sample ?Kirkpatrick
I feel like this is kind of clunky but I was running low on time, so this fix worked for me. I had to hide that row "empty" row in the gridview by adding myGridView.Rows[0].visible = false.Pagas
Y
9

More elegantly.. extend GridView and add a ShowFooterWhenEmpty property so that you don't have to implement custom code everywhere.

Imports System.Web.UI.WebControls
Imports System.ComponentModel

Namespace UI.WebControls
Public Class GridViewExtended
    Inherits GridView

    Private _footerRow As GridViewRow

    <DefaultValue(False), Category("Appearance"), Description("Include the footer when the table is empty")> _
    Property ShowFooterWhenEmpty As Boolean

    <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
    Public Overrides ReadOnly Property FooterRow As GridViewRow
        Get
            If (Me._footerRow Is Nothing) Then
                Me.EnsureChildControls()
            End If
            Return Me._footerRow
        End Get
    End Property

    Protected Overrides Function CreateChildControls(ByVal dataSource As System.Collections.IEnumerable, ByVal dataBinding As Boolean) As Integer
        Dim returnVal As Integer = MyBase.CreateChildControls(dataSource, dataBinding)
        If returnVal = 0 AndAlso Me.ShowFooterWhenEmpty Then
            Dim table As Table = Me.Controls.OfType(Of Table)().First
            Me._footerRow = Me.CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal, dataBinding, Nothing, Me.Columns.Cast(Of DataControlField).ToArray, table.Rows, Nothing)
            If Not Me.ShowFooter Then
                _footerRow.Visible = False
            End If
        End If
        Return returnVal
    End Function

    Private Overloads Function CreateRow(ByVal rowIndex As Integer, ByVal dataSourceIndex As Integer, ByVal rowType As DataControlRowType, ByVal rowState As DataControlRowState, ByVal dataBind As Boolean, ByVal dataItem As Object, ByVal fields As DataControlField(), ByVal rows As TableRowCollection, ByVal pagedDataSource As PagedDataSource) As GridViewRow
        Dim row As GridViewRow = Me.CreateRow(rowIndex, dataSourceIndex, rowType, rowState)
        Dim e As New GridViewRowEventArgs(row)
        If (rowType <> DataControlRowType.Pager) Then
            Me.InitializeRow(row, fields)
        Else
            Me.InitializePager(row, fields.Length, pagedDataSource)
        End If
        If dataBind Then
            row.DataItem = dataItem
        End If
        Me.OnRowCreated(e)
        rows.Add(row)
        If dataBind Then
            row.DataBind()
            Me.OnRowDataBound(e)
            row.DataItem = Nothing
        End If
        Return row
    End Function

End Class
End Namespace
Yarvis answered 16/12, 2010 at 14:52 Comment(1)
C# version #995395Department
H
4

Another solution is to always add a dummy row in your datasource, "mark" that row with a specific value, then hide the row on RowDataBound.

To be more precise, add the column ", 0 AS dummyRow" to end of your query's SELECT clause, then UNION ALL the full statment to

SELECT NULL AS column1, NULL AS column2,...,NULL AS columnN, 1 AS dummyRow

Once you have the query in place (all of which can be done within your SQLDataSource or in the your DAL object, your code for the grid will look something like this:

Protected Sub MyGridView_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridView.RowDataBound
    If (e.Row.RowType = DataControlRowType.DataRow) AndAlso (Not e.Row.DataItem Is Nothing) AndAlso (CInt(e.Row.DataItem("dummyRow")) = 1) Then
          e.Row.Visible = False
    End If
End Sub

This solution comes with some obvious overhead, since this check will be done for every row of the results, not to mention you have to change your SELECT Query, but it also has the advantage of not requiring to dynamically change the dataset (as in the first example) and not requiring much code or having to deploy custom control libraries for your web-project.

Hobo answered 28/6, 2012 at 18:16 Comment(0)
H
1

As a side-note, if you want to conditionally EITHER show the grid's header and footer OR show the emptydata text/template, after you have hidden the row with the code I posted above, you can check your condition and if necessary delete the row. Then the code will look something like this:

 Protected Sub MyGridView_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridView.RowDataBound
      If (e.Row.RowType = DataControlRowType.DataRow) AndAlso (Not e.Row.DataItem Is Nothing) AndAlso (CInt(e.Row.DataItem("dummyRow")) = 1) Then
            e.Row.Visible = False
      If (ConditionToShowEmptyDataTemplate) Then
           CType(e.Row.DataItem, System.Data.DataRowView).Delete()
           CType(e.Row.Parent, System.Web.UI.WebControls.Table).Rows.Remove(e.Row)
      End If
 End Sub

Notice that here we remove both the DataItem row (necessary because on post-backs the gridview may redraw itself without re-databinding) and the GridView Row itself (necessary because by this point the row is already in the grid's Childtable, which we don't want).

Finally, if the hidden dummy record is causing other issues in your gridview when it has other data (for example, bad paging), you can use similar code to delete your dummy row when the gridview has more rows.

Hobo answered 5/7, 2012 at 15:35 Comment(0)
J
1

You can create an "empty" row and make it invisible:

if (list != null && list.Any())
        {
            gridView.DataSource = list;
            gridView.DataBind();
        }
        else
        {
            MyCustomClass item = new MyCustomClass(){Id = 0, Name = "(No Data Rows)", Active = false};
            List<MyCustomClass> l = new List<MyCustomClass>();
            l.Add(item);
            gridView.DataSource = l;
            gridView.DataBind();
            gridView.Rows[0].Visible = false;
        }
Jolda answered 1/9, 2016 at 19:9 Comment(0)
T
0

Ideally you only want to show the dummy row if there are no records in the table yet. So set your SelectCommand to something like this:

SELECT [ID], FirstName, LastName, Email FROM Customers union SELECT 0 [ID], '' FirstName, '' LastName, '' Email where 0 in (SELECT COUNT(1) from Customers)

That way if the count > 0, the dummy row isn't returned.

Note that the dummy row does not have a FROM clause in it.

Tidal answered 15/9, 2015 at 2:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.