2009-11-14 16 views
5

Estoy seguro de que esto es simple pero me está volviendo loco.¿Por qué se llaman los métodos no relacionados (autopostback) cuando se invoca un método Asp.Net ListBox autopostback?

Tengo un cuadro de lista en mi página para mostrar los artistas, que llama a un método cuando se cambia el índice, y un botón que carga un artista de esa lista en otra página cuando se hace clic:

<asp:ListBox ID="lbArtists" runat="server" Rows="1" AutoPostBack="true" OnSelectedIndexChanged="ShowArtistsWorks" /> 

<asp:Button ID="btnEditArtist" runat="server" Text="Edit the artist" OnClick="LoadArtist" /> 

Más adelante , tengo una lista similar de enlaces, que también tiene un método AutoPostBack:

<asp:ListBox ID="lbLinks" runat="server" Rows="1" AutoPostBack="true" OnSelectedIndexChanged="LoadLink" /> 

el problema es que cuando invoco ShowArtistsWorks() haciendo clic btnEditArtist, el método también es llamado LoadLink(). ¿Por qué está sucediendo eso? ¿Por qué se llamará cuando no haya cambiado el índice en el lbLinks ListBox? No debería acercarse a ese método.

EDIT: métodos (relevante) de código subyacente (

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack){ 
     GetArtists(); // populates artists listbox 
     GetLinks(); // populates links listbox 
    } 
} 

protected void LoadArtist(object sender, EventArgs e){ 
    if (lbArtists.SelectedValue != "") 
     Response.Redirect("Artist.aspx?id=" + lbArtists.SelectedValue); 
} 

protected void LoadLink(object sender, EventArgs e) 
{ 
    if (lbLinks.SelectedValue != "") 
     Response.Redirect("Link.aspx?id=" + lbLinks.SelectedValue); 
} 

editar # 2: podría fácilmente kludge una solución para esto en los métodos individuales para detenerlos sucede cuando no deberían , pero quiero entender por qué los métodos que no llaman, y que sólo se les llamó desde un solo lugar, obtener invoqué inadvertidamente

respuesta aceptada:. aunque Boon (ahora CRice) se puso en primer lugar con una explicación y una solución, decidí aceptar la explicación más completa de Jeff porque eso era lo que quería, un análisis más profundo. Gracias a todos los que contestaron.

+0

Asegúrese de que no tiene EnableViewState = "false" en la página web.config o en la directiva de la página. – Phaedrus

+0

No, no es eso. Fan de "Zen and the Art ..."? –

+0

mofe ........... – CRice

Respuesta

2

eventos de cambio se elevan en cada devolución de datos para los que sean relevantes - como se describe en el tema de MSDN "ASP.NET Web Server Control Event Model."

eventos de cambio de servidor HTML controla y servidor Web controles, tales como el control de cuadro de texto , inmediatamente no causar un poste. En su lugar, se generan la próxima vez que se produzca una publicación.

Cuando los usuarios hacen clic el botón de su 'Editar Artista', ASP.NET piensa lbLinks.SelectedIndex ha cambiado, por lo que invoca su controlador SelectedIndexChanged.

La razón ASP.NET cree que el índice ha cambiado es la siguiente: cuando la página se carga por primera, lbLinks no tienen un índice seleccionado (o valor) a menos que se diga lo contrario estableciendo explícitamente. Hasta que lo haga, el índice seleccionado es -1 y su valor seleccionado es una cadena vacía. El valor seleccionado (en este caso, una cadena vacía) se escribe para ver el estado cuando se representa la página para que ASP.NET pueda decir si el valor ha cambiado en las devoluciones de datos.

Puede observar esto durante la depuración inspeccionando los índices y valores seleccionados de sus cuadros de lista antes del renderizado, o puede usar uno de los decodificadores de estado de vista en línea (like this one) para ver lo que está en su página cuando se escribe por primera vez (aunque lea esto, necesita saber acerca de the structure of serialized view state data).

Al siguiente segundo palo, el elemento HTML <select>lbLinkstiene un valor no vacío, y se presenta como parte de los datos de envío. Eche un vistazo al Request.Form["lbLinks"] y verá que es igual a lbLinks.Items[0].Value.

ASP.NET asigna el valor publicado a lbLinks.SelectedValue, pero también sabe que el valor seleccionado solía ser una cadena vacía - se pone el valor antiguo del estado de vista. Dado que los dos valores son diferentes, el proceso aumenta el evento de cambio de índice seleccionado del control, causando el comportamiento indeseable que ha observado.

