O artigo anterior introduziu os conceitos básicos de implementação de eventos de controle de servidor personalizados. Este artigo explicará como capturar eventos de retorno de chamada por meio de exemplos típicos.
1. Implemente a captura de eventos de postback.
Se um controle de servidor precisar capturar eventos de postback do cliente e quiser personalizar a lógica de processamento de eventos do lado do servidor para os eventos de postback, o controle deverá implementar a interface System.Web.UI.IPostBackEventHandler. A definição da interface está listada abaixo.
interface pública IPostBackEventHandler
{
void RaisePostBackEvent(string eventArgument);
}
Conforme mostrado no código acima, a interface IPostBackEventHandler inclui apenas um método membro RaisePostBackEvent. Este método permite que o controle do servidor manipule eventos gerados quando o formulário é enviado ao servidor. Seu parâmetro eventArgument representa os parâmetros de evento opcionais a serem passados para o manipulador de eventos. Os desenvolvedores podem implementar a lógica executada durante o processo de postback de controle do servidor no método RaisePostBackEvent. Normalmente, o método RaisePostBackEvent gerará um ou mais eventos do lado do servidor. O trecho de código a seguir mostra a implementação de RaisePostBackEvent que gera o evento Click no servidor.
public void RaisePostBackEvent(String eventArgument)
{
OnClick(EventArgs.Empty);
}
Para conseguir capturar eventos de postback, não basta apenas fazer com que a classe de controle do servidor implemente a interface IPostBackEventHandler e implemente os métodos membros desta interface. Os desenvolvedores também precisam prestar atenção na implementação de outras coisas. Listados abaixo estão três pontos-chave no processo de captura de eventos de postback.
Primeiro, e mais importante, a classe de controle de servidor customizada deve implementar a interface IPostBackEventHandler e implementar o método RaisePostBackEvent do membro da interface. Este processo foi descrito acima.
Segundo, atribua um UniqueID ao controle.
Definir o valor do atributo name do controle que faz com que o evento de postback seja UniqueID é uma das chaves para implementar corretamente o método RaisePostBackEvent. Quando um postback é acionado, a estrutura da página procura o conteúdo que está sendo enviado e determina se o nome do objeto de envio corresponde ao UniqueID do controle de servidor que implementa IPostBackEventHandler. Se for correspondente, a estrutura da página chamará o método RaisePostBackEvent no controle. O ponto principal aqui é que os desenvolvedores precisam atribuir UniqueID ao atributo name do controle na lógica de renderização. Um exemplo de código simples está listado abaixo.
substituição protegida void Render (saída HtmlTextWriter)
{
output.Write("<INPUT TYPE=submit name="+this.UniqueID+"Value='Clique em mim' />");
}
Conforme mostrado no código acima, no método de renderização de controle Render, é apresentado um botão, cujo valor do atributo nome é UniqueID. Somente quando o atributo name do controle que causa o postback recebe um UniqueID o evento de postback pode ser capturado corretamente.
Terceiro, implemente a estrutura de atributos do evento.
A estrutura de atributos de evento é uma forma otimizada de implementar eventos. Antes de apresentar, vamos primeiro examinar os métodos comuns de implementação de eventos de controle. O código específico é o seguinte.
...
classe pública WebCustomControl:WebControl,IPostBackEventHandler{
//Declara o delegado do evento Click public event EventHandler Click;
//Implementar o método RaisePostBackEvent void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
OnClick(EventArgs.Empty);
}
//Definir manipulador de eventos OnClick protegido virtual void OnClick(EventArgs e) {
if(Clique!= null) {Clique(este,e });
}
...
}
No código acima, estão incluídos três conteúdos principais relacionados à definição do evento: 1. Definir o delegado do evento Click 2. A classe de controle implementa a interface IPostBackEventHandler, na qual o manipulador de eventos OnClick é definido ao implementar o método membro da interface RaisePostBackEvent. ;3. Implemente o manipulador de eventos OnClick. O método de implementação acima é simples e fácil de usar, mas apresenta uma desvantagem, ou seja, baixa eficiência de execução. Especialmente quando vários eventos são acionados em uma classe, isso aumentará a sobrecarga, desperdiçará muitos recursos do servidor e, por fim, levará à redução da eficiência operacional.
Para resolver os problemas acima, uma estrutura otimizada de atributos de método-evento de implementação de evento é apresentada abaixo. Essa estrutura usa a classe System.ComponentModel.EventHandlerList, que fornece uma lista de delegados simples. Usando os métodos relacionados fornecidos por esta classe, os desenvolvedores podem manipular com flexibilidade a lista de delegados do manipulador de eventos do controle. Por exemplo, o evento Click no controle usa a estrutura de atributos do evento da seguinte maneira:
objeto somente leitura estático protegido EventClick = new object();
evento público EventHandler Click{
adicionar {
Events.AddHandler(EventClick,valor);
}
remover {
Events.RemoveHandler(EventClick,valor);
}
}
Antes de definir a estrutura de atributos do evento, primeiro você precisa definir o objeto delegado do evento Click. Como cada evento é criado apenas uma vez, ele precisa ser declarado estático e somente leitura. Em seguida, opere a lista de delegados do manipulador de eventos por meio dos métodos AddHandler e RemoveHandler na estrutura de propriedades. Quando a página chama o evento Click, ela adiciona ou remove manipuladores da coleção EventHandlerList do controle. Como este método de implementação é mais eficiente que o método de implementação comum no processo de declaração de múltiplos eventos, é um método altamente recomendado.
Além disso, durante a implementação do método OnClick, ao utilizar um atributo de evento, o delegado deve ser recuperado de EventHandlerList e convertido para o tipo EventHandler.
vazio virtual protegido OnClick(EventArgs e){
EventHandler clickHandler = (EventHandler)Eventos[EventClick];
if(clickHandler! = nulo) {
clickHandler(isto,e);
}
}
Observação aos leitores: a estrutura de atributos de evento não é aplicável à linguagem VB.NET e só pode ser aplicada em linguagens como C#.
2. Aplicações típicas
Para ser honesto, a introdução teórica acima à captura de eventos de postback é um tanto difícil de entender para leitores que nunca implementaram eventos de controle de servidor. Para este fim, esta seção utiliza um exemplo típico para ilustrar especificamente o método de implementação de captura de eventos de retorno.
Este exemplo implementa um controle de servidor personalizado WebCustomControl. Embora esse controle apareça como um botão, ele não herda da classe Button. Quando o botão é clicado, o controle causará um postback e o servidor capturará automaticamente o evento click retornado, acionará o evento Click e executará o manipulador de eventos correspondente. A seguir está o código-fonte da implementação do controle do servidor:
usando o sistema; usando System.Collections.Generic; usando System.ComponentModel; usando System.Text; usando System.Web; usando System.Web.UI; usando System.Web.UI.WebControls; namespace WebControlLibrary{ [DefaultEvent("Clique")] [ToolboxData("<{0}:WebCustomControl runat=server></{0}:WebCustomControl>")] classe pública WebCustomControl: WebControl, IPostBackEventHandler { //Definir um objeto delegado de evento Click private static readonly object EventClick = new object(); //Implementar propriedades do evento Click [Description("Click event properties"), Category("Action") ] evento público EventHandler Click { adicionar { Events.AddHandler(EventClick, valor); } remover { Events.RemoveHandler(EventClick, valor); } } // Substitui o método de renderização de controle RenderContents substituição protegida void RenderContents(saída HtmlTextWriter) { output.Write("<input type='submit' name=" + this.UniqueID + " value=Por favor clique/>"); } //Implementar método de evento protegido virtual void OnClick(EventArgs e) { EventHandler clickHandler = (EventHandler)Eventos[EventClick]; if (clickHandler! = nulo) { clickHandler(este, e); } } // Implementar membro da interface IPostBackEventHandler void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) { OnClick(EventArgs.Empty); } } } |
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register TagPrefix="cc" Namespace="WebControlLibrary" Assembly="WebControlLibrary" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="servidor"> void wcc1_Click(objeto remetente, EventArgs e) { message.Text = "Você acabou de clicar no botão acima"; } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="servidor"> <title>Capturar eventos de postback</title> </head> <corpo> <form id="form1" runat="servidor"> <centro> <cc:WebCustomControl ID="wcc1" runat="server" OnClick="wcc1_Click" /> <br /> <br /> <asp:Label ID="message" runat="server"></asp:Label> </centro> </form> </body> </html> |
Figura 1 Renderizações de inicialização da página Figura 2 Efeitos após clicar no botão |
//Define o atributo AutoPostBack público bool AutoPostBack{ definir { this._autoPostBack = valor; } pegar { retorne isto._autoPostBack; } } //Adicionar o método Page.GetPostBackEventReference() no método Render substituição protegida void Render(saída HtmlTextWriter){ ... if(this.AutoPostBack) { escritor.WriteAttribute("ontextchanged","javascript:" + Page.GetPostBackEventReference(this)); } ... } |