Unable to Export the Dynamically added row to Gridview to Excel - c#

I have tried Exporting GridView to Excel but observed that
the Dynamically added last Row to Gridview is not exported to excel.
I have two datasets first one binds the data directly to Gridview.
After Which I add the last row from another DataSet.
In the page I'm able to see the result as Expected but when exported excel I'm not.
Below is my code:
DataSet dsgrid = SqlHelper.ExecuteDataset(DBConnectionString.ConnectionString, CommandType.StoredProcedure, "usp_Training_GetCirclescoreCardReport ", sqlparam);
if (TrainingUtil.isDataSetValid(dsgrid))
{
RSGScoreCard_Grid.DataSource = dsgrid;
RSGScoreCard_Grid.DataBind();
AddOverallRow(dsgrid);
}
else RSGScoreCard_Grid.DataBind();
Adding Overall row at bottom:
#region Add OverallRow
private void AddOverallRow(DataSet dsgrid)
{
using (GridViewRow gr = new GridViewRow(RSGScoreCard_Grid.Rows.Count + 1, 0, DataControlRowType.DataRow, DataControlRowState.Normal))
{
for (int i = 0; i < 6; i++)//6 is the column count for overall row
{
using (TableCell tc = new TableCell())
{
gr.Cells.Add(tc);
if (i == 0)
{
gr.Cells[i].ColumnSpan = 4;
gr.Cells[i].Text = "Overall";
gr.Cells[i].Attributes.Add("class", "fcol");
gr.Cells[i].Attributes.Add("style", "font-weight:bold;padding-left:20%");
}
else gr.Cells[i].Attributes.Add("style", "font-weight:bold");
}
}
if (dsgrid.Tables[1] != null)//creating a dynamic row to gridview
if (dsgrid.Tables[1].Rows.Count > 0)
{
gr.Cells[1].Text = dsgrid.Tables[1].Rows[0][5].ToString();
gr.Cells[1].Width = Unit.Percentage(8);
gr.Cells[2].Text = dsgrid.Tables[1].Rows[0][6].ToString();
gr.Cells[2].Width = Unit.Percentage(8);
gr.Cells[3].Text = dsgrid.Tables[1].Rows[0][7].ToString();
gr.Cells[3].Width = Unit.Percentage(8);
gr.Cells[4].Text = dsgrid.Tables[1].Rows[0][8].ToString();
gr.Cells[4].Width = Unit.Percentage(8);
gr.Cells[5].Text = dsgrid.Tables[1].Rows[0][9].ToString();
gr.Cells[5].Width = Unit.Percentage(8);
}
gr.Attributes.Add("class", "row2");
RSGScoreCard_Grid.Controls[0].Controls.AddAt(RSGScoreCard_Grid.Rows.Count + 1, gr);
}
}
#endregion
and Last my code to Export the GrieView:
protected void btnExport_Click(object sender, EventArgs e)
{
TrainingUtil.Export(ddlOptions.SelectedItem.Text.ToString().Replace(" ", string.Empty) + "_" + ddlVerticals.SelectedItem.Text.ToString().Replace(" ", string.Empty) + "_" + ddlLernerGroups.SelectedItem.Text.ToString().Replace(" ", string.Empty), RSGScoreCard_Grid, "For the Month/Year: " + ddlFromMonths.SelectedItem.Text.ToString()+"/"+ddlYears.SelectedItem.Text.ToString(), RSGScoreCard_Grid.HeaderRow.Cells.Count);
}
public override void VerifyRenderingInServerForm(Control control)
{
/* Confirms that an HtmlForm control is rendered for the specified ASP.NET
server control at run time. */
}
the Export Method in TrainingUtil class
#region Export
public static void Export(string filename, GridView grid, string Heading, int ColumnsCount)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", filename + ".xls"));
HttpContext.Current.Response.ContentType = "application/ms-excel";
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
grid.HeaderStyle.BackColor = System.Drawing.Color.Cyan;
//Cells color settings
GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
TableCell cell = new TableCell();
cell.Text = String.Format("{0}", Heading);
cell.ColumnSpan = ColumnsCount;
cell.Attributes.Add("align", "center");
cell.Attributes.Add("class", "yellow");
row.Cells.Add(cell);
grid.Controls[0].Controls.AddAt(0, row);
foreach (GridViewRow gridRow in grid.Rows)
{
foreach (TableCell tcGridCells in gridRow.Cells)
{
tcGridCells.Attributes.Add("class", "sborder");
}
}
grid.RenderControl(htw);
//Add the style sheet class here
HttpContext.Current.Response.Write(#"<style> .sborder { color : Black;border : 1px Solid Black; } .yellow {background-color:yellow;color:black;} </style> ");
HttpContext.Current.Response.Write(sw.ToString());
HttpContext.Current.Response.End();
}
}
}
#endregion
Can any help me out.Why I'm not able to export the last row.
Thanks in advance

