2009-01-23 15 views
5

Tengo una aplicación .NET 2.0 WinForms con una ToolStrip en mi formulario principal. A veces, los iconos de ToolStrip no responden al primer clic del mouse, por lo que tengo que hacer clic dos veces en el ícono. Es solo una ToolStrip estándar con varios iconos y textos de información sobre herramientas, no hago nada especial. ¿Es esto común?ToolStrip veces no responde a un clic del mouse

Respuesta

0

Si la ventana de la aplicación no tiene el foco, debe hacer clic dos veces en el botón ToolStrip. El primer clic establece el foco en la ventana, el segundo aumenta el evento de clic. Este es (desafortunadamente) el comportamiento predeterminado y es por diseño. Microsoft Word muestra el mismo comportamiento (aunque .NET ToolStrip no tiene el mismo control).

+5

Existe una diferencia entre MS Word y los botones .NET ToolStrip: cuando la aplicación de Word no tiene el foco, los menús y símbolos en Word no se resaltan con el cursor del mouse. Solo se resaltan cuando Word tiene el foco. Por otro lado, .NET ToolStrip resalta sus botones incluso cuando la aplicación no tiene el foco, simulando que un clic del mouse activaría el botón inmediatamente. –

1

He tenido eso en otros entornos de desarrollo (VB6), y resultó ser porque el primer clic estaba siendo absorbido por la barra de herramientas para adquirir el foco. O, para decirlo de otra manera, la barra de herramientas no respondería a un clic en hasta que tuvo el foco. Para probar esto, intente hacer clic en una parte vacía de la barra de herramientas antes de hacer clic en el botón. Si nunca tiene que hacer clic dos veces en el botón después de hacer clic en la barra de herramientas, ese podría ser el problema. Creo que lo superaron (y esto fue hace unos años, así que disculpen el truco) fue programáticamente dar el foco a la barra de herramientas en el evento MouseOver.

+0

Gracias, de todos modos parece que este no es mi caso. Si configuro el foco en otro control (digamos un botón fuera de ToolStrip) y luego hago clic en un botón ToolStrip, se acepta el clic. – user20353

20

Tuve el mismo problema algunas veces, y encontré una solución en Rick Brewster's blog. La idea es sobrescribir 'WndProc' en una clase derivada ToolStripEx. El núcleo de esta solución es el siguiente:

protected override void WndProc(ref Message m) 
{ 
    base.WndProc(ref m); 

    if (m.Msg == NativeConstants.WM_MOUSEACTIVATE && 
     m.Result == (IntPtr)NativeConstants.MA_ACTIVATEANDEAT) 
    { 
     m.Result = (IntPtr)NativeConstants.MA_ACTIVATE; 
    } 
} 
+0

Esto es perfecto, mejor que cualquiera de las alternativas que he probado. – user169771

+0

Solución similar en: https://stackoverflow.com/a/4967537/767664 – Pedro77

1

Usted puede crear su propia clase que hereda de ToolStrip y el uso de una propiedad personalizada ClickThrough para cambiar el comportamiento o desactivar:

Public Class ToolStripExtended : Inherits ToolStrip 
    Private Const WM_MOUSEACTIVATE As UInteger = &H21 
    Private Const MA_ACTIVATE As UInteger = 1 
    Private Const MA_ACTIVATEANDEAT As UInteger = 2 
    Private Const MA_NOACTIVATE As UInteger = 3 
    Private Const MA_NOACTIVATEANDEAT As UInteger = 4 

    Private _clickThrough As Boolean = False 

    Public Sub New() 
     MyBase.New() 
    End Sub 

    ''' <summary> 
    ''' Gets or sets whether the ToolStripEx honours item clicks when its containing form does 
    ''' not have input focus. 
    ''' </summary> 
    ''' <remarks> 
    ''' Default value is false, which is the same behaviour provided by the base ToolStrip class. 
    ''' </remarks> 
    Public Property ClickThrough() As Boolean 
     Get 
      Return Me._clickThrough 
     End Get 

     Set(value As Boolean) 
      Me._clickThrough = value 
     End Set 
    End Property 

    Protected Overrides Sub WndProc(ByRef m As Message) 
     MyBase.WndProc(m) 

     If _clickThrough AndAlso m.Msg = WM_MOUSEACTIVATE AndAlso m.Result = New IntPtr(MA_ACTIVATEANDEAT) Then 
      m.Result = New IntPtr(MA_ACTIVATE) 
     End If 
    End Sub 
End Class 
Cuestiones relacionadas