Alterando propriedades de controles (server controls) através de eventos Callback
Bom dia.
Estou precisando resolver a seguinte situação:
Em um WebForm (Asp.Net) temos um GridView. Na primeira coluna do GridView existe um botão que executa uma chamada CallBack alterando as propriedades específicas de alguns controles da página. (Ex.: altera a propriedade Text de um label).
Porém pelo fato de ser um Callback, as alterações nos controles não são visualizadas, por não recarregar a página.
Minha dúvida é: como consigo alterar propriedades de controles (label por exemplo) e aplicar estas alterações na página através da chamada Callback? Existe a possibilidade de fazer isto sem a utilização de Javascript?
Att.
Samuel
Nefrodata Ltda
Curtidas 0
Respostas
Luiz Maia
08/05/2009
Ola,
Não precisa usar javascript não. Segue exemplo de codigo abaixo:
protected void Atualizar()
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ToString()); SqlCommand command = new SqlCommand("UPDATE CLIENTE SET NOME = @NOME, STATUS = @STATUS WHERE ID_CLIENTE = @ID_CLIENTE", connection); command.Parameters.AddWithValue("@ID_CLIENTE", lblCodigo.Text);
command.Parameters.AddWithValue("@NOME", txtNome.Text);
command.Parameters.AddWithValue("@STATUS", DropDownList1.SelectedValue); connection.Open(); command.ExecuteNonQuery(); connection.Close(); //Atualiza GridView
Buscar();
} protected void grvClientes_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName.Equals("Excluir"))
{
int codigo = int.Parse(e.CommandArgument.ToString()); Excluir(codigo);
}
else if (e.CommandName.Equals("Editar"))
{
int index = int.Parse(e.CommandArgument.ToString()); GridViewRow row = grvClientes.Rows[index];
lblCodigo.Text = row.Cells[0].Text;
txtNome.Text = row.Cells[1].Text;
DropDownList1.SelectedValue = row.Cells[3].Text;
}
}
E no ASPX: <asp:GridView ID="grvClientes" runat="server" AutoGenerateColumns="False" BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px" CellPadding="4" DataKeyNames="ID_CLIENTE" ForeColor="Black" GridLines="Vertical" onrowcommand="grvClientes_RowCommand"> <RowStyle BackColor="#F7F7DE" /> <Columns> <asp:BoundField DataField="ID_CLIENTE" HeaderText="C¢digo" /> <asp:BoundField DataField="NOME" HeaderText="Nome" /> <asp:BoundField DataField="DATA_CADASTRO" HeaderText="Cadastro" /> <asp:BoundField DataField="STATUS" HeaderText="Status" /> <asp:TemplateField> <ItemTemplate> <asp:LinkButton ID="lnkExcluir" CommandArgument='<%# DataBinder.Eval(Container.DataItem,"ID_CLIENTE") %>' runat="server" CommandName="Excluir">Excluir</asp:LinkButton> </ItemTemplate> </asp:TemplateField> <asp:TemplateField> <ItemTemplate> <asp:LinkButton ID="lnkEditar" runat="server" CommandArgument='<%# Container.DataItemIndex %>' CommandName="Editar">Editar</asp:LinkButton> </ItemTemplate> </asp:TemplateField> </Columns> <FooterStyle BackColor="#CCCC99" /> <PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" /> <SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> </asp:GridView> Caso não entenda algo, me avise que publico um projetinho para vc baixar ai no disco virtual. Abraços Att Luiz Maia
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ToString()); SqlCommand command = new SqlCommand("UPDATE CLIENTE SET NOME = @NOME, STATUS = @STATUS WHERE ID_CLIENTE = @ID_CLIENTE", connection); command.Parameters.AddWithValue("@ID_CLIENTE", lblCodigo.Text);
command.Parameters.AddWithValue("@NOME", txtNome.Text);
command.Parameters.AddWithValue("@STATUS", DropDownList1.SelectedValue); connection.Open(); command.ExecuteNonQuery(); connection.Close(); //Atualiza GridView
Buscar();
} protected void grvClientes_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName.Equals("Excluir"))
{
int codigo = int.Parse(e.CommandArgument.ToString()); Excluir(codigo);
}
else if (e.CommandName.Equals("Editar"))
{
int index = int.Parse(e.CommandArgument.ToString()); GridViewRow row = grvClientes.Rows[index];
lblCodigo.Text = row.Cells[0].Text;
txtNome.Text = row.Cells[1].Text;
DropDownList1.SelectedValue = row.Cells[3].Text;
}
}
E no ASPX: <asp:GridView ID="grvClientes" runat="server" AutoGenerateColumns="False" BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px" CellPadding="4" DataKeyNames="ID_CLIENTE" ForeColor="Black" GridLines="Vertical" onrowcommand="grvClientes_RowCommand"> <RowStyle BackColor="#F7F7DE" /> <Columns> <asp:BoundField DataField="ID_CLIENTE" HeaderText="C¢digo" /> <asp:BoundField DataField="NOME" HeaderText="Nome" /> <asp:BoundField DataField="DATA_CADASTRO" HeaderText="Cadastro" /> <asp:BoundField DataField="STATUS" HeaderText="Status" /> <asp:TemplateField> <ItemTemplate> <asp:LinkButton ID="lnkExcluir" CommandArgument='<%# DataBinder.Eval(Container.DataItem,"ID_CLIENTE") %>' runat="server" CommandName="Excluir">Excluir</asp:LinkButton> </ItemTemplate> </asp:TemplateField> <asp:TemplateField> <ItemTemplate> <asp:LinkButton ID="lnkEditar" runat="server" CommandArgument='<%# Container.DataItemIndex %>' CommandName="Editar">Editar</asp:LinkButton> </ItemTemplate> </asp:TemplateField> </Columns> <FooterStyle BackColor="#CCCC99" /> <PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" /> <SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> </asp:GridView> Caso não entenda algo, me avise que publico um projetinho para vc baixar ai no disco virtual. Abraços Att Luiz Maia
GOSTEI 0
Nefrodata Ltda
08/05/2009
Boa tarde.
Veja no exemplo abaixo que eu altero a propriedade Text do controle lblTeste, esta alteração não é visualizada na página pois não foi recarregada por se tratar de callback e não postback. Existe a possibilidade de aplicar as alterações feitas via Callback? Ou seja eu queria que o texto "EXECUTOU CALLBACK" fosse visualizada na página.
EM ASPX:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CallbackBasico.aspx.cs" Inherits="CallbackBasico" %>
<%@ Register Assembly="DevExpress.Web.ASPxEditors.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.Web.ASPxEditors" TagPrefix="dxe" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<script language="javascript">
function ExibeNome(arg, context) {
document.getElementById('txtNome').value = arg;
}
function TrataErro(arg, Context) {
document.getElementById('lblErro').value = arg;
document.getElementById('lblErro').value += Context;
}
</script>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblCPF" runat="server" Text="C.P.F.:"></asp:Label>
<asp:TextBox ID="txtCPF" runat="server" ></asp:TextBox>
<asp:Label ID="lblNome" runat="server" Text="Nome :"></asp:Label>
<asp:TextBox ID="txtNome" runat="server" ></asp:TextBox>
<asp:Label ID="lblErro" ForeColor="Red" runat="server" Text=""></asp:Label>
<br />
<asp:Button ID="btnBuscar" runat="server" Text="Buscar"/>
<asp:Label ID="lblTeste" ForeColor="Red" runat="server" Text=""></asp:Label>
</div>
</form>
</body>
</html>
EM C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class CallbackBasico : System.Web.UI.Page, ICallbackEventHandler
{
private string _cpf;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsCallback && Request.Browser.SupportsCallback)
{
string funcaoJS = this.ClientScript.GetCallbackEventReference(this, "document.getElementById('" + this.txtCPF.ClientID + "').value",
"ExibeNome",
"'Aqui é o Contexto'",
"TrataErro",
true);
this.btnBuscar.OnClientClick = string.Concat(funcaoJS, "; return false;");
lblTeste.Text = "EXECUTOU POSTBACK";
}
if (IsCallback)
lblTeste.Text = "EXECUTOU CALLBACK";
}
public void RaiseCallbackEvent(string eventArgs)
{
this._cpf = eventArgs;
lblTeste.Text = "EXECUTOU CALLBACK";
}
public string GetCallbackResult()
{
if (this._cpf.Length != 11)
throw new ArgumentException("Comprimento do cpf incorreto!");
if (this._cpf == "00011122233")
return ("teste3");
if (this._cpf == "00011122244")
return ("teste4");
if (this._cpf == "00011122255")
return ("teste5");
throw new ArgumentException("Registro Inexistente");
}
}
Veja no exemplo abaixo que eu altero a propriedade Text do controle lblTeste, esta alteração não é visualizada na página pois não foi recarregada por se tratar de callback e não postback. Existe a possibilidade de aplicar as alterações feitas via Callback? Ou seja eu queria que o texto "EXECUTOU CALLBACK" fosse visualizada na página.
EM ASPX:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CallbackBasico.aspx.cs" Inherits="CallbackBasico" %>
<%@ Register Assembly="DevExpress.Web.ASPxEditors.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.Web.ASPxEditors" TagPrefix="dxe" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<script language="javascript">
function ExibeNome(arg, context) {
document.getElementById('txtNome').value = arg;
}
function TrataErro(arg, Context) {
document.getElementById('lblErro').value = arg;
document.getElementById('lblErro').value += Context;
}
</script>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblCPF" runat="server" Text="C.P.F.:"></asp:Label>
<asp:TextBox ID="txtCPF" runat="server" ></asp:TextBox>
<asp:Label ID="lblNome" runat="server" Text="Nome :"></asp:Label>
<asp:TextBox ID="txtNome" runat="server" ></asp:TextBox>
<asp:Label ID="lblErro" ForeColor="Red" runat="server" Text=""></asp:Label>
<br />
<asp:Button ID="btnBuscar" runat="server" Text="Buscar"/>
<asp:Label ID="lblTeste" ForeColor="Red" runat="server" Text=""></asp:Label>
</div>
</form>
</body>
</html>
EM C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class CallbackBasico : System.Web.UI.Page, ICallbackEventHandler
{
private string _cpf;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsCallback && Request.Browser.SupportsCallback)
{
string funcaoJS = this.ClientScript.GetCallbackEventReference(this, "document.getElementById('" + this.txtCPF.ClientID + "').value",
"ExibeNome",
"'Aqui é o Contexto'",
"TrataErro",
true);
this.btnBuscar.OnClientClick = string.Concat(funcaoJS, "; return false;");
lblTeste.Text = "EXECUTOU POSTBACK";
}
if (IsCallback)
lblTeste.Text = "EXECUTOU CALLBACK";
}
public void RaiseCallbackEvent(string eventArgs)
{
this._cpf = eventArgs;
lblTeste.Text = "EXECUTOU CALLBACK";
}
public string GetCallbackResult()
{
if (this._cpf.Length != 11)
throw new ArgumentException("Comprimento do cpf incorreto!");
if (this._cpf == "00011122233")
return ("teste3");
if (this._cpf == "00011122244")
return ("teste4");
if (this._cpf == "00011122255")
return ("teste5");
throw new ArgumentException("Registro Inexistente");
}
}
GOSTEI 0
Luiz Maia
08/05/2009
Ola Srs,
Simulei sua aplicação aqui e percebi que não esta aparecendo a referencia JS para o ___callback, como no post back:
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
} Se vc olhar o "view source" de seu HTML, vera o metodo acima mas sem o __callback, ai nao tem como funcionar. O callback é um post back especial, então sempre ocorre um round-trip, diferente do postback classico, o callback nao renderiza a pagina completa. O viewstate nao é atualizado durante um callback, so no postback. No codigo cliente js, se o GetCallbackEventReference() é refernciado, quando o codigo js é executado, um canal do servidor é aberto e uma requisição HTTO e enviada para uma pagina ASP.net remota. Apos o ASPnet runtine recuperar a requisição HTTP, ele procura pelo metodo que te falei acima, o __CALLBACKID, Somente se ele for encontrado, o runtime conclui que uma chamada callback esta sendo feita. Agora, qual seu intuito de fazer isto usando callback? Aguardo Att Luiz Maia
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
} Se vc olhar o "view source" de seu HTML, vera o metodo acima mas sem o __callback, ai nao tem como funcionar. O callback é um post back especial, então sempre ocorre um round-trip, diferente do postback classico, o callback nao renderiza a pagina completa. O viewstate nao é atualizado durante um callback, so no postback. No codigo cliente js, se o GetCallbackEventReference() é refernciado, quando o codigo js é executado, um canal do servidor é aberto e uma requisição HTTO e enviada para uma pagina ASP.net remota. Apos o ASPnet runtine recuperar a requisição HTTP, ele procura pelo metodo que te falei acima, o __CALLBACKID, Somente se ele for encontrado, o runtime conclui que uma chamada callback esta sendo feita. Agora, qual seu intuito de fazer isto usando callback? Aguardo Att Luiz Maia
GOSTEI 0
Luiz Maia
08/05/2009
Veja se com este exemplo vcs conseguem algum avanço:
<%@ Page Language="C#" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> public int cbCount = 0; // Define method that processes the callbacks on server.
public void RaiseCallbackEvent(String eventArgument)
{
cbCount = Convert.ToInt32(eventArgument) + 1;
} // Define method that returns callback result.
public string GetCallbackResult()
{
return cbCount.ToString();
} protected void Page_Load(object sender, EventArgs e)
{
// Define a StringBuilder to hold messages to output.
StringBuilder sb = new StringBuilder(); // Check if this is a postback.
sb.Append("No page postbacks have occurred.");
if (Page.IsPostBack)
{
sb.Append("A page postback has occurred.");
} // Write out any messages.
MyLabel.Text = sb.ToString(); // Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript; // Define one of the callback script's context.
// The callback script will be defined in a script block on the page.
StringBuilder context1 = new StringBuilder();
context1.Append("function ReceiveServerData1(arg, context)");
context1.Append("{");
context1.Append("Message1.innerText = arg;");
context1.Append("value1 = arg;");
context1.Append("}"); // Define callback references.
String cbReference1 = cs.GetCallbackEventReference(this, "arg",
"ReceiveServerData1", context1.ToString());
String cbReference2 = cs.GetCallbackEventReference("'" +
Page.UniqueID + "'", "arg", "ReceiveServerData2", "",
"ProcessCallBackError", false);
String callbackScript1 = "function CallTheServer1(arg, context) {" +
cbReference1 + "; }";
String callbackScript2 = "function CallTheServer2(arg, context) {" +
cbReference2 + "; }"; // Register script blocks will perform call to the server.
cs.RegisterClientScriptBlock(this.GetType(), "CallTheServer1",
callbackScript1, true);
cs.RegisterClientScriptBlock(this.GetType(), "CallTheServer2",
callbackScript2, true); }
</script> <script type="text/javascript">
var value1 = 0;
var value2 = 0;
function ReceiveServerData2(arg, context)
{
Message2.innerText = arg;
value2 = arg;
}
function ProcessCallBackError(arg, context)
{
Message2.innerText = 'An error has occurred.';
}
</script> <html >
<head id="Head1" runat="server">
<title>ClientScriptManager Example</title>
</head>
<body>
<form id="Form1"
runat="server">
<div>
Callback 1 result: <span id="Message1">0</span>
<br />
Callback 2 result: <span id="Message2">0</span>
<br /> <br />
<input type="button"
value="ClientCallBack1"
onclick="CallTheServer1(value1, alert('Increment value'))"/>
<input type="button"
value="ClientCallBack2"
onclick="CallTheServer2(value2, alert('Increment value'))"/>
<br /> <br />
<asp:Label id="MyLabel"
runat="server"></asp:Label>
</div>
</form>
</body>
</html> Aguardo um retorno de vcs. Abraços Att Luiz Maia
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> public int cbCount = 0; // Define method that processes the callbacks on server.
public void RaiseCallbackEvent(String eventArgument)
{
cbCount = Convert.ToInt32(eventArgument) + 1;
} // Define method that returns callback result.
public string GetCallbackResult()
{
return cbCount.ToString();
} protected void Page_Load(object sender, EventArgs e)
{
// Define a StringBuilder to hold messages to output.
StringBuilder sb = new StringBuilder(); // Check if this is a postback.
sb.Append("No page postbacks have occurred.");
if (Page.IsPostBack)
{
sb.Append("A page postback has occurred.");
} // Write out any messages.
MyLabel.Text = sb.ToString(); // Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript; // Define one of the callback script's context.
// The callback script will be defined in a script block on the page.
StringBuilder context1 = new StringBuilder();
context1.Append("function ReceiveServerData1(arg, context)");
context1.Append("{");
context1.Append("Message1.innerText = arg;");
context1.Append("value1 = arg;");
context1.Append("}"); // Define callback references.
String cbReference1 = cs.GetCallbackEventReference(this, "arg",
"ReceiveServerData1", context1.ToString());
String cbReference2 = cs.GetCallbackEventReference("'" +
Page.UniqueID + "'", "arg", "ReceiveServerData2", "",
"ProcessCallBackError", false);
String callbackScript1 = "function CallTheServer1(arg, context) {" +
cbReference1 + "; }";
String callbackScript2 = "function CallTheServer2(arg, context) {" +
cbReference2 + "; }"; // Register script blocks will perform call to the server.
cs.RegisterClientScriptBlock(this.GetType(), "CallTheServer1",
callbackScript1, true);
cs.RegisterClientScriptBlock(this.GetType(), "CallTheServer2",
callbackScript2, true); }
</script> <script type="text/javascript">
var value1 = 0;
var value2 = 0;
function ReceiveServerData2(arg, context)
{
Message2.innerText = arg;
value2 = arg;
}
function ProcessCallBackError(arg, context)
{
Message2.innerText = 'An error has occurred.';
}
</script> <html >
<head id="Head1" runat="server">
<title>ClientScriptManager Example</title>
</head>
<body>
<form id="Form1"
runat="server">
<div>
Callback 1 result: <span id="Message1">0</span>
<br />
Callback 2 result: <span id="Message2">0</span>
<br /> <br />
<input type="button"
value="ClientCallBack1"
onclick="CallTheServer1(value1, alert('Increment value'))"/>
<input type="button"
value="ClientCallBack2"
onclick="CallTheServer2(value2, alert('Increment value'))"/>
<br /> <br />
<asp:Label id="MyLabel"
runat="server"></asp:Label>
</div>
</form>
</body>
</html> Aguardo um retorno de vcs. Abraços Att Luiz Maia
GOSTEI 0
Luiz Maia
08/05/2009
E ai pessoal, conseguiram chegar na solução?
Aguardo retorno.
Att
Luiz Maia
GOSTEI 0
Nefrodata Ltda
08/05/2009
Ok, Obrigado!
GOSTEI 0
Luiz Maia
08/05/2009
Blz gente, precisando é so falar!!!
Abraços
Att
Luiz Maia
GOSTEI 0