I think in every post back your not binding the dynamically added rows.
Try to find the control which cause the postback and bind the data once again.
Code to find the postback control ex:-
public static Control GetPostBackControl(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
}
}
return control;
}

Related

ImageButton not firing on the second time

In my ASP.Net page I need to show an HTML div who contains : Images, Text, Arrows and Connectors.
What are my "Connectors" ?
It's an ImageButton, and when the user click on this connector, the HTML div is showing a new content. This connectors are used to navigate in a TreeView.
But my problem is :
I create all my connectors (and all the HTML div content) dynamically. When the user click on the first connector the HTML div is showing new content. But on this second content, when the user click on a connector : nothing. The Click event of the ImageButton is not fired.
This is my Connector creation (on PageLoad and then on each Connector Click) :
List<Connecteur> ListConnecteur = new List<Connecteur>();
ListConnecteur = NomenclatureObj.SelectConnecteurs(DocId, ExterneData.RapidoBDDCnx);
foreach (Connecteur CeConnecteur in ListConnecteur)
{
if (CeConnecteur.FK_docversion_suivant_id != 0)
{
ImageButton ImgBtnTmp = new ImageButton();
ImgBtnTmp.Width = 30;
ImgBtnTmp.Height = 30;
ImgBtnTmp.ImageUrl = "~/images/GreenButton.png";
ImgBtnTmp.Style.Add("left", CeConnecteur.position_x_pix.ToString() + "px");
ImgBtnTmp.Style.Add("top", CeConnecteur.position_y_pix.ToString() + "px");
ImgBtnTmp.Click += new ImageClickEventHandler(ImgBtnTmp_Click);
ImgBtnTmp.CommandArgument = CeConnecteur.FK_docversion_suivant_id.ToString();
ImgBtnTmp.Style.Add("position", "absolute");
DivAffichage.Controls.Add(ImgBtnTmp);
ImgBtnTmp.CausesValidation = true;
}
}
And this is my Connector OnClick :
public void ImgBtnTmp_Click(object sender, EventArgs e)
{
ImageButton ThisBtn = sender as ImageButton;
string CommandArg = ThisBtn.CommandArgument;
int DocId = Convert.ToInt32(CommandArg);
TREEVIEW_NIVEAU++;
//DocId of the clicked connector
Session["DocId"] = DocId;
ClearDiv();
LoadDiv(DocId);
}
EDIT 1 : My whole LoadDiv() function
public void LoadDiv(int DocId)
{
#region Connecteurs
List<Connecteur> ListConnecteur = new List<Connecteur>();
ListConnecteur = NomenclatureObj.SelectConnecteurs(DocId, ExterneData.RapidoBDDCnx);
foreach (Connecteur CeConnecteur in ListConnecteur)
{
if (CeConnecteur.FK_docversion_suivant_id != 0)
{
ImageButton ImgBtnTmp = new ImageButton();
ImgBtnTmp.Width = 30;
ImgBtnTmp.Height = 30;
ImgBtnTmp.ImageUrl = "~/images/GreenButton.png";
ImgBtnTmp.Style.Add("left", CeConnecteur.position_x_pix.ToString() + "px");
ImgBtnTmp.Style.Add("top", CeConnecteur.position_y_pix.ToString() + "px");
ImgBtnTmp.Click += new ImageClickEventHandler(ImgBtnTmp_Click);
ImgBtnTmp.CommandArgument = CeConnecteur.FK_docversion_suivant_id.ToString();
ImgBtnTmp.Style.Add("position", "absolute");
DivAffichage.Controls.Add(ImgBtnTmp);
}
}
#endregion
#region Textes
List<Texte> ListTexte = new List<Texte>();
ListTexte = NomenclatureObj.SelectTextes(DocId, LANGUE_ID, ExterneData.RapidoBDDCnx);
foreach (Texte CeTexte in ListTexte)
{
Label LblText = new Label();
LblText.Text = CeTexte.contenu;
LblText.Width = CeTexte.largeur_voulue_pix;
LblText.Style.Add("left", CeTexte.position_x_pix.ToString() + "px");
LblText.Style.Add("top", CeTexte.position_y_pix.ToString() + "px");
LblText.Style.Add("position", "absolute");
DivAffichage.Controls.Add(LblText);
}
#endregion
#region Images
List<ImageNomenclature> ListImg = new List<ImageNomenclature>();
ListImg = NomenclatureObj.SelectImages(DocId, ExterneData.RapidoBDDCnx);
foreach (ImageNomenclature CetteImage in ListImg)
{
Image ImgTmp = new Image();
ImgTmp.ImageUrl = "~/Nomenclature/RAPIDO/planches/" + CetteImage.fichier_chemin;
ImgTmp.Width = CetteImage.largeur_voulue_pix;
ImgTmp.Height = CetteImage.hauteur_voulue_pix;
ImgTmp.Style.Add("left", CetteImage.position_x_pix.ToString() + "px");
ImgTmp.Style.Add("top", CetteImage.position_y_pix.ToString() + "px");
ImgTmp.Style.Add("position", "absolute");
ImgTmp.Style.Add("z-index", "-1");
DivAffichage.Controls.Add(ImgTmp);
}
#endregion
#region Flèches
List<Fleche> ListFleche = new List<Fleche>();
ListFleche = NomenclatureObj.SelectFleches(DocId, LANGUE_ID, ExterneData.RapidoBDDCnx);
foreach (Fleche CetteFleche in ListFleche)
{
string HTMLCode = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"800\" height=\"600\"><line x1=\"" + CetteFleche.position_x1_pix + "\" y1=\"" + CetteFleche.position_y1_pix + "\" x2=\"" + CetteFleche.position_x2_pix + "\" y2=\"" + CetteFleche.position_y2_pix + "\" stroke=\"#ff0000\"/></svg>";
//DivAffichage.InnerHtml += HTMLCode;
}
#endregion
}
You should create your dynamic control every time on Page_Init or Page_Load if you would like to handle events from them after Postback.
See links below for details:
http://msdn.microsoft.com/en-us/library/y3bwdsh3%28v=vs.140%29.aspx
http://msdn.microsoft.com/en-us/library/hbdfdyh7%28v=vs.100%29.aspx
Here you can see the same problem.
EDIT
Try to do something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
LoadDiv(Session["DocId"])
}
}

