GridView added rows non-persistent

F

Flinky Wisty Pomm

Hi all, I've got a really annoying problem that I need to fix sharpish.

I've got a GridView derived control which has a templated header and
footer. It works wonderfully on the first render but then the
header/footer vanish into thin air. If I add the header/footer
onDataBound then they disappear when I do a postback with no
databinding. If I add them during PreRender, then they persist, but one
of my data rows is emptied for each time I postback.

It feels like there's a rowIndex being kicked out of place, but I've
run reflector over CreateChildControls and given up all hope of
understanding it in the next week. Can anyone offer some help?

test code is below, apologies if it's not quite cut/paste ready but
it's lifted and munged from an active system. ASPX might need a quick
wrangle, but it looks good to my untrained eye.

cheers,

Flinky Wisty Pomm

--- code--

//
// this code is lifted from TwoHeadedGridView by Matt Dotson,
// license and other code is available @
//
http://www.gotdotnet.com/workspaces....aspx?id=1ecb6d2e-a104-48f7-a8fb-1622eba20852
// I'm using this because it's a simpler form of my grid and has the
same problem

//#################################
// TwoHeadedGridView.cs
//#################################
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Drawing;

namespace RealWorld.Grids
{
public class TwoHeadedGridView : GridView
{
public string HeaderText
{
get
{
object val = this.ViewState["HeaderText"];
if (null == val)
{
return String.Empty;
}

return (String)val;
}
set
{
this.ViewState["HeaderText"] = value;
}
}

protected Table InnerTable
{
get
{
if (this.HasControls())
{
return (Table)this.Controls[0];
}

return null;
}
}

protected override void OnDataBound(EventArgs e)
{
base.OnDataBound(e);
this.CreateSecondHeader();
}

private void CreateSecondHeader()
{
GridViewRow row = new GridViewRow(0, -1,
DataControlRowType.Header, DataControlRowState.Normal);
TableCell th = new TableHeaderCell();

th.HorizontalAlign = HorizontalAlign.Center;
th.ColumnSpan = this.Columns.Count;
th.BackColor = Color.SteelBlue;
th.ForeColor = Color.White;
th.Font.Bold = true;
th.Text = this.HeaderText;
row.Cells.Add(th);

this.InnerTable.Rows.AddAt(0, row);
}
}
}



// #####################################
// GridTest.cs
// #####################################

using System;
using System.Collections.Generic;
using System.Web.UI;

using RealWorld.Grids;

namespace Pages
{
public class GridTest : Page
{
protected TwoHeadedGridView testgrid;

protected void Page_Load()
{
if(!IsPostBack)
BindGrid();
}

private void BindGrid()
{
Dictionary<string,string> data = new
Dictionary<string,string>(8);

data.Add("123","abc");
data.Add("fred","fredder");
data.Add("bing","bong");
data.Add("foo","bar");
data.Add("baz","quux");
data.Add("oogle","fooble");
data.Add("boogle","zork");
data.Add("quuux","quuuux");
data.Add("spam","eggs");

testgrid.DataSource = data;
testgrid.DataBind();
}

protected void BindButtonClicked(object sender, EventArgs e)
{
BindGrid();
}

}
}


// #########################
// GridTest.aspx
// #########################
<%@ Page language="c#" EnableViewState="true" Inherits="Pages.GridTest"
MasterPageFile="~/MasterPages/Agenda.Master"%>
<%@ Register TagPrefix="RealGrid" Namespace="RealWorld.Grids"
Assembly="Cogentic.DSMSWeb.Core.Controls" %>

<html>
<head></head>
<body>
<form runat="server">

<RealGrid:TwoHeadedGridView runat="server" id="testgrid"
HeaderText="Fred" />

<asp:Button id="btnRefresh" Text="Postback, no databind"
runat="server" />
<asp:Button id="btnBind" Text="Postback, rebind"
onclick="BindButtonClicked" runat="server" />

</form>
</body>
</html>
 
T

Teemu Keiski

Hi,

perhaps you could utilize same idea that I've used in one of my GridView
samples as I add grouping rows into the GridView (when GridView renders).
Same idea applies, you are just adding the first and last row where I am
adding the grouping headers

GridView Sort Grouping
http://aspadvice.com/blogs/joteke/archive/2006/02/11/15130.aspx

--
Teemu Keiski
ASP.NET MVP, AspInsider
Finland, EU
http://blogs.aspadvice.com/joteke


