LA.Net
Reflexões sobre C#, .Net e programação em geral

Na versão 1.X do ASP.NET a obtenção do HTML de um controlo existente numa página implicava apenas o override do método VerifyRenderingInServerForm. Actualmente, podemos ainda ter que garantir que essa geração apenas é efectuada após o evento PreRender. A página seguinte ilustra o código necessário à obtenção do HTML de um controlo TextBox sempre que um utilizador clica num botão existente no formulário:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.IO" %>

<script runat="server">
    bool render = false;  
    void P(object sender, EventArgs args)
    {
        render = true;
    }

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

    protected override void OnPreRenderComplete(EventArgs e)
    {
        base.OnPreRenderComplete(e);

        if (render)
        {
            TextWriter str = new StringWriter();
            XhtmlTextWriter writer = new XhtmlTextWriter(str);
            string id = txt.ID;
            txt.ID = "HH"; //mudar ID antes
            txt.RenderControl(writer);
            lbl.Text = str.ToString();
            txt.ID = id;        }
    }
</script>
<html>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox runat="server" ID="txt" />
        <asp:Button runat="server" ID="bt" Text ="bt" OnClick="P" />
        <asp:Label runat="server" ID="lbl" />
    </div>
    </form>
</body>
</html>

Se quisermos, podemos ainda ir um pouco mais longe e construir o nosso próprio controlo que permite obter o HTML num evento anterior ao PreRender. Para tal, vamos por começar por construir uma nova classe:

namespace Test
{
    public class PageTextBox: TextBox
    {
        private bool _suspendPage = false;

        public override Page Page
        {
            get
            {
                if (!_suspendPage)
                {
                    return base.Page;
                }
                return null;
            }
            set
            {
               base.Page = value;
            }
        }
        public void SuspendPage(bool val)
        {
            _suspendPage = val;
        }     
    }
}

Em seguida, podemos construir a seguinte página:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.IO" %>
<%@ Register Namespace="Test" TagPrefix="LA" %>
<script runat="server">
    void P(object sender, EventArgs args)
    {
       TextWriter str = new StringWriter();
       XhtmlTextWriter writer = new XhtmlTextWriter(str);
       txt.ID = "HH"; //mudar ID antes
       txt.SuspendPage(true);
       txt.RenderControl(writer);
       txt.SuspendPage(false);
       lbl.Text = str.ToString();
       txt.ID = id;    }

</script>
<html>
<body>
    <form id="form1" runat="server">
    <div>
        <LA:PageTextBox runat="server" ID="txt" />
        <asp:Button runat="server" ID="bt" Text ="bt" OnClick="P" />
        <asp:Label runat="server" ID="lbl" />
    </div>
    </form>
</body>
</html>

O controlo personaliza apenas a propriedade Page já que esta é utilizada para efecutar as validações relacionadas com a localização do controlo. Para além de personalizarmos a propriedade, adicionámos um método responsável por suspender o retorno do valor normal da propriedade Page. Assim, sempre que quisermos obter o HTML temos de rodear a invocação do método RenderControl de dois métodos SuspendPage (o segundo método deve ser invocado de forma a garantir que o controlo disponibliza o comportamento normal nas restantes situações). Apesar desta última solução ser mais trabalhosa, permite-nos obter o HTML do controlo em qualquer instante do ciclo de vida do controlo. Uma última observação: foi necessário modificar o ID do controlo já que estamos a adicionar o seu HTML ao interior de uma Label apresentado na página (se não o fizermos vamos estar a modificar os dados obtidos durante o postback de forma não intencional).

posted on Friday, October 28, 2005 11:15 AM
Comments
Title  
Name  
Url
Box Code
Protected by FormShield
Comments