I want to add an image to a specific cell in my table within my aspx class

I want to add an image to a particular cell in a table within my aspx class. Right now I have an if statement which changes the colour of the cell, I want another if statement which adds an image to that same cell. Any ideas how to do this?
public partial class FutureDelivery : System.Web.Mvc.ViewPage
{
protected void Page_Load(object sender, EventArgs e)
{
// Response.Cache.SetCacheability(HttpCacheability.NoCache);
errormsg.Text = "";
FutureDeliveryModel theModel = (FutureDeliveryModel)ViewData["FutureDelivery"];
// litSite.Text = Site.getSite();
//DataTable StockTable = (DataTable)ViewData["Future"];
DataTable StockTable = theModel.GetFuture();
DataView StockView = StockTable.DefaultView;
StringBuilder SB = new StringBuilder();
SB.Append("<table class=\"display\" id=\"dt\" style=\"align: left; width: 99%;\" ");
SB.Append("rules=\"all\" border=\"1px\" ");
SB.Append("cellspacing=\"0px\" cellpadding=\"4px\">");
SB.Append("<thead>");
SB.Append("<tr></tr>");
SB.Append("<tr style=\"background-color: Silver; color: #212121; ");
SB.Append("font-weight: bold\">");
// Header
foreach (DataColumn aColumn in StockTable.Columns)
{
SB.Append("<td>");
SB.Append(aColumn.ColumnName);
SB.Append("</td>");
}
SB.Append("</tr>");
SB.Append("</thead>");
SB.Append("<tbody>");
string Site = " ";
//detail
foreach (DataRowView aRowView in StockView)
{
int qty = 0;
int export = 0;
SB.Append("<tr>");
foreach (DataColumn aColumn in StockTable.Columns)
{
SB.Append("<td style=\"text-align: left\"");
if (aColumn.ColumnName.ToString().Equals("Site"))
{
// SB.Append("<a href=\"");
// SB.Append(ApplicationUtility.FormatURL("/Stock/FutureDelivery"));
// SB.Append("?Site=");
SB.Append(">");
Site = aRowView["Site"].ToString();
SB.Append(Site);
// SB.Append(aRowView[aColumn.ColumnName].ToString());
// SB.Append("</a>");
}
else
{
if (aColumn.ColumnName.ToString().Equals("Quantity")) qty = Convert.ToInt32(aRowView["Quantity"].ToString());
if (aColumn.ColumnName.ToString().Equals("Export Quantity"))
{
export = Convert.ToInt32(aRowView["Export Quantity"].ToString());
if (export != qty && export != 0) SB.Append(" BGCOLOR=\"#00ff00\" ");
}
SB.Append(">");
if (aColumn.ColumnName.ToString().Equals("Export Quantity"))
{
if (export == 0)
{
SB.Append(" ");
}
else
{
SB.Append(aRowView[aColumn.ColumnName].ToString());
}
}
else
{
SB.Append(aRowView[aColumn.ColumnName].ToString());
}
}
SB.Append("</td>");
}
SB.Append("</tr>");
}
SB.Append("</tbody>");
SB.Append("</table>");
litFutureDeliveryDetail.Text = SB.ToString();
linkBackToMainPage.NavigateUrl = ApplicationUtility.FormatURL("/Stock/Login?action=out");
linkBack.NavigateUrl = (String)Session["BACKURL"];
linkUserMaint.NavigateUrl = ApplicationUtility.FormatURL("/Stock/UserMaint");
screentitle.Text = "Future Deliveries";
if (theModel.GetErrorMessage().Trim() != "")
{
StringBuilder ES = new StringBuilder();
ES.Append("<table border=1><tr><td class=\"ErrorText\">");
ES.Append(theModel.GetErrorMessage().ToString());
ES.Append("</td></tr></table>");
errormsg.Text = ES.ToString();
}
else
{
errormsg.Text = " ";
}
}
}
}
May be you simply need a string append like follows,
if(condition){
sb.Append("<img src=\"images/pic.jpg\" alt=\"Sample Photo\" />");
}
Where images/pic.jpg is the path to image.

