GridView必须放置在runat=";的表单标记内;服务器";即使在GridView位于表单标记内
本文关键字:GridView 表单 quot 于表单 runat 服务器 | 更新日期: 2023-09-27 17:59:10
<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="server"的from标记中,我仍然会收到这个错误。
有线索吗?
您正在调用GridView.RenderControl(htmlTextWriter)
,因此该页面引发一个异常,即服务器控件在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);
}
请注意,我在函数中不做任何事情。
编辑:蒂姆也回答了同样的问题。:(你也可以在这里找到答案
只想添加另一种方法。我在各种相关线程上看到很多人问你是否可以在不将VerifyRenderingInServerForm添加到父页面的情况下使用它。
你确实可以这样做,但这有点麻烦。
首先创建一个新的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. */
}
Tim Schmelter的回答对我帮助很大,但我还需要做一件事才能让它在我的aspx页面上运行。我正在使用此代码通过电子邮件发送嵌入的GridView控件(作为HTML(,以实现报表自动化。
除了添加覆盖子,我还必须在Me.HHandles.onunload中执行render((,否则我在RenderControl行上会出错。
Protected Sub Page_After_load(sender As Object, e As EventArgs) Handles Me.Unload
If runningScheduledReport Then
Dim stringBuilder As StringBuilder = New StringBuilder()
Dim stringWriter As System.IO.StringWriter = New System.IO.StringWriter(stringBuilder)
Dim htmlWriter As HtmlTextWriter = New HtmlTextWriter(stringWriter)
GridView1.RenderControl(htmlWriter)
Dim htmlcode As String = stringBuilder.ToString()
Func.SendEmail(Context.Request.QueryString("email").ToString, htmlcode, "Auto Report - Agent Efficiency", Nothing)
End If
End Sub