2010-08-02 15 views
5

He vuelto a enviar esta pregunta debido a la imposibilidad de resolver el problema (original here).MouseLeave El evento se dispara cuando se mueve sobre ScrollBar del control

En el TreeView, ListBox, o parece que desde mi google busca cualquier cosa con ScrollBar, ScrollBar no se considera una parte del control.

Tengo un TreeView que estoy poniendo en un control personalizado, y es Dock Fill. Entonces funciona como una TreeView personalizada que tiene toda nuestra lógica para administrarla en un solo lugar.

En partes de nuestro programa, lo deslizamos en función de un evento MouseEnter y lo volvemos a deslizar en un evento MouseLeave; sin embargo, estamos utilizando una TreeView de biblioteca de terceros para esto, que he tenido la tarea de reemplazar.

Así que he trasladado todo a Windows TreeView, pero no puedo encontrar una forma de capturar el MouseLeave de manera confiable, solo si deja todo el TreeView, la barra de desplazamiento incluida.

He visto una solución hackish de envolverlo en un panel con varios píxeles y capturar el MouseLeave del panel, pero no creo que esto sea lo que Microsoft pretendía que hiciéramos en esta situación.

En breve:

El ScrollBar no se dispara MouseEnter o MouseLeave para el control, y que hace que el uso MouseEnter/MouseLeave para deslizarse a cabo el control inutilizable ya que el usuario no puede utilizar la barra de desplazamiento.

¿Cuál es la forma preferida de manejar esta situación?

En la pregunta anterior recibí consejo para usar Spy ++ e intentar adjuntarlo a WndProc() para manejar MouseEnter/MouseLeave para ScrollBar.

Sin embargo, esto no funcionó ya que los mensajes que Spy ++ mostró no se activaron en el WndProc() a nivel de formulario o nivel de control. Es como si .NET simplemente no pudiera ver ScrollBar.

El uso de WndProc() también parece poco realista para una solicitud tan simple, ¿hay alguna otra manera de hacerlo, o si WndProc() es la única manera, alguien realmente ha podido lograr esto y mostrarme cómo?

Respuesta

4

No hay una solución limpia para esto. El truco del panel tampoco funciona, se perderá por completo cuando el usuario mueva el mouse rápidamente.

Punt. Una vez que obtienes MouseEnter, inicia un temporizador de 200 ms. En el evento Tick, compruebe si el mouse todavía está sobre la vista de árbol. Por ejemplo:

private void treeView1_MouseEnter(object sender, EventArgs e) { 
     timer1.Enabled = true; 
     treeView1.Width = 220; 
    } 

    private void timer1_Tick(object sender, EventArgs e) { 
     Point pos = treeView1.PointToClient(Cursor.Position); 
     if (!treeView1.DisplayRectangle.Contains(pos)) { 
      timer1.Enabled = false; 
      treeView1.Width = 50; 
     } 
    } 

El evento Application.Idle funciona demasiado por cierto, solo un poquito más incómodo.

+0

Esto funcionó perfectamente, gracias! –

2

Gracias por la sugerencia de tener el mismo problema, modifiqué el evento timer_Tick para incluir la barra de desplazamiento agregando 20 al ancho.

private void tmrListPos_Tick(object sender, EventArgs e) 
    { 
     Point posLB = clbPlants.PointToClient(Cursor.Position); 
     Rectangle rectPlants = clbPlants.DisplayRectangle; 
     rectPlants.Width = rectPlants.Size.Width + 20; 
     if (!rectPlants.Contains(posLB)) 
     { 
      tmrListPos.Enabled = false; 
      clbPlants.Size = clbPlants.MinimumSize; 
     } 
    } 
Cuestiones relacionadas