Exporting GridView to Excel without gridview cells with hyperlinks showing red

I have an ASP.Net 4.0 GridView and a button which exports the GridView data to Excel. This all works fine. However, within the GridView, the text in three cells of each row are red because they are hyperlinks. When I export the data to Excel, these cells are still red. I want them to be black. How do I do this? Here's my code:
Response.ClearContent();
Response.AppendHeader("content-disposition", "attachment; filename=Mobile.xls");
Response.ContentType = "application/excel";
StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
foreach (GridViewRow gridViewRow in gvResults.Rows)
{
gridViewRow.ForeColor = Color.Black;
foreach (TableCell gridViewRowTableCell in gridViewRow.Cells)
gridViewRowTableCell.Style["forecolor"] = "#000000";
if (gridViewRow.RowType == DataControlRowType.DataRow)
{
for (int columnIndex = 0; columnIndex < gridViewRow.Cells.Count; columnIndex++)
{
gridViewRow.Cells[columnIndex].Attributes.Add("class", "text");
}
}
}
gvResults.RenderControl(htmlTextWriter);
string style = #"<style> .text { mso-number-format:\#; } </style> ";
Response.Write(style);
Response.Write(stringWriter.ToString());
Response.End();
And here's the code for the links. This runs OnDataBound:
foreach (GridViewRow row in gvResults.Rows)
{
if (row.RowType == DataControlRowType.DataRow || row.RowType == DataControlRowType.EmptyDataRow)
{
string imei = row.Cells[0].Text;
if (imei != " ")
{
string imeiLink = "window.location='SmartphoneInventory.aspx?imei=" + imei + "';";
row.Cells[0].Attributes.Add("onClick", String.Format(imeiLink));
row.Cells[0].Text = "<span style='color:red'>" + row.Cells[0].Text + "</span>";
}
string phonenumber = row.Cells[1].Text;
if (phonenumber != " ")
{
string phonenumberLink = "window.location='SmartphoneInventory.aspx?phonenumber=" + phonenumber + "';";
row.Cells[1].Attributes.Add("onClick", String.Format(phonenumberLink));
row.Cells[1].Text = "<span style='color:red'>" + row.Cells[1].Text + "</span>";
}
int cellCount = row.Cells.Count;
string empName = row.Cells[cellCount - 1].Text;
if (empName != " ")
{
string empNameLink = "window.location='DevicesByEmployee.aspx?empName=" + empName + "';";
row.Cells[cellCount - 1].Attributes.Add("onClick", String.Format(empNameLink));
row.Cells[cellCount - 1].Text = "<span style='color:red'>" + row.Cells[cellCount - 1].Text + "</span>";
}
}
}
I guess what I need is how to re-style the span. Is this possible? The GridView autogenerates its columns.
Get the LinkButton Text, assign it to the GridView Cell Text and Remove control.
Here is ho I do it in the header:
C#
foreach (TableCell c in gv.HeaderRow.Cells) {
if (c.HasControls) {
c.Text = (c.Controls(0) as LinkButton).Text;
c.Controls.Clear();
}
}
VB.NET
For Each c As TableCell In gv.HeaderRow.Cells
If c.HasControls Then
c.Text = TryCast(c.Controls(0), LinkButton).Text
c.Controls.Clear()
End If
Next
EDIT:
Create an extension method:
C#
[Extension()]
public string StripTags(string html)
{
return Regex.Replace(html, "<.*?>", "");
}
VB.NET
<Extension> _
Public Function StripTags(html As String) As String
Return Regex.Replace(html, "<.*?>", "")
End Function
It will remove tags from your string, therefore your style. Use as follows:
foreach (GridViewRow gridViewRow in gvResults.Rows)
{
gridViewRow.ForeColor = Color.Black;
foreach (TableCell gridViewRowTableCell in gridViewRow.Cells)
gridViewRowTableCell.Style["forecolor"] = "#000000";
if (gridViewRow.RowType == DataControlRowType.DataRow)
{
for (int columnIndex = 0; columnIndex < gridViewRow.Cells.Count; columnIndex++)
{
gridViewRow.Cells[columnIndex].Text = gridViewRow.Cells[columnIndex].Text.StripTags();
}
}
}

