2009-11-23 15 views
8

Este es un problema absurdamente común y habiendo agotado todas las soluciones obvias, espero que SO pueda ofrecerme alguna información ... Tengo un UserControl dentro de una página que contiene un repetidor que contiene varios controles que causan la devolución de datos. El problema es que todos los controles dentro del repetidor nunca golpean a sus manejadores de eventos cuando se devuelven, pero los controles fuera del repetidor (todavía en la UC) se manejan correctamente. Ya me aseguré de que no se regeneraran mis controles debido a que faltaba if(!IsPostBack) y verifiqué que Request.Form ["__ EVENTTARGET"] contenía el ID de control correcto en el evento Page_Load. Intenté reproducir los síntomas en un proyecto separado y funcionó como debería.ASP.NET - Eventos de control que no encienden Inside Repeater

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="NoteListControl.ascx.cs" 
    Inherits="SantekGBS.Web.UserControls.NoteListControl" %> 

<asp:UpdatePanel ID="upNotes" runat="server" UpdateMode="Conditional"> 
    <ContentTemplate> 
     <div class="NoteList" id="divNoteList" runat="server"> 
      <asp:Repeater ID="repNotes" runat="server"> 
       <HeaderTemplate> 
        <table width="98%" cellpadding="3" cellspacing="0"> 
       </HeaderTemplate> 
       <ItemTemplate> 
        <tr class="repeaterItemRow"> 
         <asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/Content/images/DeleteIcon.gif" 
          OnClick="ibRemove_Click" CommandArgument='<%# Container.ItemIndex %>' CommandName='<%# Eval("ID") %>' 
          CausesValidation="false" AlternateText="Delete" /> 
         <%# Eval("Text") %></td> 
        </tr> 
       </ItemTemplate> 
       <FooterTemplate> 
        </table> 
       </FooterTemplate> 
      </asp:Repeater> 
      <asp:PlaceHolder ID="phNoNotes" runat="server" Visible="false"> 
       <div class="statusMesssage"> 
        No notes to display. 
       </div> 
      </asp:PlaceHolder> 
     </div> 
    </ContentTemplate> 
</asp:UpdatePanel> 

public partial class NoteListControl : UserControl 
{ 
    [Ninject.Inject] 
    public IUserManager UserManager { get; set; } 

    protected List<Note> Notes 
    { 
     get 
     { 
      if (ViewState["NoteList"] != null) 
       return (List<Note>)ViewState["NoteList"]; 
      return null; 
     } 
     set { ViewState["NoteList"] = value; } 
    } 

    public event EventHandler<NoteEventArgs> NoteAdded; 
    public event EventHandler<NoteEventArgs> NoteDeleted; 
    public event EventHandler<NoteEventArgs> NoteChanged; 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      UtilityManager.FillPriorityListControl(ddlPriority, false); 
     } 
    } 

    protected void ibRemove_Click(object sender, ImageClickEventArgs e) 
    { 
     System.Diagnostics.Debug.WriteLine("ibRemove POSTBACK"); // This is NEVER hit 
    } 

    public void Fill(List<Note> notes) 
    { 
     Notes = notes; 
     RefreshRepeater(); 
    } 

    private void RefreshRepeater() 
    { 
     if (Notes != null && Notes.Any()) 
     { 
      var sorted = Notes.OrderByDescending(n => n.Timestamp); 
      Notes = new List<Note>(); 
      Notes.AddRange(sorted); 
      repNotes.Visible = true; 
      phNoNotes.Visible = false; 
      repNotes.DataSource = Notes; 
      repNotes.DataBind(); 
     } 
     else 
     { 
      repNotes.Visible = false; 
      phNoNotes.Visible = true; 
     } 
    } 
} 

public class NoteEventArgs : EventArgs 
{ 
    public Note Note { get; set; } 
    public NoteEventArgs() 
    { } 
    public NoteEventArgs(Note note) 
    { 
     this.Note = note; 
    } 
} 

El código falta intencional funcionalidad así que no tener en cuenta este hecho.

Respuesta

2

Encontré una etiqueta td faltada en la plantilla Item, a veces cuando DOM es incorrecta, el panel de actualización hace cosas extrañas.

+0

Buena captura, pero en realidad puede ignorar eso. El marcado que estoy mostrando no es ni siquiera el mismo que el código de producción. Creé ese solo para mostrar el efecto. Todos los controles dentro de ItemTemplate se comportan de la misma manera. –

3

Su código editado tiene propiedades residuales CommandArgument y CommandName; ¿está realmente manejando el evento Repeater.ItemCommand?

Si es así, y si su página llama al método Fill del control en las devoluciones, eso lo explicaría.

Este clásico ASP.NET problema capilar-rasgado se explica en estos mensajes: A Stumper of an ASP.NET Question y A Stumper of an ASP.NET Question: SOLVED!

La explicación es un poco endiablada, pero el quid de la cuestión es que Repeater.DataBind interfiere con la capacidad de ASP.NET para determinar qué botón repetidor causó una devolución de datos.

+0

Aunque estoy usando los argumentos CommandArgument y CommandName, no estoy generando eventos a través de Repeater.ItemCommand. Estoy usando las propiedades para almacenar información a la que accedo en el evento de clic de botón estándar. –

+0

Creo que el enlace debe ser http://scottonwriting.net/sowBlog/archive/0000/00/00/162929.aspx – darasd

+0

@darasd - ¡gracias por la corrección del enlace! –

2

Casi CADA vez que me encuentro con este problema es porque se llama a DataBind() cuando no debería ser. Esto matará a la mayoría de los eventos de los controles dentro de un repetidor. Veo que tiene un! IsPostBack check en su Page_Load ... así que eso es un comienzo. Pero intenta poner un punto de interrupción en repNotes.DataBind() y ver si se llama cuando no lo esperas.

¿Funciona bien fuera de un UpdatePanel?

+0

DataBind() solo se invoca en la carga de página inicial y después de eventos de control especificados, ninguno de los cuales se activa como debería. El UpdatePanel no parece estar relacionado con el problema. Tengo otra forma en mi aplicación que también solía funcionar y que muestra un comportamiento similar, cuando el formulario publica el repetidor se vacía como lo hace aquí. Comportamiento muy extraño. –

+0

No ha desactivado ViewState para ninguno de estos controles, ¿verdad? Tienes "otra forma" ... ¿Asumo que es una página .aspx diferente? ¿No tienes una etiqueta de formulario adicional en esta página? – Bryan

+0

El comentario de Bryan me ayudó: en mi caso tenía EnableViewState = "false" en el repetidor padre, y eso impidió que se disparara el controlador de devolución de datos del control de pie de página. – fortboise

0

Me encontré con el mismo problema. Me pasó si ejecuté DataBind dos veces. En otras palabras, cuando llene el control de repetidor dos veces (por cualquier motivo) los eventos no se dispararán.

Espero que ayude.

0

Me encontré con este problema también. Me volvía loco porque no estaba reconectando mi repetidor, intenté agregar un controlador de eventos dinámicamente, cambiar la configuración de ViewState por todos lados, nada funcionó.

La respuesta en mi caso fue que estaba llamando a "Page.DataBind()" en la página maestra, para manejar algunas variables de código subyacente que estaban vinculadas a la página utilizando la sintaxis <% # MyVar%>.

Una vez que saqué el Page.DataBind() funcionó, solo tuve que recodificar la Página maestra para obtener esos datos de una manera diferente.

Supongo que si está haciendo un DataBind() en cualquier lugar de la cadena para su página, control de usuario, clase base de página, página maestra, etc. podría matar su viewstate y el evento de burbujeo.

Cuestiones relacionadas