2010-11-03 9 views
24

Los WinForms CheckedListBox control tiene 2 comportamientos predeterminados cuando se hace clic con el ratón:Los comportamientos extraños cuando el estado verificado alternar el objeto: CheckedListBox a través MouseClick al hacer clic sobre la misma selección

  1. Con el fin de activar/desactivar un elemento que está es necesario hacer clic en un elemento dos veces. El primer clic selecciona el elemento y el segundo activa el estado de verificación.
  2. Además, un clic posterior del mismo elemento alternará el estado comprobado de ese elemento.

Como característica de conveniencia, necesitaba permitir a los usuarios activar o desactivar la selección con un solo clic. Lo he logrado, por lo que ahora el comportamiento predeterminado n. ° 1 anterior se logra con un solo clic. El problema es que el comportamiento # 2 ya no funciona correctamente al hacer clic en el mismo elemento (es decir, actualmente seleccionado). Funciona bien cuando se salta entre elementos, lo que se desea, pero requiere hasta 4 clics en el mismo elemento.

Mi solución para esto es llamar a la lógica de alternar dos veces si el usuario selecciona el mismo elemento varias veces. Así que a mis preguntas:

  1. Esto funciona, pero ¿por qué? ¿Cuál es el verdadero problema subyacente?
  2. ¿Hay una manera mejor de lograr esto para que pueda hacer que funcione como el comportamiento predeterminado # 2 sin llamar al método dos veces y hacer un seguimiento de mi última selección?

Por lo demás, la depuración del código revela que el estado comprobado ha cambiado pero no aparece en el lado de la interfaz de usuario hasta que se llama dos veces. Pensé que podría estar relacionado con el subprocesamiento, pero no se está desencadenando un evento que pueda necesitar el uso de BeginInvoke.

Aquí está mi código:

using System.Linq; 
using System.Windows.Forms; 

namespace ToggleCheckedListBoxSelection 
{ 
    public partial class Form1 : Form 
    { 
     // default value of -1 since first item index is always 0 
     private int lastIndex = -1; 

     public Form1() 
     { 
      InitializeComponent(); 
      CheckedListBox clb = new CheckedListBox(); 
      clb.Items.AddRange(Enumerable.Range(1, 10).Cast<object>().ToArray()); 
      clb.MouseClick += clb_MouseClick; 
      this.Controls.Add(clb); 
     } 

     private void clb_MouseClick(object sender, MouseEventArgs e) 
     { 
      var clb = (CheckedListBox)sender; 
      Toggle(clb); 

      // call toggle method again if user is trying to toggle the same item they were last on 
      // this solves the issue where calling it once leaves it unchecked 
      // comment these 2 lines out to reproduce issue (use a single click, not a double click) 
      if (lastIndex == clb.SelectedIndex) 
       Toggle(clb); 

      lastIndex = clb.SelectedIndex; 
     } 

     private void Toggle(CheckedListBox clb) 
     { 
      clb.SetItemChecked(clb.SelectedIndex, !clb.GetItemChecked(clb.SelectedIndex)); 
     } 
    } 
} 

para reproducir mi comentario problema de las líneas mencionadas en los comentarios de código y siga estos pasos:

  1. haga clic en el elemento en la posición 2 - estado cambia a comprobado.
  2. Con el elemento actual seleccionado, haga clic de nuevo; el estado no cambia. Esperado: sin marcar. Haga clic en él varias veces y finalmente cambiará.

¡Gracias por leer!

Respuesta

49

Como función de conveniencia, necesitaba permitir a los usuarios activar o desactivar la selección con un solo clic.

no estoy seguro de lo que está pasando con el código, pero el establecimiento de CheckOnClick a true va a hacer esto:

CheckOnClick indica si la casilla de verificación debe ser cambiada cada vez que se selecciona un elemento. El comportamiento predeterminado es cambiar la selección en el primer clic, y luego hacer que el usuario vuelva a hacer clic para aplicar la marca de verificación.Sin embargo, en algunos casos, es posible que prefiera que se marque el artículo tan pronto como se haga clic en él.

+1

+1: Bonito y simple. De alguna manera, pasé por alto esta opción. –

+3

El mío se estableció en falso de forma predeterminada cuando el comportamiento que quería era verdadero. gracias por la respuesta, ¡me ayudó también! – rizalp1

Cuestiones relacionadas