2011-01-13 20 views
6

Tengo un ListBox al que agrego ListItems en un código subyacente. El problema que estoy teniendo es que ListBox no está viendo los elementos seleccionados. Tengo el ListBox poblado dinámicamente según lo que el usuario seleccione de DropDownList, por lo que DropDownList tiene AutoPostBack establecido en verdadero. Creo que esto de alguna manera está causando el problema.ListBox no está recibiendo elementos seleccionados

Mi método SelectedIndexChanged, que se usa cada vez que se selecciona un elemento en DropDownList, llama a un método llamado PopulateListBox. Esto es lo que se ve esos métodos como:

protected void SelectedIndexChanged(object sender, EventArgs e) 
{ 
    string typeStr = type.SelectedItem.Text; 
    MyType = Api.GetType(typeStr); 
    PopulateListBox(); 
} 

private void PopulateListBox() 
{ 
    listbox.Items.Clear(); 
    foreach (PropertyInfo info in MyType.GetProperties()) 
     listbox.Items.Add(new ListItem(info.Name)); 
} 

Por lo que vale la pena, que aquí son los DropDownList y ListBox:

<asp:DropDownList runat="server" ID="type" width="281px" OnSelectedIndexChanged="SelectedIndexChanged" AutoPostBack="true" /> 

<asp:ListBox runat="server" ID="listbox" width="281px" height="200px" selectionmode="Multiple" /> 

Lo que estoy tratando de hacer es añadir una lista de cadenas (siendo el seleccionadas elementos) como una variable de sesión al hacer clic en un botón de enviar. El botón redirige a una nueva página después de que la Lista se haya agregado a la sesión. Pasando por el depurador, la Lista de cadenas está vacía en el punto donde la agrego a la sesión.

listbox.GetSelectedIndices() no devuelve nada.

actualización

que puede acceder a los elementos seleccionados si no hago un cambio en el DropDownList. El ListBox se rellena inicialmente en la carga de página, y si realizo selecciones, se reconocen. Si selecciono algo de DropDownList y ListBox se vuelve a llenar, las selecciones no se reconocen.

Mi método Page_Load hace solo dos cosas. Se inicializa mi variable de Api y llama PopulateDropDown, que se ve así:

private void PopulateDropDown() 
{ 
    foreach (Type t in Api.GetAllTypes()) 
     type.Items.Add(new ListItem(t.Name)); 
    string typeStr = type.Items[0].Text; 
    Type = Api.GetType(typeStr); 
    PopulateListBox(); 
} 
+0

¿Pero cuándo no puede ver los elementos seleccionados en el cuadro de lista? Al cambiar la selección en la lista desplegable? ¿O tienes algún otro control que realice una devolución de datos? – dzendras

+0

@dzendras: actualicé la publicación al final con respecto a esto. –

+0

¿Cuándo accede al cuadro de lista? PageLoad? Compruebe si el lugar al que accede es correcto de acuerdo con el ciclo de vida de la página ASP.NET (en las primeras etapas de procesamiento, los controles de solicitud no tienen sus propiedades establecidas). También verifique si no está borrando el listbox anteriormente en el ciclo de vida de la página. – dzendras

Respuesta

13

El problema es que se llama a PopulateDropDown() en cada Page_Load(), que llama PopulateListBox(), que despeja el cuadro de lista y vuelve a llenar él. Al borrar el cuadro de lista, borra la selección.

Debe reemplazar su llamada al PopulateDropDown() en el Page_Load() con el siguiente código. El problema del que creo que no se da cuenta es que la página se carga en cada devolución de datos, y que en el ciclo de vida de la página, la carga de la página se produce antes del evento. Entonces al seleccionar un elemento desplegable, se ejecuta primero el evento Page_Load() (que indirectamente ejecuta el método LoadListBox, borrando la selección). El siguiente código rellenará la lista desplegable la primera vez que la página carga solo. Mantenga la misma en cualquier otro lugar que está utilizando el método desplegable de carga:

protected void Page_Load(object sender, EventArgs e) 
{ 
    // Do your API code here unless you want it to occur only the first 
    // time the page loads, in which case put it in the IF statement below. 
    if (!IsPostBack) 
    { 
     PopulateDropDown(); 
    } 
} 

El IsPostBack devuelve un valor booleano que indica si el código del lado del servidor se ejecuta debido a que la página se carga por primera vez ("falso") o como una publicación posterior ("verdadera").

Como dije en otro lugar, tenga en cuenta que un cuadro de lista con potencial para múltiples valores seleccionados debe manejarse de manera diferente que uno con potencial para una sola selección.No haga referencia a listbox.SelectedItem, sino más bien:

foreach (ListItem item in lbFullNames) 
{ 
    if (item.Selected) 
    { 
     // TODO: Whatever you are doing with a selected item. 
    } 
} 
+0

Ah, gracias Justin. DropDownList solo llama a una devolución de datos porque AutoPostBack está configurado como verdadero para él, ¿verdad? Mañana daré una oportunidad a tu solución e informaré. –

+0

Sí, pero si configura AutoPostBack en falso, entonces el código C# no se ejecutará cuando cambie los índices, lo que significa que el cuadro de lista no se volverá a llenar. –

1

También he descubierto que si se desactiva el servidor del lado del cuadro de lista, a continuación, use el código del lado del cliente para que el cuadro de lista mediante código como el siguiente, entonces no se puede conseguir los elementos seleccionados del lado del servidor.

$('.css-class-assigned-to-listbox').attr('disabled', ''); 

La solución es simplemente para hacer del lado del servidor seguro de que está activado (por defecto), y luego desactivarlo (ver golpe) o activarlo (véase más arriba) usando el código del lado del cliente.

$('.css-class-assigned-to-listbox').attr('disabled', 'disabled'); 
Cuestiones relacionadas