2010-01-19 20 views
9

Estoy usando un control CheckedListBox en una pequeña aplicación en la que estoy trabajando. Es un buen control, pero una cosa me molesta; No puedo establecer una propiedad para que solo compruebe el elemento cuando realmente marque la casilla de verificación. ¿Cuál es la mejor manera de superar esto? He estado pensando en obtener la posición del mouse, relativo desde el lado izquierdo de la casilla de verificación. Lo cual funciona en parte, pero si hago clic en un espacio vacío, lo suficientemente cerca de la izquierda, el elemento seleccionado actualmente aún se verificará. Alguna idea con respecto a esto?Control CheckedListBox - Solo marcando la casilla de verificación cuando se hace clic en la casilla de verificación real

+0

Tal vez me esté perdiendo algo. ¿Qué está pasando ahora cuando marque la casilla? ¿Nada? ¿Está revisando algo por defecto? ¿Qué está pasando que quieres que deje de suceder? – hunter

+0

Solo quiero que se marque la casilla cuando hago clic en el cuadro, no en la línea. Imagínese que se parece a: [] Artículo1 Actualmente, la casilla se comprueba al hacer clic en el elemento completo, pero no quiero eso. Solo quiero que se haga clic cuando hago clic en el cuadro, no en el texto descriptivo al lado. – Oxymoron

+0

podría usar una etiqueta adicional, solo la casilla de verificación, y luego crear etiquetas, ... no es tan agradable de resolver pero funciona:> – Tyzak

Respuesta

7

Bueno, es bastante feo, pero se podía calcular ratón golpe coordina contra rectángulos de artículos enganchando en CheckedListBox.MouseDown y CheckedListBox.ItemCheck como la siguiente

/// <summary> 
/// In order to control itemcheck changes (blinds double clicking, among other things) 
/// </summary> 
bool AuthorizeCheck { get; set; } 

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) 
{ 
    if(!AuthorizeCheck) 
     e.NewValue = e.CurrentValue; //check state change was not through authorized actions 
} 

private void checkedListBox1_MouseDown(object sender, MouseEventArgs e) 
{ 
    Point loc = this.checkedListBox1.PointToClient(Cursor.Position); 
    for (int i = 0; i < this.checkedListBox1.Items.Count; i++) 
    { 
     Rectangle rec = this.checkedListBox1.GetItemRectangle(i); 
     rec.Width = 16; //checkbox itself has a default width of about 16 pixels 

     if (rec.Contains(loc)) 
     { 
      AuthorizeCheck = true; 
      bool newValue = !this.checkedListBox1.GetItemChecked(i); 
      this.checkedListBox1.SetItemChecked(i, newValue);//check 
      AuthorizeCheck = false; 

      return; 
     } 
    } 
} 
+0

Sí, como dije en el PO, también estaba pensando en algo como esto, pero como no me siento muy bien, comencé a buscar alternativas :) – Oxymoron

+2

¡Gracias, simplemente funciona! Algunas optimizaciones son posibles, ¡pero la idea funciona! – nightcoder

0

El texto para una casilla de verificación en un CheckedListBox se representa de forma predeterminada es colocar una etiqueta HTML después de la entrada de casilla de verificación y establecer el atributo "para" de la etiqueta en el ID de la casilla de verificación.

Cuando una etiqueta indica un elemento que es "para", al hacer clic en esa etiqueta le dice al navegador que se centre en ese elemento, que es lo que está viendo.

Dos opciones son renderizar su propia lista con controles y texto CheckBox separados (no como la propiedad Text del CheckBox, ya que hace lo mismo que CheckBoxList) si la lista es estática o usar algo así como un Repeater si la lista es dinámica

+0

No es un formulario web, sino un winform :) Pero entiendo su opinión. El enfoque está bien y en realidad lo que quiero, simplemente no quiero que se marque la casilla de verificación al hacer clic en el elemento en sí. Parece que voy a jugar con un control personalizado :) – Oxymoron

+0

Ok, es difícil saber cuándo solo había C# y CheckedListBox como las etiquetas. Seguí adelante y agregué winforms. –

9

Sé que este hilo es un poco viejo, pero yo don' creo que es un problema de ofrecer otra solución:

private void checkedListBox1_MouseClick(object sender, MouseEventArgs e) 
{ 
    if ((e.Button == MouseButtons.Left) & (e.X > 13)) 
    { 
     this.checkedListBox1.SetItemChecked(this.checkedListBox1.SelectedIndex, !this.checkedListBox1.GetItemChecked(this.checkedListBox1.SelectedIndex)); 
    } 
} 

(con el valor de CheckOnClick = True).

Puede usar esa cosa con el rectángulo, pero ¿por qué hacerlo más complejo?

5

Otra solución es simplemente usar un Treeview.
Establezca CheckBoxes en verdadero, ShowLines en falso y ShowPlusMinus en falso y tiene básicamente lo mismo que un CheckedListBox. Los elementos solo se verifican cuando se hace clic en la casilla de verificación real.

CheckedListBox es mucho más simple, pero TreeView ofrece muchas opciones que pueden ser más adecuadas para su programa.

0

Pruebe esto. Declare iLastIndexClicked como una variable int de nivel de formulario.

private void chklst_MouseClick(object sender, MouseEventArgs e) 
{ 
    Point p = chklst.PointToClient(MousePosition); 
    int i = chklst.IndexFromPoint(p); 
    if (p.X > 15) { return; } // Body click. 
    if (chklst.CheckedIndices.Contains(i)){ return; } // If already has focus click anywhere works right. 
if (iLastIndexClicked == i) { return; } // native code will check/uncheck 
    chklst.SetItemChecked(i, true); 
    iLastIndexClicked = i; 
} 

sólo la comprobación para ver si el usuario hace clic en el extremo izquierdo de 15 píxeles de la lista activado (el área casilla de verificación) trabaja en todo momento excepto volver a comprobar un elemento seleccionado actualmente. Almacenar el último índice y salir sin cambiar permite que el código nativo lo maneje apropiadamente, tratando de configurarlo para que se active, en ese caso lo enciende y simplemente se apaga cuando se ejecuta el código "ItemCheck".

Cuestiones relacionadas