2010-10-09 18 views
10

¿Cómo hago para que una vista de lista no compruebe automáticamente un elemento cuando hago doble clic en él?Winforms ListView - Detener comprobación automática al hacer doble clic en

puedo intentar enganchar en el caso MouseDoubleClick, y establezca la propiedad Checked en falso, pero que se siente como un poco de un truco. También realizo un cálculo razonablemente caro cuando un elemento está realmente verificado, y no quiero que este código se ejecute con un doble clic. Con el enganche de evento anterior, los eventos ItemCheck & ItemChecked se generan antes de que se maneje el doble clic.

¿Hay alguna solución elegent para esto?

Respuesta

11

elegante no es normalmente la palabra que salta a la mente cuando se tiene que cortar la forma en que funciona nativas de control de Windows, pero eso es lo que se requiere aquí. Considere si realmente desea que su control se comporte de manera diferente de las listas de todos los demás programas.

Agregue una nueva clase a su proyecto y pegue el código que se muestra a continuación. Compilar. Coloque el nuevo control desde la parte superior de la caja de herramientas en su formulario.

using System; 
using System.Windows.Forms; 

class MyListView : ListView { 
    protected override void WndProc(ref Message m) { 
     // Filter WM_LBUTTONDBLCLK 
     if (m.Msg != 0x203) base.WndProc(ref m); 
    } 
} 
+1

Hmmm, esta es la forma menos hacky de hacerlo ... esto funciona, especialmente si llamas al método OnMouseDoubleClick desde WndProc cuando se golpea el mensaje. Esto pasa por alto el manejo de Check, mientras se mantiene el evento de doble clic que es lo que quería hacer. ¡Gracias! – Gareth

+0

Este tipo tiene un reemplazo similar, donde el doble clic también continúa funcionando: http://blogs.msdn.com/b/hippietim/archive/2006/03/27/562256.aspx –

11

Si no desea desactivar completamente los mensajes de DoubleClick, simplemente desactive el comportamiento de autocheck. En su lugar, puede hacer lo siguiente:

public class NoDoubleClickAutoCheckListview : ListView 
{ 
    private bool checkFromDoubleClick = false; 

    protected override void OnItemCheck(ItemCheckEventArgs ice) 
    { 
     if (this.checkFromDoubleClick) 
     { 
      ice.NewValue = ice.CurrentValue; 
      this.checkFromDoubleClick = false; 
     } 
     else 
      base.OnItemCheck(ice); 
    } 

    protected override void OnMouseDown(MouseEventArgs e) 
    { 
     // Is this a double-click? 
     if ((e.Button == MouseButtons.Left) && (e.Clicks > 1)) { 
      this.checkFromDoubleClick = true; 
     } 
     base.OnMouseDown(e); 
    } 

    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     this.checkFromDoubleClick = false; 
     base.OnKeyDown(e); 
    } 
} 
+0

excelente, cubre exactamente mis necesidades y funciona bien para mí, gracias! –

2

Tuve un problema similar, y así es como lo manejé. Básicamente si el elemento está marcado mientras la coordenada x del cursor es mayor que la coordenada x de la casilla de verificación, entonces cancelo el cheque (porque significa que se llamó al cheque cuando el usuario hizo doble clic en el elemento).

El margen de error con el número 22 es sólo si el usuario hace doble clic la derecha después de la casilla de verificación (muy difícil de hacer).

NOTA: Mi código se supone que el usuario no va a hacer doble clic en la casilla de verificación (ya sea el usuario hace doble clic el artículo o clics individuales en la casilla)

código sentimos es en VB :)

Private Sub lvComboLists_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles lvComboLists.ItemCheck 
    Dim i As Integer = CType(sender, ListView).PointToClient(Cursor.Position).X 
    If i > 22 Then 
     e.NewValue = e.CurrentValue 
    End If 
End Sub 
+1

Debe diferenciar entre las acciones del usuario y las acciones del programa para el evento ItemCheck. Lo hice agregando una variable booleana "MyDoing" en el formulario para permitir que pase la verificación originada por el programa. –

+1

He encontrado esta otra solución que parece incluso más simple (menos complicada): http://stackoverflow.com/questions/1406887/only-change-a-listviewitems-checked-state-if-the-checkbox-is-clicked –

1

utilizo un método mucho más simple de simplemente restablecer el valor de la casilla de verificación al estado original cambiando al contrario de lo que actualmente es:

Private Sub lst_Images_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lst_Images.DoubleClick 
     Dim fIndex As Integer = Me.lst_Images.SelectedIndices(0) 
     ' Undo the changing of the checkbox's state by the double click event. 
     lst_Images.Items(fIndex).Checked = Not lst_Images.Items(fIndex).Checked 

     ' Call the viewer form 
     Dim fViewer As New Image_Edit(fIndex) 
     fViewer.ShowDialog() 
     fViewer.Dispose() 
End Sub 
Cuestiones relacionadas