Sometimes it would be nice if things did what you expect them to do, for example the gridview in .NET. I expected it to display the header and footer rows even if the query returned no rows, als this is not the case, there isn't even a switch to turn it on. After alot of searching I found several solutions, but struggled to make them work, finally I did and I thought I would share how it's done.
First of all we need to create a class - showheader.cs this goes in the App_Code folder.
GridViewAlwaysShow.cs
1: using System;
2: using System.Collections;
3: using System.Data;
4: using System.Web.UI.WebControls;
5:
6: namespace AlwaysShowHeaderFooter
7: {
8: public delegate IEnumerable MustAddARowHandler(IEnumerable data);
9: public class GridViewAlwaysShow : GridView
10: {
11: //Flag used to identify if the datasource is empty.
12: bool _isEmpty = false;
13: protected override void OnDataBound(EventArgs e)
14: {
15: //if in DesignMode, don't do anything special. Just call base and return.
16: if (DesignMode)
17: {
18: base.OnDataBound(e);
19: return;
20: }
21: //hide the dummy row.
22: if (_isEmpty)
23: {
24: Rows[0].Visible = false;
25: }
26: base.OnDataBound(e);
27: }
28: protected override void PerformDataBinding(IEnumerable data)
29: {
30: //If in DesignMode, don't do anything special. Just call base and return.
31: if (DesignMode)
32: {
33: base.PerformDataBinding(data);
34: return;
35: }
36: //Count the data items.(I wish I knew a better way to do this.)
37: int objectItemCount = 0;
38: foreach (object o in data)
39: {
40: objectItemCount++;
41: }
42: //If there is a count, don't do anything special. Just call base and return.
43: if (objectItemCount > 0) {
44: base.PerformDataBinding(data);
45: return;
46: }
47: //Set these values so the GridView knows what's up.
48: SelectArguments.TotalRowCount++;
49: _isEmpty = true;
50: //If it's a DataView, it will work without having to handle the MustAddARow event.
51: if (data.GetType() == typeof(DataView))
52: {
53: //Add a row and use that new view.
54: DataView dv = (DataView)data;
55: dv.Table.Rows.InsertAt(dv.Table.NewRow(), 0);
56: base.PerformDataBinding(dv.Table.DefaultView);
57: return;
58: }
59: else
60: {
61: //If you are using some custom object, you need to handle this event.
62: base.PerformDataBinding(OnMustAddARow(data));
63: return;
64: }
65: }
66: protected IEnumerable OnMustAddARow(IEnumerable data) {
67: if (MustAddARow == null) {
68: throw new NullReferenceException("The datasource has no rows. You must handle the \"MustAddARow\" Event.");
69: }
70: return MustAddARow(data);
71: }
72: public event MustAddARowHandler MustAddARow;
73: }
74: }
Also we need a class to create the blank row this does nothing (it was this that confused me for quite a while I thought I needed to populate this with something related to my datasource)
Class1.cs
1: using System;
2:
3: public class Class1
4: {
5: public Class1()
6: {
7: }
8: }
Then we need to register this in the web.config file
web.config
<pages>
<controls>
<add tagPrefix="custom" namespace="AlwaysShowHeaderFooter" />
</controls>
</pages>
Finally we need to impliment the table the .aspx pag, this is the same as you would do for a normal gridview, just replace <asp:GridView with <Custom:GridViewAlwaysShow and it will pick up the new namespace.
emptygridview.aspx
<Custom:GridViewAlwaysShow ID="gvGridView" runat="server"
AllowPaging="True"
AllowSorting="True"
AutoGenerateColumns="False"
EmptyDataText="There are no data records to display."
ShowFooter="True"
DataKeyNames="DataField2"
DataSourceID="dsSQL" OnMustAddARow="gv_MustAddARow">
<Columns>
<asp:BoundField DataField="DataField1" HeaderText="Data Field 1"
SortExpression="DataField1" />
<asp:BoundField DataField="DataField2" HeaderText="Data Field 2"
SortExpression="DataField2" InsertVisible="False" ReadOnly="True" />
<asp:BoundField DataField="DataField3"
HeaderText="Data Field 3"
SortExpression="DataField3" />
</Columns>
</Custom:GridViewAlwaysShow>
<asp:SqlDataSource ID="dsSQL" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="selectData" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="0" Name="SearchField" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
And the aspx.cs handleryou will need
using System.Collections.Generic;
using System.Collections;
in addition to any others.
emptygridview.aspx.cs
1: protected IEnumerable gv_MustAddARow(IEnumerable data)
2: {
3: List<Class1> dds = null;
4: dds.Add(new Class1());
5: return dds;
6: }
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5