即使在GridView位于表单标签之后,GridView也必须放置在runat =“server”的表单标签内
<form runat="server" id="f1"> <div runat="server" id="d"> grid view: <asp:GridView runat="server" ID="g"> </asp:GridView> </div> <asp:TextBox runat="server" ID="t" TextMode="MultiLine" Rows="20" Columns="50"></asp:TextBox> </form>
代码后面:
public partial class ScriptTest : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { g.DataSource = new string[] { "a", "b", "c" }; g.DataBind(); TextWriter tw = new StringWriter(); HtmlTextWriter h = new HtmlTextWriter(tw); d.RenderControl(h); t.Text = tw.ToString(); } }
即使GridView是在一个从runat =“服务器”标签,仍然是我得到这个错误。
有什么线索吗?
您正在调用GridView.RenderControl(htmlTextWriter)
,因此页面引发了一个exception,Server-Control被呈现在Form外部。
你可以通过重写VerifyRenderingInServerForm来避免这个错误
public override void VerifyRenderingInServerForm(Control control) { /* Confirms that an HtmlForm control is rendered for the specified ASP.NET server control at run time. */ }
看到这里和这里 。
重写VerifyRenderingInServerForm的替代方法是在执行渲染时从控件集合中删除网格,然后在加载页面之前完成添加。 如果你想有一些通用的帮助器方法来获取网格html,这是有帮助的,因为你不必记得添加覆盖。
Control parent = grid.Parent; int GridIndex = 0; if (parent != null) { GridIndex = parent.Controls.IndexOf(grid); parent.Controls.Remove(grid); } grid.RenderControl(hw); if (parent != null) { parent.Controls.AddAt(GridIndex, grid); }
避免重写的另一种方法是这样做:
grid.RenderBeginTag(hw); grid.HeaderRow.RenderControl(hw); foreach (GridViewRow row in grid.Rows) { row.RenderControl(hw); } grid.FooterRow.RenderControl(hw); grid.RenderEndTag(hw);
在你的Page_Load之后添加这个:
public override void VerifyRenderingInServerForm(Control control) { //base.VerifyRenderingInServerForm(control); }
请注意,我没有做任何事情的function。
编辑: 蒂姆回答同样的事情。 :)你也可以在这里find答案
只是想添加另一种方式来做到这一点。 我已经看到多个相关的线程上的人问你是否可以使用VerifyRenderingInServerForm而不添加到父页面。
你其实可以做到这一点,但这是一个闪光点。
首先创build一个新的Page类,如下所示:
public partial class NoRenderPage : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } public override void VerifyRenderingInServerForm(Control control) { //Allows for printing } public override bool EnableEventValidation { get { return false; } set { /*Do nothing*/ } } }
不需要有一个.ASPX与它关联。
然后在你想渲染的控件中,你可以做如下的事情。
StringWriter tw = new StringWriter(); HtmlTextWriter hw = new HtmlTextWriter(tw); var page = new NoRenderPage(); page.DesignerInitialize(); var form = new HtmlForm(); page.Controls.Add(form); form.Controls.Add(pnl); controlToRender.RenderControl(hw);
现在,您已经将原始控件呈现为HTML。 如果需要,请将控制权重新添加到原始位置。 您现在已经呈现了HTML,页面正常并且没有对页面本身的更改。
这是我的代码
protected void btnExcel_Click(object sender, ImageClickEventArgs e) { if (gvDetail.Rows.Count > 0) { System.IO.StringWriter stringWrite1 = new System.IO.StringWriter(); System.Web.UI.HtmlTextWriter htmlWrite1 = new HtmlTextWriter(stringWrite1); gvDetail.RenderControl(htmlWrite1); gvDetail.AllowPaging = false; Search(); sh.ExportToExcel(gvDetail, "Report"); } } public override void VerifyRenderingInServerForm(Control control) { /* Confirms that an HtmlForm control is rendered for the specified ASP.NET server control at run time. */ }