MouseHover Event on DataGridView - Index Out of Range

I have a winforms application with a DataGridView, and have been trying to set up a MouseHover event which provides some more detailed information about the cell being hovered over.
My code is as follows:
private void dataCaseHistory_MouseHover(object sender, EventArgs e)
{
try
{
DataGridView grid = (DataGridView)sender;
Point clientPos = grid.PointToClient(Control.MousePosition);
DataGridViewCell cell = (DataGridViewCell)grid[clientPos.X, clientPos.Y];
int cellRow = cell.RowIndex;
int cellColumn = cell.ColumnIndex;
DataTable table = (DataTable)dataCaseHistory.DataSource;
int docColumn = table.Columns.IndexOf("Doc");
if (cellColumn == docColumn)
{
var varBundleID = table.Rows[cellRow]["BundleID"];
if (varBundleID != DBNull.Value && varBundleID != null)
{
int bundleID = (int)varBundleID;
cBundle bundle = new cBundle(bundleID);
string header = "Bundle: '" + bundle.Name + "'";
string body = "";
foreach (DataRow row in bundle.DocumentBundle.Rows)
{
int docID = (int)row["DocumentID"];
cDocument doc = new cDocument(docID);
body += doc.DocumentName + Environment.NewLine;
}
MessageBox.Show(body, header);
}
else
{
var varDocID = table.Rows[cellRow]["DocID"];
if (varDocID != DBNull.Value && varDocID != null)
{
int docID = (int)varDocID;
cDocument doc = new cDocument(docID);
string header = "Document";
string body = doc.DocumentName;
MessageBox.Show(body, header);
}
}
}
}
catch (Exception eX)
{
string eM = "Error occurred when Single Clicking a Document link in the History tab";
aError err = new aError(eX, eM);
MessageBox.Show(eX.Message, eM);
}
}
But I get an index out of range error as soon as the form loads and whenever I move my mouse. I've never used this event before, so I'd be most appreciative if someone could point out where I am going wrong.
The Item[] property which you access in this line of code:
DataGridViewCell cell = (DataGridViewCell)grid[clientPos.X, clientPos.Y];
is indexed by row and column not by screen coordinates, so your screen coordinates are probably much higher than the number of rows or columns in your grid, therefore causing IndexOutOfRange exception.
You should get the cell using the HitTestInfo class:
MouseEventArgs args = (MouseEventaArgs) e;
DataGridView.HitTestInfo hitTest = this.grid.HitTest(args.X, args.Y);
if (hitTest.Type == DataGridViewHitTestType.Cell)
{
DataGridViewCell cell = (DataGridViewCell)this.Grid[hitText.ColumnIndex, hitTest.RowIndex];
// execute business logic here
}

