2010-03-31 17 views
14

¿Es posible cancelar el evento SelectedIndexChange para un cuadro de lista en una aplicación de winforms? Esto parece una cosa tan lógica de tener que estar pasando por alto alguna característica fácil. Básicamente, he estado mostrando un cuadro de mensaje que pregunta si el usuario realmente desea pasar a otro elemento, ya que esto cambiará la interfaz de usuario y no quiero que se pierdan sus cambios. Me gustaría poder cancelar el evento en caso de que el usuario no haya guardado lo que están trabajando. ¿Hay una mejor manera de hacer esto?Cancelación de ListBox SelectedIndexChange Evento

+0

Estoy de acuerdo con nawfal para más detalles revisa el siguiente enlace .... http://www.mindstick.com/Articles/176c6d68-ceca-4072-a319-7389f4e5b9dd/?ListBox%20events % 20in% 20C% 20 # .Net –

+0

Posible duplicado de [Cómo prevenir/cancelar el cambio del valor de un cuadro combinado en C#?] (Http://stackoverflow.com/questions/314503/how-to-prevent-cancel-a- comboboxs-value-change-in-c) –

Respuesta

16

No puede cancelarlo.

Lo que hice hace solo un par de días fue tener una variable con el último índice seleccionado. Luego, cuando se desate el evento, le pregunta al usuario si quiere guardar, esto se hace en el manejador de eventos. Si el usuario seleccionó "Cancelar", cambia la identificación nuevamente.

El problema es que esto hará que el evento vuelva a dispararse. Entonces, lo que he usado es un bool diciendo "Inhibir". Y en la parte superior del manejador de sucesos que tengo:

if(Inhibit) 
    return; 

A continuación, por debajo de este, donde se hace la pregunta que hacer algo como esto:

DialogResult result = MessageBox.Show("yadadadad", yadada cancel etc); 
if(result == DialogResult.Cancel){ 
    Inhibit = true; //Make sure that the event does not fire again 
    list.SelectedIndex = LastSelectedIndex; //your variable 
    Inhibit = false; //Enable the event again 
} 
LastSelectedIndex = list.SelectedIndex; // Save latest index. 
+1

Una pequeña variación de esto, descubrí después de leer esta respuesta: puede eliminar el controlador de eventos en lugar de usar el indicador Inhibir: 'list.SelectedIndexChanged - = list_SelectedIndexChanged; list.SelectedIndex = LastSelectedIndex; list.SelectedIndexChanged + = list_SelectedIndexChanged; ' Puede haber algunas razones por las que este es un método inferior, pero funcionó muy bien para mis propósitos. – TwainJ

+0

@J Jones ¿Qué pasa si lo hiciste menos dos veces? ¿No estoy seguro si eso no arrojaría una excepción? –

+0

@OskarKjellin No lo harías dos veces porque está dentro de la función.La función nunca volverá a llamarse hasta que la vuelva a agregar más tarde. – Grungondola

2

El SelectedIndexChanged no se puede cancelar. Entonces usted solo tiene una opción real:

private int? currentIndex; 
public void ListBox_SelectedIndexChanged(sender, EventArgs args) { 
    if (currentIndex.HasValue && currentIndex.Value != listBox1.SelectedIndex) { 
     var res = MessageBox.Show("Do you want to cancel edits?", "Cancel Edits", MessageBoxButtons.YesNo); 
     if (res == DialogResult.Yes) { 
      currentIndex = (listBox1.SelectedIndex == -1 ? null : (int?) listBox1.SelectedIndex); 
     } else { 
      listBox1.SelectedIndex = currentIndex.Value; 
     } 
    } 
} 
5

Acabo de encontrarme con este problema exacto. Lo que hice es que cuando el usuario hace cambios, configuro ListBox.Enabled = false; Esto les impide seleccionar un índice diferente. Una vez que guardan o descartan sus cambios, configuro ListBox.Enabled = true; Probablemente no tan resbaladizo como un aviso, pero hace el trabajo bien.

+0

Esto es asombroso. Cada vez que empiezo a tener que preocuparme por las variables de los miembros privados que hacen un seguimiento del índice actual, o hago un seguimiento de algún Inhibit booleano, empiezo a pensar: ¿cómo puedo evitar agregar esta capa adicional de lógica? Deshabilitar el ListBox se ocupa de eso. – JustLooking

9

Este es exactamente el método de @Oskar Kjellin, pero con un giro. Es decir, una variable menos y con un evento de cambio de índice seleccionado que realmente se comporta como un evento cambiado de índice seleccionado. A menudo me pregunto por qué se selecciona el evento de cambio de índice seleccionado, incluso si hago clic en el mismo elemento seleccionado exactamente. Aquí no. Sí, es una desviación, así que esté doblemente seguro de que quiera que esté allí.

int _selIndex = -1; 
    private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (listBox1.SelectedIndex == _selIndex) 
      return; 

     if (MessageBox.Show("") == DialogResult.Cancel) 
     { 
      listBox1.SelectedIndex = _selIndex; 
      return; 
     } 

     _selIndex = listBox1.SelectedIndex; 
     // and the remaining part of the code, what needs to happen when selected index changed happens 
    } 
0

más elegante, utilice la propiedad Tag:

 if ((int)comboBox.Tag == comboBox.SelectedIndex) 
     { 
      // Do Nothing 
     } 
     else 
     { 
      if (MessageBox.Show("") == DialogResult.Cancel) 
      { 
       comboBox.SelectedIndex = (int)comboBox.Tag; 
      } 
      else 
      { 
       // Reset the Tag 
       comboBox.Tag = comboBox.SelectedIndex; 

       // Do what you have to 
      } 
     } 
0

Esta es mi manera de cancelar SelectionChange de ComboBox. Creo que también podría caber en ListBox.

private bool comboBox_CancelSelection = false; 
private int comboBox_LastSelectedIndex = -1; 

private void comboBox_SelectedIndexChanged(object sender, EventArgs e) { 
    if (comboBox_CancelSelection) { 
     comboBox_CancelSelection = false; 
     return ; 
    } 

    // Handle Event 

    if (!comoBox_CancelSelection) { 
     comboBox_LastSelectedIndex = comboBox.SelectedIndex; 
    } else { 
     comboBox.SelectedIndex = comboBox_LastSelectedIndex; 
    } 
}