ASP.Net:por que os eventos de clique/comando do meu botão não são vinculados/disparados em um repetidor?
Pergunta
Aqui está o código do ascx que possui o repetidor:
<asp:Repeater ID="ListOfEmails" runat="server" >
<HeaderTemplate><h3>A sub-header:</h3></HeaderTemplate>
<ItemTemplate>
[Some other stuff is here]
<asp:Button ID="removeEmail" runat="server" Text="X" ToolTip="remove" />
</ItemTemplate>
</asp:Repeater>
E no codebehind para databound e eventos do repetidor:
Protected Sub ListOfEmails_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles ListOfEmails.ItemDataBound
If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim removeEmail As Button = CType(e.Item.FindControl("removeEmail"), Button)
removeEmail.CommandArgument = e.Item.ItemIndex.ToString()
AddHandler removeEmail.Click, AddressOf removeEmail_Click
AddHandler removeEmail.Command, AddressOf removeEmail_Command
End If
End Sub
Sub removeEmail_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Response.Write("<h1>click</h1>")
End Sub
Sub removeEmail_Command(ByVal sender As Object, ByVal e As CommandEventArgs)
Response.Write("<h1>command</h1>")
End Sub
Nem o clique nem o comando estão sendo chamados. O que estou fazendo de errado?
Solução
Os controles aninhados dentro dos Repetidores não interceptam eventos.Em vez disso, você precisa se vincular ao Repeater.ItemCommand
Evento.
ItemCommand
contém RepeaterCommandEventArgs
que possui dois campos importantes:
- NomeDoComando
- ComandoArgumento
Então, um exemplo trivial:
void rptr_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
// Stuff to databind
Button myButton = (Button)e.Item.FindControl("myButton");
myButton.CommandName = "Add";
myButton.CommandArgument = "Some Identifying Argument";
}
}
void rptr_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Add")
{
// Do your event
}
}
Outras dicas
Você precisa lidar com Evento ItemCommand em seu repetidor.Aqui está um exemplo.
Em seguida, os cliques nos botões serão tratados pelo método ListOfEmails_ItemCommand.Não acho que conectar o evento Click ou Command (do botão) em ItemDataBound funcione.
Se você está planejando usar o evento ItemCommand, certifique-se de registrar-se no evento ItemCommand em Page_Init e não em Page_Load.
protected void Page_Init(object sender, EventArgs e)
{
// rptr is your repeater's name
rptr.ItemCommand += new RepeaterCommandEventHandler(rptr_ItemCommand);
}
Não sei por que não funcionou para mim com este evento registrado em Page_Load, mas movê-lo para Page_Init ajudou.
Aqui está uma experiência para você tentar:
Defina um ponto de interrupção em ListOfEmails_ItemDataBound e veja se ele está sendo chamado para postbacks.
Você sabe o que é frustrante nisso?
Se você especificar um OnClick nessa tag asp:Button, o build vai verifique se o método nomeado existe na classe codebehind e relate um erro se isso não acontecer...mesmo que esse método nunca seja chamado.