Exported CSV file is empty

I have this code which export data from GridView to csv. It works with other sites but not on this current one I've been developing.
The GridView is binded with DataTable in code behind. Following is the event that binds the fetch and bind the data to GridView.
private void bindGridView()
{
//Fetching data from DB goes here
myTable.Columns.Add("type", typeof(int));
myTable.Columns.Add("rate", typeof(int));
foreach (DataRow rows in myTable.Rows)
{
if (rows["dst"].ToString() == "1875")
{
rows["type"] = 1;
rows["rate"] = 500;
rows.AcceptChanges();
}
else if (rows["dst"].ToString() == "1876")
{
rows["type"] = 0;
rows["rate"] = 30;
rows.AcceptChanges();
}
}
gridViewData.DataSource = myTable;
gridViewData.AllowPaging = true;
gridViewData.PageSize = 10;
gridViewData.DataBind();
}
Following is the button click event to export data from GridView
protected void btnExportCDR_Click(object sender, EventArgs e)
{
if (gridViewData.Rows.Count == 0)
{
lblStatus.Text = "Data is empty. Can not export CDR. Please check your filtering dates.";
}
else
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=CDRMMCC_" + System.DateTime.Now.ToShortDateString() + ".csv");
Response.Charset = "";
Response.ContentType = "application/text";
bindGridView();
gridViewData.AllowPaging = false;
StringBuilder sb = new StringBuilder();
//I did a trace here, gridViewData.Columns.Count is 0. That's why it got skipped, I think.
for (int k = 0; k < gridViewData.Columns.Count; k++)
{
sb.Append(gridViewData.Columns[k].HeaderText + ",");
}
sb.Append("\r\n");
for (int i = 0; i < gridViewData.Rows.Count; i++)
{
for (int k = 0; k < gridViewData.Columns.Count; k++)
{
sb.Append(gridViewData.Rows[i].Cells[k].Text + ",");
}
sb.Append("\r\n");
}
Response.Output.Write(sb.ToString());
Response.Flush();
Response.End();
}
}
Please advice.
If you use the AutoGenerateColumns property of the GridView set to true the Columns collection will be empty. The MSDN documentation for this property says:
"Automatically generated bound column fields are not added to the Columns collection".
This is the reason your Columns collection is empty. As Henk Holterman pointed out use your DataTable directly to generate your CSV file.
An alternative approach would be to set the AutoGenerateColumns property to false and define the Columns explicitly.
In addition to Hans answer, you can use RenderControl of the GridView which reduces your work.
StringWriter strWriter = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(strWriter);
MyGridView.RenderControl(htmlWriter);
Response.Write(strWriter.ToString());

Categories