Fornecer precedência para um postback assíncrono específico
Por padrão, quando uma página faz vários postbacks assíncronos ao mesmo tempo, o postback feito mais recentemente terá precedência.Em algumas situações, convém dar prioridade a um postback assíncrono específico e cancelar os outros postbacks.
Neste tutorial, você irá controlar qual postback terá precedência.Você pode fazer isso criando um manipulador de eventos para o evento initializeRequest da classe PageRequestManager.Para obter informações sobre a sequência de eventos gerado na classe PageRequestManager, consulte Trabalhando com eventos PageRequestManager.
Pré-requisitos
Para implementar os procedimentos no seu próprio ambiente de desenvolvimento você precisa:
Microsoft Visual Studio 2005 ou Microsoft Visual Web Developer Express Edition.
Um site da Web ASP.NET habilitado para AJAX.
A criação de scripts que fornecem precedência para um elemento específico postback
Você iniciará criando Código ECMAScript (JavaScript) que gerencia o postback assíncrono no navegador.
Para criar scripts que fornecem precedência para um elemento específico postback
No site da Web ASP.NET, adicione um arquivo JScript e denomine-o PostbackPrecedence.js.
Adicione o seguinte script ao arquivo:
Sys.Application.add_load(ApplicationLoadHandler) function ApplicationLoadHandler(sender, args) { if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) { Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(InitializeRequest); } } var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var exclusivePostBackElement = 'Button1'; var lastPostBackElement; function InitializeRequest(sender, args) { var prm = Sys.WebForms.PageRequestManager.getInstance(); if (prm.get_isInAsyncPostBack() && args.get_postBackElement().id === exclusivePostBackElement) { if (lastPostBackElement === exclusivePostBackElement) { args.set_cancel(true); ActivateAlertDiv('visible', 'A previous postback is still executing. The new postback has been canceled.'); setTimeout("ActivateAlertDiv('hidden','')", 1500); } else if (lastPostBackElement !== exclusivePostBackElement) { prm.abortPostBack(); } } else if (prm.get_isInAsyncPostBack() && args.get_postBackElement().id !== exclusivePostBackElement) { if (lastPostBackElement === exclusivePostBackElement) { args.set_cancel(true); ActivateAlertDiv('visible', 'A previous postback is still executing. The new postback has been canceled.'); setTimeout("ActivateAlertDiv('hidden','')", 1500); } } lastPostBackElement = args.get_postBackElement().id; } function ActivateAlertDiv(visString, msg) { var adiv = $get(divElem); var aspan = $get(messageElem); adiv.style.visibility = visString; aspan.innerHTML = msg; } if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
Sys.Application.add_load(ApplicationLoadHandler) function ApplicationLoadHandler(sender, args) { if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) { Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(InitializeRequest); } } var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; var exclusivePostBackElement = 'Button1'; var lastPostBackElement; function InitializeRequest(sender, args) { var prm = Sys.WebForms.PageRequestManager.getInstance(); if (prm.get_isInAsyncPostBack() && args.get_postBackElement().id === exclusivePostBackElement) { if (lastPostBackElement === exclusivePostBackElement) { args.set_cancel(true); ActivateAlertDiv('visible', 'A previous postback is still executing. The new postback has been canceled.'); setTimeout("ActivateAlertDiv('hidden','')", 1500); } else if (lastPostBackElement !== exclusivePostBackElement) { prm.abortPostBack(); } } else if (prm.get_isInAsyncPostBack() && args.get_postBackElement().id !== exclusivePostBackElement) { if (lastPostBackElement === exclusivePostBackElement) { args.set_cancel(true); ActivateAlertDiv('visible', 'A previous postback is still executing. The new postback has been canceled.'); setTimeout("ActivateAlertDiv('hidden','')", 1500); } } lastPostBackElement = args.get_postBackElement().id; } function ActivateAlertDiv(visString, msg) { var adiv = $get(divElem); var aspan = $get(messageElem); adiv.style.visibility = visString; aspan.innerHTML = msg; } if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
O script executa as seguintes tarefas:
Defines a handler for the load event of the Sys.Application class.O manipulador por sua vez registra um manipulador chamado InitializeRequest para o evento initializeRequest da classe PageRequestManager.
Define o manipulador InitializeRequest para verificar se um postback assíncrono está em execução e para determinar o nome do elemento que causou o postback.Se o elemento que causou o postback é aquele que você especificou como um elemento de postback exclusivo (aquele que deve ter prioridade), o novo postback é cancelado, definindo a propriedade cancel da classe InitializeRequestEventArgs.
Define uma função ActivateAlertDiv que alterna a visibilidade de um elemento <div> na página para exibir mensagens.
Usando o Script com um Controle UpdatePanel
Nesse procedimento você irá usar o script que você criou em uma página.A página contém um botão cujo postback tem precedência sobre o postback de outro botão na página.
Para criar uma página a fim de certificar-se de que o postback de um postback tem precedência
Criar uma nova página da Web Single-File do ASP.NET e alternar para modo de design.
Na guia Extensões AJAX da caixa de ferramentas, clique duas vezes no controle ScriptManager para adicioná-lo à página.
Dê dois cliques duas vezes no controle UpdatePanel para adicionar duas instâncias do controle à página.
Em cada UpdatePanel controle, da Padrão guia da caixa de ferramentas.Adicionar um Label controle e um Button controle.
conjunto o Text valor da Label controle de ambos os painéis de painel inicialmente processados.
Clique duas vezes em cada controle Button para adicionar um manipulador para cada botão do evento Click.
Adicione o seguinte código para os manipuladores Click, que artificialmente cria um atraso e exibe a hora atual no painel que originou o postback:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) System.Threading.Thread.Sleep(4000) Label1.Text = "Last update from server " & DateTime.Now.ToString() End Sub Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) System.Threading.Thread.Sleep(1000) Label2.Text = "Last update from server " & DateTime.Now.ToString() End Sub
protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(4000); Label1.Text = "Last update from server " + DateTime.Now.ToString(); } protected void Button2_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(1000); Label2.Text = "Last update from server " + DateTime.Now.ToString(); }
Observação: Os manipuladores para o evento Click introduz intencionalmente um atraso para este tutorial.Na prática, você poderia não introduzir um atraso.Em vez disso, o atraso deve ser o resultado do tráfego do servidor ou do código que demora para processar, como uma consulta ao banco de dados de execução demorada .
Alterne para modo de exibição Source e em seguida, adicione o seguinte bloco <style> no elemento <head> da página:
<style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1, #UpdatePanel2 { width: 400px; height: 100px; border: solid 1px gray; } div.MessageStyle { background-color: #FFC080; top: 95%; left: 1%; height: 20px; width: 600px; position: absolute; visibility: hidden; } </style>
<style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1, #UpdatePanel2 { width: 400px; height: 100px; border: solid 1px gray; } div.MessageStyle { background-color: #FFC080; top: 95%; left: 1%; height: 20px; width: 600px; position: absolute; visibility: hidden; } </style>
As regras de estilo definem o tamanho do elemento <div> que é processado pelo controle UpdatePanel e do elemento <div> que alerta o usuário quando um postback é cancelado.
Adicione a seguinte marcação dentro do elemento <form> na página:
<div id="AlertDiv" class="MessageStyle"> <span id="AlertMessage"></span> </div>
<div id="AlertDiv" class="MessageStyle"> <span id="AlertMessage"></span> </div>
A marcação define um elemento <div> que exibirá uma mensagem quando um postback assíncrono for cancelado devido um que já está em andamento.
Alternar para modo Design.
Clique dentro do primeiro controle UpdatePanel e depois a partir da guia Ajax Extensions na caixa de ferramentas, adicione um controle UpdateProgress.
clicar dentro de UpdateProgress controle e tipo Painel1 atualizando ….
Isso define a propriedade ProgressTemplate.
selecionar o UpdateProgress controle e, em seguida, na janela Propriedades, conjunto o AssociatedUpdatePanelID propriedade para UpdatePanel1.
A página no designer será semelhante a figura a seguir:
Clique dentro do segundo controle UpdatePanel e adicione um segundo controle UpdateProgress.
clicar dentro de UpdateProgress controle e tipo Painel2 atualizando ….
Isso define a propriedade ProgressTemplate.
selecionar o UpdateProgress controle e, em seguida, na janela Propriedades, defina o AssociatedUpdatePanelID propriedade para UpdatePanel2.
A página no designer será semelhante a figura a seguir:
Selecione o controle ScriptManager.
Na janela Propriedades, selecione a propriedade Scripts e clique no botão reticências (…) para exibir a caixa de diálogo ScriptReference Collection Editor.
Clique em Adicionar para adicionar uma referência de script.
Defina a propriedade Path da referência de script para PostbackPrecedence.js, que é o arquivo de JavaScript que você criou anteriormente.
Adicionando uma referência de script usando a coleção Scripts do ScriptManager, certifique-se que o script é carregado depois que o Microsoft AJAX Library foi carregado.
Clique em OK para fechar a caixa de diálogo Editor de Coleção ScriptReference.
Salve suas alterações e, em seguida, pressione CTRL + F5 para exibir a página em um navegador.
Clique no botão no primeiro painel e, em seguida clique no botão no segundo painel.
É exibida uma mensagem que indica que o novo postback foi cancelado.O botão no primeiro painel deve terminar antes de uma novo postback ser iniciado.O arquivo de script fornece a lógica para aplicar esse comportamento.
Clique no botão no segundo painel e, em seguida clique no botão no primeiro painel.
O Botão no segundo painel não terá precedência porque ele não foi codificado para fazer isso na arquivo de script.Portanto, nenhuma mensagem de aviso é exibida e um novo postback é iniciado pelo botão no primeiro painel.Esse é o comportamento padrão de postbacks assíncronos — o postback mais recente tem precedência.
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) System.Threading.Thread.Sleep(4000) Label1.Text = "Last update from server " & DateTime.Now.ToString() End Sub Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) System.Threading.Thread.Sleep(1000) Label2.Text = "Last update from server " & DateTime.Now.ToString() End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>Postback Precedence Example</title> <style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1, #UpdatePanel2 { width: 400px; height: 100px; border: solid 1px gray; } div.MessageStyle { background-color: #FFC080; top: 95%; left: 1%; height: 20px; width: 600px; position: absolute; visibility: hidden; } </style> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" > <Scripts> <asp:ScriptReference Path="PostBackPrecedence.js" /> </Scripts> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="Server" > <ContentTemplate> <strong>UpdatePanel 1</strong><br /> This postback takes precedence.<br /> <asp:Label ID="Label1" >Panel initially rendered.</asp:Label><br /> <asp:Button ID="Button1" Text="Button" OnClick="Button1_Click" /> <asp:UpdateProgress ID="UpdateProgress1" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> Panel1 updating... </ProgressTemplate> </asp:UpdateProgress> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel ID="UpdatePanel2" UpdateMode="Conditional" runat="Server" > <ContentTemplate> <strong>UpdatePanel 2</strong><br /> <asp:Label ID="Label2" >Panel initially rendered.</asp:Label><br /> <asp:Button ID="Button2" Text="Button" OnClick="Button2_Click" /> <asp:UpdateProgress ID="UpdateProgress2" AssociatedUpdatePanelID="UpdatePanel2"> <ProgressTemplate> Panel2 updating... </ProgressTemplate> </asp:UpdateProgress> </ContentTemplate> </asp:UpdatePanel> <div id="AlertDiv" class="MessageStyle"> <span id="AlertMessage"></span> </div> </div> </form> </body> </html>
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(4000); Label1.Text = "Last update from server " + DateTime.Now.ToString(); } protected void Button2_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(1000); Label2.Text = "Last update from server " + DateTime.Now.ToString(); } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>Postback Precedence Example</title> <style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1, #UpdatePanel2 { width: 400px; height: 100px; border: solid 1px gray; } div.MessageStyle { background-color: #FFC080; top: 95%; left: 1%; height: 20px; width: 600px; position: absolute; visibility: hidden; } </style> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" > <Scripts> <asp:ScriptReference Path="PostBackPrecedence.js" /> </Scripts> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="Server" > <ContentTemplate> <strong>UpdatePanel 1</strong><br /> This postback takes precedence.<br /> <asp:Label ID="Label1" >Panel initially rendered.</asp:Label><br /> <asp:Button ID="Button1" Text="Button" OnClick="Button1_Click" /> <asp:UpdateProgress ID="UpdateProgress1" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> Panel1 updating... </ProgressTemplate> </asp:UpdateProgress> </ContentTemplate> </asp:UpdatePanel> <asp:UpdatePanel ID="UpdatePanel2" UpdateMode="Conditional" runat="Server" > <ContentTemplate> <strong>UpdatePanel 2</strong><br /> <asp:Label ID="Label2" >Panel initially rendered.</asp:Label><br /> <asp:Button ID="Button2" Text="Button" OnClick="Button2_Click" /> <asp:UpdateProgress ID="UpdateProgress2" AssociatedUpdatePanelID="UpdatePanel2"> <ProgressTemplate> Panel2 updating... </ProgressTemplate> </asp:UpdateProgress> </ContentTemplate> </asp:UpdatePanel> <div id="AlertDiv" class="MessageStyle"> <span id="AlertMessage"></span> </div> </div> </form> </body> </html>
Revisão
Este tutorial mostra como ativar um postback assíncrono específico para tomar precedência (ou seja, para concluir o processamento) antes do outro postback assíncrono iniciar.A lógica para aplicar esse comportamento está em um arquivo de JavaScript que está incluído como uma referência de script para a página.O script pode ser personalizado para que todos os postbacks assíncronos atuais devam terminar antes de qualquer outro ser iniciado.No entanto, você deve considerar com cuidado o design quando você especifica quais postbacks têm precedência.
Consulte também
Conceitos
Trabalhando com eventos PageRequestManager