Flinky Wisty Pomm said:
Hi all, I've got a really annoying problem that I need to fix sharpish.

I've got a GridView derived control which has a templated header and
footer. It works wonderfully on the first render but then the
header/footer vanish into thin air. If I add the header/footer
onDataBound then they disappear when I do a postback with no
databinding. If I add them during PreRender, then they persist, but one
of my data rows is emptied for each time I postback.

It feels like there's a rowIndex being kicked out of place, but I've
run reflector over CreateChildControls and given up all hope of
understanding it in the next week. Can anyone offer some help?

test code is below, apologies if it's not quite cut/paste ready but
it's lifted and munged from an active system. ASPX might need a quick
wrangle, but it looks good to my untrained eye.

cheers,

Flinky Wisty Pomm

--- code--

//
// this code is lifted from TwoHeadedGridView by Matt Dotson,
// license and other code is available @
//
http://www.gotdotnet.com/workspaces....aspx?id=1ecb6d2e-a104-48f7-a8fb-1622eba20852
// I'm using this because it's a simpler form of my grid and has the
same problem

//#################################
// TwoHeadedGridView.cs
//#################################
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Drawing;

namespace RealWorld.Grids
{
public class TwoHeadedGridView : GridView
{
public string HeaderText
{
get
{
object val = this.ViewState["HeaderText"];
if (null == val)
{
return String.Empty;
}

return (String)val;
}
set
{
this.ViewState["HeaderText"] = value;
}
}

protected Table InnerTable
{
get
{
if (this.HasControls())
{
return (Table)this.Controls[0];
}

return null;
}
}

protected override void OnDataBound(EventArgs e)
{
base.OnDataBound(e);
this.CreateSecondHeader();
}

private void CreateSecondHeader()
{
GridViewRow row = new GridViewRow(0, -1,
DataControlRowType.Header, DataControlRowState.Normal);
TableCell th = new TableHeaderCell();

th.HorizontalAlign = HorizontalAlign.Center;
th.ColumnSpan = this.Columns.Count;
th.BackColor = Color.SteelBlue;
th.ForeColor = Color.White;
th.Font.Bold = true;
th.Text = this.HeaderText;
row.Cells.Add(th);

this.InnerTable.Rows.AddAt(0, row);
}
}
}



// #####################################
// GridTest.cs
// #####################################

using System;
using System.Collections.Generic;
using System.Web.UI;

using RealWorld.Grids;

namespace Pages
{
public class GridTest : Page
{
protected TwoHeadedGridView testgrid;

protected void Page_Load()
{
if(!IsPostBack)
BindGrid();
}

private void BindGrid()
{
Dictionary<string,string> data = new
Dictionary<string,string>(8);

data.Add("123","abc");
data.Add("fred","fredder");
data.Add("bing","bong");
data.Add("foo","bar");
data.Add("baz","quux");
data.Add("oogle","fooble");
data.Add("boogle","zork");
data.Add("quuux","quuuux");
data.Add("spam","eggs");

testgrid.DataSource = data;
testgrid.DataBind();
}

protected void BindButtonClicked(object sender, EventArgs e)
{
BindGrid();
}

}
}


// #########################
// GridTest.aspx
// #########################
<%@ Page language="c#" EnableViewState="true" Inherits="Pages.GridTest"
MasterPageFile="~/MasterPages/Agenda.Master"%>
<%@ Register TagPrefix="RealGrid" Namespace="RealWorld.Grids"
Assembly="Cogentic.DSMSWeb.Core.Controls" %>

<html>
<head></head>
<body>
<form runat="server">

<RealGrid:TwoHeadedGridView runat="server" id="testgrid"
HeaderText="Fred" />

<asp:Button id="btnRefresh" Text="Postback, no databind"
runat="server" />
<asp:Button id="btnBind" Text="Postback, rebind"
onclick="BindButtonClicked" runat="server" />

</form>
</body>
</html>
 
F

Flinky Wisty Pomm

Okay, I can add rows when the table renders, and obviously that works -
but I've got an ITemplate for my header/footer so I can add buttons,
links etc.

These need to be added during init or I can't fire server side events
from them. All the methods I want to get hold of in order to do that
are private - so I think I'm back to hunting for workarounds.

I can add the controls directly to the controlcollection of the
gridview and they appear in the right places, but they disappear
again... GAH! I'm beginning to think this is impossible.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top