web-dev-qa-db-fra.com

GridView doit être placé dans une balise de formulaire avec runat = "server" même après que GridView se trouve dans une balise de formulaire

<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>

Code derrière:

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();
    }
}

Même le GridView est dans une balise from avec runat = "server", je reçois toujours cette erreur.

Des indices s'il vous plaît?

81
teenup

Vous appelez GridView.RenderControl(htmlTextWriter), la page lève une exception selon laquelle un contrôle de serveur a été rendu en dehors d'un formulaire.

Vous pouvez éviter cette exécution en surchargeant VerifyRenderingInServerForm

public override void VerifyRenderingInServerForm(Control control)
{
  /* Confirms that an HtmlForm control is rendered for the specified ASP.NET
     server control at run time. */
}

Voir ici et ici .

160
Tim Schmelter

Une alternative à la substitution de VerifyRenderingInServerForm consiste à supprimer la grille de la collection de contrôles pendant le rendu, puis à la rajouter lorsque vous avez terminé avant le chargement de la page. Ceci est utile si vous voulez avoir une méthode d'assistance générique pour obtenir le code HTML de la grille, car vous n'avez pas à vous souvenir d'ajouter le remplacement.

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);
}

Une autre alternative pour éviter le contournement est la suivante:

grid.RenderBeginTag(hw);
grid.HeaderRow.RenderControl(hw);
foreach (GridViewRow row in grid.Rows)
{
    row.RenderControl(hw);
}
grid.FooterRow.RenderControl(hw);
grid.RenderEndTag(hw);
27
Chris Mullins

Juste après votre Page_Load, ajoutez ceci:

public override void VerifyRenderingInServerForm(Control control)
{
    //base.VerifyRenderingInServerForm(control);
}

Notez que je ne fais rien dans la fonction.

EDIT: Tim a répondu à la même chose. :) Vous pouvez également trouver la réponse Ici

13
Ivan Nikolov

Je veux juste ajouter une autre façon de faire cela. J'ai vu plusieurs personnes sur différents threads liés vous demander si vous pouvez utiliser VerifyRenderingInServerForm sans l'ajouter à la page parent.

En fait, vous pouvez le faire, mais c’est un peu une bodge.

Commencez par créer une nouvelle classe de page ressemblant à ceci:

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*/ }
    }
}

Il n’est pas nécessaire d’avoir un fichier .ASPX associé.

Ensuite, dans le contrôle que vous souhaitez afficher, vous pouvez effectuer les opérations suivantes.

    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);

Vous avez maintenant votre contrôle original rendu en HTML. Si vous en avez besoin, rajoutez le contrôle dans sa position d'origine. Vous avez maintenant le rendu HTML, la page en tant que normale et aucune modification de la page elle-même.

2
Daniel Edwards

Voici mon code

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. */
    }
1
vipin