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