Mouseenter sur un panel contenant pleins de controls [Résolu]

Signaler
Messages postés
4
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
10 avril 2006
-
Messages postés
4
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
10 avril 2006
-
Bonjour.

J'ai un panel auquel j'ajoute dynamiquement des controls. Ces controls ont eux meme des controls.

J'aimerai pouvoir changer l'opacite de mon control principal (et donc des controls fils) sur un mouseenter/mouseleave. Pour cela je m'abonne aux evenements mouseenter/mouseleave de mon control principal.

Le probleme c'est que mes controls fils prennent toute la largeur de mon control principal. Lorsque je met ma souris dans mon control principal l'evenement mouseenter n'est pas declenche car ma souris est directement dans un contorl fils.

J'aimerai trouver une autre methode que d'abonner tous mes controls, et sous controls aux evenements mouseenter/mouseleave.

Quelqu'un sait comment faire?

Merci.

2 réponses

Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
85
Salut,

Une "bidouille" est possible en utilisant un filtre de messages (cf /library/fre/cpref/html/frlrfSystemWindowsFormsIMessageFilterClassTopic.asp IMessageFilter)

La classe implémentant =/library/fre/cpref/html/frlrfSystemWindowsFormsIMessageFilterClassTopic.asp IMessageFilter :
class MouseEnterLeaveMessageFilter : IMessageFilter
{
private const int WM_MOUSEHOVER = 0x02A1;
private const int WM_MOUSELEAVE = 0x02A3;

public MouseEnterLeaveMessageFilter ( Control mainCtrl )
{
m_mainCtrl = mainCtrl;
}

private Control m_mainCtrl;
// sera utilisé pour determiner si on est resorti du controle precedent afin d'eviter une rafale de "Hover"
private bool m_leaved = true;

public bool PreFilterMessage(ref Message m)
{
// récupération du controle (si c'est est un)
Control ctrl = Control.FromHandle(m.HWnd);

if ( ctrl == null )
return false; // pas un controle, fin du traitement

// si le controle est notre conteneur ou un de ses enfants
if ( ctrl.Handle == m_mainCtrl.Handle || m_mainCtrl.Controls.Contains(ctrl))
{
switch ( m.Msg )
{
case WM_MOUSEHOVER:
if ( m_leaved )
{
MessageBox.Show("Enter " + ctrl.Name);
m_leaved = false;
}
break;

case WM_MOUSELEAVE:
MessageBox.Show("Leave " + ctrl.Name);
m_leaved = true;
break;
}
}

return false;
}

private void m_mainCtrl_Disposed(object sender, EventArgs e)
{
// si notre controle à surveiller est detruit, on "auto supprime" le filtre
Application.RemoveMessageFilter(this);
}
}

Exemple d'ajout :
private void Form1_Load(object sender, System.EventArgs e)
{
Application.AddMessageFilter(new MouseEnterLeaveMessageFilter(panel1));
}

Il reste probablement de l'optimisation à faire mais je pense que li'dée générale y est :-)

Cocoricoooooooo !!!!
coq
MVP Visual C#
Messages postés
4
Date d'inscription
mardi 31 mai 2005
Statut
Membre
Dernière intervention
10 avril 2006

Hello.



merci pour ton aide!!!



Seul petit soucis, mon sous-control contient lui-meme des controls. De ce cote pas de soucis, je remplace "if
( ctrl.Handle == m_mainCtrl.Handle ||
m_mainCtrl.Controls.Contains(ctrl))" par quelque chose de plus
generique (une fonction recursive). J'ai juste un peu peur des
perfomances. A chaque deplacement de la souris, checker tous les
controls de mon application me semble assez enorme.