As boon suggested, la solución es establecer siempre explícitamente la SelectedIndex para todas sus ListBox controles cuando se está utilizando el evento OnSelectedIndexChanged, incluso si acaba de establecer el índice a cero.

(El ajuste AutoPostBack es una cortina de humo no relacionado. Si lo quita de ambos cuadros de lista, sus OnSelectedIndexChanged eventos tanto fuego cada vez que haga clic en el botón.)

0

¿Estás seguro de que no has cambiado el índice en la otra lista? ¿Está volviendo a encuadernar ese cuadro de lista, tal vez, porque ese código se ejecuta en el paquete postal?

+0

Ocurre si cambio o no el otro ListBox. Eso es lo que me desconcierta. No, no volver a vincularlo –

+0

Si solo llama a LoadLinks() desde el evento, ¿cómo se llena la lista para comenzar? Lo que estamos diciendo es que todo el código en el ciclo de vida de su página se ejecuta cuando el evento se publica (excepto donde está probando IsPostBack). El evento no se dispara sin que la lista cambie. – cdonner

+0

Bueno, LoadLink() significa, cargar el Enlace seleccionado en una página nueva. El ListBox se rellena en primer lugar desde el evento Page_Load, pero solo si (! IsPostBack) ... –

0

Supongo que llamas a LoadLinks() en tu Page_Load() u otro evento similar. Recuerde, cuando realiza una devolución de datos, debe volver a ejecutar todo el ciclo de vida de la página. Estás trabajando con una nueva instancia de la clase de página. Esto es cierto incluso si solo desea procesar un simple clic de botón o evento de cambio de selección.

+0

No, solo llamo a LoadLink() desde 'lbLinks' ListBox –

0

Intente ver la pila de llamadas & vea por qué se llama al método no relacionado.

Supongo que podría ser el código que cambia la propiedad Index del otro listbox & luego el cableado de eventhandlers después de eso.

La pila de llamadas debería ayudarlo a identificar el motivo, para empezar.

0

El problema está en sus declaraciones AutoPostBack = "true". No sé la razón exacta si alguien más quisiera elaborar, pero cuando los controles múltiples en una página tienen AutoPostBack = "verdadero", todos los eventos del lado del servidor se disparan cuando se vuelven a publicar en el servidor.

EDIT Supongo que, por algún motivo, posiblemente relacionado con el estado de vista que SelectedIndexChanged está evaluando como verdadero para ambos controles en la devolución de datos.

+0

¿está reconstruyendo DropDownList en Postback? – jaywon

+0

No, ambos solo se llenan si (! IsPostBack) –

+0

Eso podría ser parte del problema para la activación del evento SelectedIndexChanged. Creo que es posible que necesite volver a llenar las listas cada vez para que ViewState verifique correctamente si el evento SelectedIndexChanged es verdadero o no. – jaywon

1

Según la página, ambas listboxes han cambiado.Se seleccionó Índice1, luego, cuando la página se carga, ambos irán al índice seleccionado 0, posiblemente debido a la manera en que les está asignando los datos. Por lo tanto, cuando se produce una devolución de datos, solo tiene sentido que se ejecuten ambos métodos, ya que su índice seleccionado realmente ha cambiado.

Vea si lo siguiente hace que su problema desaparezca. Establecer el índice seleccionado como cero:

if (!IsPostBack){ 
    GetArtists(); // populates artists listbox 
    GetLinks(); // populates links listbox 

    lbArtists.SelectedIndex = 0; 
    lbLinks.SelectedIndex = 0; 
} 
+0

+1 para explicar primero en pocas palabras el problema y para la solución que funciona, gracias. –

+0

tal vez simplemente no fui lo suficientemente elaborado como parece! : P – CRice

+0

Bueno, como dije en Edit # 2, pude resolver el problema con un kludge bien, pero quería entender el problema con cierto detalle. En ese sentido, la respuesta de Jeff fue mejor –

0

Mi pensamiento es que el segundo cuadro de lista doesn No empieces con un elemento seleccionado. Cuando se carga la página, su navegador está seleccionando el primer elemento automáticamente. Cuando publica la página, el estado de visualización ha cambiado (no hay elemento en el primer elemento) para que se produzca el evento de devolución de datos. Intenta asegurarte de que tienes una selección.

Cuestiones relacionadas