Show GridView even if datasource is empty
A simple method to show a GridView even if the datasource asigned is empty.
Introduction
I was recently faced with a problem where I used a GridView
to add new data directly into the grid from the grid's footer, but found out that when there is no data (no rows in my DataTable
) to show initially, the grid was not visible, and thus adding new data via the footer was not possible.
Solution Explanation
I wrote a simple method that adds an empty row to the GridView
's DataSource
then hides that row. Many examples out there shows this technique using the RowDataBound
event; it works initially, but when doing a second postback, the empty row and its controls will show up again.
The Code
The method below takes the grid's DataSource
and extracts the DataTable
from it; it clones a copy and then adds an empty row. Cloning the DataTable
will prevent you from adding an empty row inadvertently to your "Master" source.
You will notice two if
statements; the first one will execute directly after you have assigned a source to your GridView
, the second will execute on Page_Load
.
/// =============================================================
/// <summary>
/// Show grid even if datasource is empty
/// <param name="grdView">GridView</param>
/// =============================================================
protected void EmptyGridFix(GridView grdView)
{
// normally executes after a grid load method
if (grdView.Rows.Count == 0 &&
grdView.DataSource != null)
{
DataTable dt = null;
// need to clone sources otherwise
// it will be indirectly adding to
// the original source
if (grdView.DataSource is DataSet)
{
dt = ((DataSet)grdView.DataSource).Tables[0].Clone();
}
else if (grdView.DataSource is DataTable)
{
dt = ((DataTable)grdView.DataSource).Clone();
}
if (dt == null)
{
return;
}
dt.Rows.Add(dt.NewRow()); // add empty row
grdView.DataSource = dt;
grdView.DataBind();
// hide row
grdView.Rows[0].Visible = false;
grdView.Rows[0].Controls.Clear();
}
// normally executes at all postbacks
if (grdView.Rows.Count == 1 &&
grdView.DataSource == null)
{
bool bIsGridEmpty = true;
// check first row that all cells empty
for (int i = 0; i < grdView.Rows[0].Cells.Count; i++)
{
if (grdView.Rows[0].Cells[i].Text != string.Empty)
{
bIsGridEmpty = false;
}
}
// hide row
if (bIsGridEmpty)
{
grdView.Rows[0].Visible = false;
grdView.Rows[0].Controls.Clear();
}
}
}
Implementation
The method must be called on two occasions:
- Directly after assigning your
DataSet
orDataTable
to yourGridView
- On each
Page_Load
public class MyPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.EmptyGridFix(grdYourGrid);
if (!this.IsPostBack)
{
this.LoadGrid();
}
}
protected void LoadGrid()
{
DataSet dsMyDataSet = null;
// obtain dataset/datatable from DAL/BAL
grdYourGrid.DataSource = dsMyDataSet.Table[0];
grdYourGrid.DataBind();
this.EmptyGridFix(grdYourGrid);
}
protected void EmptyGridFix(GridView grdView)
{
// method code comes here
}
// rest of page implementation would follow
}
Last words
The code above only works on instances where the GridView DataSource
is being populated via a DataSet
or DataTable
, I have not tested any other sources.
A good idea is to create a class that would inherit from System.Web.UI.Page
and drop the above method in there and have your pages inherit from that class.
I guess there are cleaner/better ways to implement this if... I can think of some really outrageous ways of fixing this stupid problem, like overloading the original GridView
control. But one has to weigh the effort spent against the benefits. I really hope to see a fix in future versions of .NET.