Reputation: 14753
I am creating a GridView in a method like so:
GridView gridView = new GridView();
gridView.DataSource = reportData.Tables[0];
gridView.DataBind();
I am later exporting it to Excel and it works great. The columns are being auto-generated from my source data. I would like to change the DataFormatString property of some of the columns however after I databind and before I export to Excel. I can't seem to find the correct property to change. Can anybody point me in the right direction?
Upvotes: 5
Views: 17609
Reputation: 138147
According to AutoGenerateColumns documentation:
This option provides a convenient way to display every field in the data source; however, you have limited control of how an automatically generated column field is displayed or behaves.
Note: Automatically generated bound column fields are not added to the Columns collection.
I tired looking for these AutoGeneratedField
s with no luck.
I can think of several options to achieve that (from worst to best):
RowDataBound
), this will give you access to the rows' cells, but isn't too convenient.Don't use AutoGeneratedField
Create these columns manually, as in:
BoundField dateField = new BoundField();
dateField.HeaderText = "Date";
dateField.DataField = "date";
dateField.DataFormatString = "{0:MMMM, yyyy}";
gridView.Columns.Add(dateField);
This options gives you bes control over titles.
List<Employee)
), and AutoGeneratedField
turns them into columns.And, as a last note, you should think about creating Excel files by using the API. It's not as easy, but HTML XLS files are less compatible with Excel 2007 - it displays a warning message that the format of the file is incompatible with the extension, and worse, the file brakes if it is opened and saves (can be Save As
though), making your files less user-friendly.
Upvotes: 7
Reputation: 25359
Here's an extract from a GridView exporter I wrote that converts controls in a GridView into literals that are re-formated. It might be of some help:
/// <summary>
/// Parses and cleans up data from the GridView controls collection
/// to make the data more suitable for Exported
/// </summary>
/// <param name="gv">The GridView to parse</param>
private void CleanUpControls(Control gv)
{
Literal l = new Literal();
for (int i = 0; i < gv.Controls.Count; i++)
{
if (gv.Controls[i].GetType() == typeof (LinkButton))
{
l.Text = (gv.Controls[i] as LinkButton).Text;
ReplaceWithLiteral(gv, l, i);
}
else if (gv.Controls[i].GetType() == typeof (ListControl))
{
l.Text = (gv.Controls[i] as ListControl).SelectedItem.Text;
ReplaceWithLiteral(gv, l, i);
}
else if (gv.Controls[i].GetType() == typeof (CheckBox))
{
l.Text = (gv.Controls[i] as CheckBox).Checked ? "True" : "False";
ReplaceWithLiteral(gv, l, i);
}
else if (gv.Controls[i].GetType() == typeof (BooleanImage))
{
l.Text = (gv.Controls[i] as BooleanImage).Value ? "True" : "False";
ReplaceWithLiteral(gv, l, i);
}
else if (gv.Controls[i].GetType().ToString() == "System.Web.UI.WebControls.PagerTable")
ReplaceWithLiteral(gv, l, i);
else if (gv.Controls[i].GetType() == typeof (HyperLink))
{
HyperLink hl = gv.Controls[i] as HyperLink;
if (MakeHyperLinksAbsolute)
{
if (hl != null)
hl.NavigateUrl = UrlHelper.MakeAbsoluteUrl(hl.NavigateUrl);
}
switch (TreatHyperLinksAs)
{
case HyperLinkMode.Text:
l.Text = hl.Text;
ReplaceWithLiteral(gv, l, i);
break;
case HyperLinkMode.NavigateUrl:
if (hl != null) l.Text = hl.NavigateUrl;
ReplaceWithLiteral(gv, l, i);
break;
case HyperLinkMode.ToolTip:
l.Text = hl.ToolTip;
ReplaceWithLiteral(gv, l, i);
break;
case HyperLinkMode.TextAndLink:
l.Text = String.Format("{0} ({1})", hl.Text, hl.NavigateUrl);
ReplaceWithLiteral(gv, l, i);
break;
case HyperLinkMode.HyperLink:
break;
}
}
if (gv.Controls[i].HasControls())
CleanUpControls(gv.Controls[i]);
}
}
Upvotes: -1
Reputation: 91359
For example:
String newDataFormatString = "{0:d}";
BoundField bf = gridView.Columns[Index] as BoundField;
if (bf != null) {
bf.DataFormatString = "{0}"; // workaround to sync with ViewState (it's documented)
bf.DataFormatString = newDataFormatString;
}
Upvotes: 0
Reputation: 2950
This is the issue of how asp.net works. When you create some controls (columns) in a method and set this controls set to user, the next time user post backs data to you, you do not have access to those columns since they … do not exists. Every time you display your site, a brand new object (instance) is created.
The only way to be able to get data in post back from previously created controls is to create controls in Page_Init method…
Upvotes: -1