2008-10-17 10 views
5

He creado un control swapper de elementos que consta de dos cuadros de lista y algunos botones que me permiten intercambiar elementos entre las dos listas. El intercambio se hace usando javascript. También muevo elementos hacia arriba y hacia abajo en la lista. Básicamente, cuando muevo los elementos al cuadro de lista a la derecha, guardo las claves de datos de los elementos (GUID) en un campo oculto. En la devolución, simplemente leí los GUID del campo. Todo funciona bien pero en la devolución de datos, recibo la siguiente excepción:Elementos de ListBox reorganizados con JavaScript que causan un error de validación de eventos en la devolución de datos

No válido postback o argumento de devolución de llamada. La validación de eventos se habilita mediante la configuración <% @ Page EnableEventValidation = "true"%> en una página. Por motivos de seguridad, esta función verifica que los argumentos para la devolución de datos o los eventos de devolución de llamada se originan en el control del servidor que los generó originalmente. Si los datos son válidos y esperados, utilice el método ClientScriptManager.RegisterForEventValidation para registrar la devolución de datos o los datos de devolución de llamada para la validación.

He preparado una aplicación de prueba. Todo lo que tienes que hacer es descargar el archivo y ejecutar el proyecto. En la página web, seleccione los 3 elementos, presione Agregar todo, luego mueva el tercer elemento un nivel y luego presione "Botón". El error aparecerá. Desactivar la validación de eventos no es aceptable. ¿Alguien puede ayudarme? He pasado dos días sin encontrar una solución.

TEST APPLICATION

+0

FYI: He descargado la aplicación y nunca tiene este error - Yo, sin embargo, aparece un error acerca col1 no ser parte de la tabla de datos, o algo por el estilo (no mirarlo en este momento). Es posible que desee comprobar para asegurarse de que su ejemplo cause este error, porque no es para mí. –

+0

Además, el "movimiento" de ida y vuelta no funciona en absoluto en Firefox, es posible que desee mencionarlo o solucionarlo. –

+0

El error con col1 se debe a destinationDT.Columns.Add ("colUID", typeof (Guid)); y destinationDT.Columns.Add ("col1", typeof (cadena)); que solo se invocan si no están en la parte posterior de la publicación, pero se requieren cuando se hace clic en el botón. – Aleris

Respuesta

0

La primera opción traerá considerables gastos generales. He definido mi propio control de cuadro de lista personalizada derivada de la clase cuadro de lista y se realizó una anulación de los datos loadpostback:

public class CustomListBox : ListBox 
{ 
    protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) 
    { 
     return true; 
    } 
} 

El uso de este en lugar del cuadro de lista regular en mi control de usuario resuelve el problema, sin embargo, ¿hay riesgos asociados con mi enfoque?

+0

Probablemente quiera devolver el valor falso si hace esto: si devuelve verdadero, siempre se activará SelectedIndexChanged, pero como ha anulado el bit que rellena SelectedIndex de los datos de la publicación, en realidad nunca cambiará. – stevemegson

0

Se quejaba de que el elemento seleccionado en una lista no estaba presente en la lista cuando se haya adoptado. Considere usar PageMethods a través de AJAX para regresar sus datos a su formulario en lugar de PostBack. O utilice controles que no sean de entrada para contener los datos, como las listas desordenadas a las que mueva los elementos de la lista de un lado a otro. Puede colocar los GUID en tramos ocultos dentro del elemento de la lista, donde puede acceder a ellos si es necesario.

+0

Sin embargo, si simplemente muevo los elementos de la lista de la izquierda a la de la derecha y luego los devuelve sin cambiar su orden (arriba o abajo) todo está bien. En este caso, ¿no son las dos listas diferentes en la devolución de datos en comparación con cuando se escribió la página? – kjv

+0

Más precisamente, se queja porque el valor seleccionado en la lista no estaba presente en la lista cuando se escribió la página. Agregar elementos está bien, pero reordenarlos deja un elemento seleccionado y, por lo tanto, causa el problema. – stevemegson

+0

Descripción fija del problema. – tvanfosson

3

El problema es que el estado de la vista guardada de la lista y los datos recibidos en la devolución no coinciden. El problema de validación de eventos probablemente sea uno de los posibles problemas que pueden aparecer debido a este enfoque. La arquitectura de los formularios web no permite este tipo de usos y, lo más probable, habrá más problemas con este enfoque, incluso si logra evitar el problema de validación de eventos. Tiene varias alternativas:

1) Lo más simple es hacer la lógica de intercambio en el servidor en lugar de usar javascript. De esta forma, el estado de la vista se conservará entre las devoluciones y la sobrecarga adicional de múltiples viajes redondos al servidor podría no ser un problema.

2) Si los múltiples viajes redondos al servidor son un problema, escriba un control de servidor que maneje su propio estado de vista. Este es, por supuesto, un enfoque muy atractivo.

3) Un enfoque intermedio podría ser usar dos listas html simples (solo escriba las etiquetas html sin usar los controles asp.net) y mantenga en el lado del cliente una lista de identificadores javascript en un campo oculto. En la parte posterior de la publicación simplemente analiza el campo oculto y extrae la identificación ignorando las listas html.

Iría con 1 si no hay argumentos SERIOS contra él.

1

Unas pocas opciones posibles:

  • Si es posible, desactivar ViewState en las dos listas. Sin ViewState, el servidor no sabrá cuáles eran los valores originales y, por lo tanto, no generará errores. Con este enfoque, tendrá que volver a llenar las listas (debido a la falta de ViewState) y es posible que deba hacer un seguimiento de la selección manualmente, o deberá rellenar las listas durante la fase OnInit.

  • desactivar la validación de evento (si puede)

  • Rellenar ambas listas totalmente en el lado del servidor y el uso de script del lado del cliente (JavaScript) para eliminar las entradas de las dos listas según sea necesario.

0

Por casualidad, ¿has intentado esto ya? Haga esto cada vez que ensucia con la lista de cualquier manera.

document.getElementById("listbox").selectedIndex = -1; 
0

Alternativamente, puede utilizar un HtmlSelect del lado del servidor en lugar de un ListBox para evitar el problema de validación de eventos. Lo mejor de todo, es posible que pueda dejar intacta gran parte de su código subyacente (es decir, la lógica de población de la lista es la misma que la de ListBox).

<select runat="server" id="myList" multiple="true" /> 
0

Se podría anular el evento render para registrar todos los posibles elementos de cuadro de lista con dos cuadros de lista. De esa forma, sin importar qué elementos se trasladen a dónde, la validación los está esperando.

protected override void Render(HtmlTextWriter writer) 
{ 
    foreach (DictionaryEntry entry in ColumnConfig) {   
    Page.ClientScript.RegisterForEventValidation(lstbxColumnsToExport.UniqueID,(string)entry.Key); 
    Page.ClientScript.RegisterForEventValidation(lstbxNonExportColumns.UniqueID,(string)entry.Key); 
    } 
    base.Render(writer); 
} 
Cuestiones relacionadas