2009-05-25 19 views
19

Estoy usando un cuadro de lista en mi aplicación de formularios de Windows C# 2.0. El método para rellenar el cuadro de lista esCómo prevenir el evento ListBox.SelectedIndexChanged?

private void PopulateListBox(ListBox lb, ReportColumnList reportColumnList) 
    { 
     lb.DataSource = reportColumnList.ReportColumns; 
     lb.DisplayMember = "ColumnName"; 
     lb.ValueMember = "ColumnName"; 
    } 

Sin embargo, cuando se ejecuta el método también se llama al controlador de eventos SelectedIndexChanged del cuadro de lista, a pesar de que no soy la creación del índice seleccionado en el método anterior. ¿Cómo puedo evitar que se llame al controlador de eventos SelectedIndexChanged para el código anterior?

Quiero que se llame al evento solo cuando el usuario realiza las selecciones en el ListBox. ¿O hay algún otro evento que sea solo para que el usuario seleccione los elementos de la lista de lista con un clic del mouse?

En otra nota, incluso si el usuario hace clic en un área vacía en el cuadro de lista, se desencadena el evento SelectedIndexChanged. ¿Entonces me pregunto qué tan diferente es del evento MouseClick?

+1

En su mayor parte, no se puede evitar que un objeto de elevar un evento .. Sólo se puede optar por deja de escuchar las notificaciones de eventos. – Gishu

+0

Quería decir si podría evitar de alguna manera esa parte de mi código, que dispara el evento. Pero como podemos ver, no hay mucho que pueda hacer ya que las tres líneas en el PopulateListBox() son necesarias :) –

Respuesta

15

puede rellenar el cuadro de lista utilizando lb.Items.AddRange() en lugar de establecer el origen de datos. Además de no activar el SelectedIndexChanged, esto tampoco preselecciona el primer elemento.

lb.Items.Clear(); 
lb.Items.AddRange(reportColumnList.ReportColumns.ToArray()); 
+1

Sí ... eso es exactamente lo que yo quería. Cambié mi código según tu respuesta y funciona a las mil maravillas :) ¡¡¡Muchísimas gracias, Kim !!! –

18

Hay tres formas de hacerlo.

A) No enganche en el evento SelectedIndexChanged hasta DESPUÉS de haber llamado a este método.

B) Tener un booleano privado en su clase que inicialmente se establece en verdadero. Al inicio de su método PopulateListBox, establézcalo en falso y, al final, configúrelo como verdadero. En su controlador de eventos para SelectedIndexChanged, si el indicador es falso, simplemente regrese y no haga nada.

C) Al iniciar su método PopulateListBox, desenganche del evento (this.listbox1.SelectedIndexChanged - = myMethod;) y luego, justo antes de que se complete el método, vuelva a conectarlo a ese evento.

+0

Gracias por la respuesta. Sin embargo, en lugar de los pasos anteriores, ¿qué sucede si uso el evento MouseClick para manejar los cambios en la selección del usuario? De esta forma, el evento MouseClick se activará solo si la selección del usuario cambia y no se llamará cuando se llame a PopulateListBox(). ¿Hay algún inconveniente de usar el evento MouseClick en este escenario? Lo probé y funciona bien, aunque me gustaría saber algunos errores ocultos que podría enfrentar en el futuro debido a esto. –

+0

No se puede usar el enfoque MouseClick. Motivo: para el cuadro de lista MultiExtended, cuando se hace clic con el mouse, incluso si seleccioné más de un elemento, el recuento de índices seleccionado no refleja eso. Solo cuando se llama a SelectedIndexChanged, obtengo un recuento adecuado. –

+0

Normalmente voy con la Opción A. +1 – Cerebrus

1

Debe tener en cuenta que incluso si no maneja el evento, el primer elemento de la lista se seleccionará automáticamente al asignar la propiedad DataSource. Para obligar al usuario a realizar una selección, deberá deseleccionar el elemento seleccionado automáticamente.

Si su controlador de eventos SelectedIndexChanged activa alguna funcionalidad cuando se selecciona un elemento, es posible que desee bloquearlo para que no se ejecute. Una forma de hacerlo es realizar un seguimiento de si el código está ocupando actualmente el listbox o no. Si el evento se desencadena SelectedIndexChanged mientras que el cuadro de lista se rellena, se puede evitar la realización de estas acciones:

private bool _populating = false; 
private void PopulateListBox(ListBox lb, ReportColumnList reportColumnList) 
{ 
    _populating = true; 
    lb.DataSource = reportColumnList.ReportColumns; 
    lb.DisplayMember = "ColumnName"; 
    lb.ValueMember = "ColumnName"; 

    // clear the automatically made selection 
    lb.SelectedIndex = -1; 
    _populating = false; 
} 

private void ListBox_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    if (!_populating) 
    { 
     // perform the action associated with selecting an item 
    } 

} 
6

Hay una respuesta sencilla a este problema: Un Fragmento de código a continuación puede sugerir el trabajo alrededor.

lstBxState.SelectionMode = SelectionMode.None; 
lstBxState.DataSource = lstStates; 
lstBxState.ValueMember = "StateId"; 
lstBxState.DisplayMember = "StateName"; 
lstBxState.ClearSelected(); 
lstBxState.SelectionMode = SelectionMode.One; 

Esto significa, simplemente Haga que el Modo de Selección sea "Ninguno", y felizmente Enlace de Datos al control. Luego avance y cambie el modo al requerido (aquí lo he cambiado a Uno, también puede seleccionar Múltiple).

+0

'System.Web.UI.WebControls.ListSelectionMode' no contiene una definición para 'Ninguno' – Homer

+1

Esta pregunta se trata de formularios de Windows, ese espacio de nombres es para controles de ASP.NET. – KyleMit

1

Dentro del método SelectedIndexChanged, solo hoyo en una sentencia if que dice, si SelectedIndex == -1 hacer nada más, hacer lo que quiere hacer en este método, probablemente no es el código más eficiente, pero que funcionó para mí :)

0
private void PopulateListBox(ListBox lb, ReportColumnList reportColumnList) 
{ 

    lb.SelectedIndexChanged -= this.*MethodnamewhichhandlesthisEvent*; //unset eventhandler 

    lb.DataSource = reportColumnList.ReportColumns; 
    lb.DisplayMember = "ColumnName"; 
    lb.ValueMember = "ColumnName"; 

    lb.SelectedIndexChanged += this.*MethodnamewhichhandlesthisEvent*; //set the eventhandler 
} 

Básicamente eliminar el delegado del evento y luego agregar una vez que haya terminado.

0

Mi situación puede ser única, pero la publicaré aquí en caso de que ayude a alguien.

Estaba haciendo el Items.AddRange para llenar mi ListBox en lugar de vinculante. No sé por qué, pero en PostBack, SelectedIndex iba de -1 a 0. Esto podría deberse a que mi ListBox era SelectionMode="Single".

Mi solución fue establecer manualmente el SelectedIndex a 0 en lugar de -1 después población:

listBox.Items.AddRange(items); 
listBox.SelectedIndex = 0; 
Cuestiones relacionadas