Intercommunication événements de souris pour le contrôle des parents
-
23-08-2019 - |
Question
Environnement: .NET Framework 2.0, VS 2008
. Je suis en train de créer une sous-classe de certains contrôles .NET (étiquette, panneau), qui passera par certains événements de souris (MouseDown
, MouseMove
, MouseUp
) à son contrôle parent (ou bien à la forme de haut niveau). Je peux le faire en créant des gestionnaires pour ces événements dans les cas des contrôles standard, par exemple:.
public class TheForm : Form
{
private Label theLabel;
private void InitializeComponent()
{
theLabel = new Label();
theLabel.MouseDown += new MouseEventHandler(theLabel_MouseDown);
}
private void theLabel_MouseDown(object sender, MouseEventArgs e)
{
int xTrans = e.X + this.Location.X;
int yTrans = e.Y + this.Location.Y;
MouseEventArgs eTrans = new MouseEventArgs(e.Button, e.Clicks, xTrans, yTrans, e.Delta);
this.OnMouseDown(eTrans);
}
}
Je ne peux pas déplacer le gestionnaire d'événements dans une sous-classe du contrôle, parce que les méthodes qui soulèvent les événements dans le contrôle des parents sont protégés et je ne dispose pas d'un match de qualification pour le contrôle parent:
Impossible d'accéder
System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)
membre protégé par une qualification de typeSystem.Windows.Forms.Control
; le qualificatif doit être de typeTheProject.NoCaptureLabel
(ou dérivé de celui-ci).
Je cherche en redéfinissant la méthode WndProc
du contrôle dans mon sous-classe, mais nous espérons que quelqu'un peut me donner une solution plus propre.
La solution
Oui. Après beaucoup de recherches, je trouve l'article « Contrôles flottants, style infobulle » , qui utilise WndProc
pour modifier le message de WM_NCHITTEST
à HTTRANSPARENT
, ce qui rend le Control
transparent aux événements de souris.
Pour cela, créer un contrôle hérité de Label
et il suffit d'ajouter le code suivant.
protected override void WndProc(ref Message m)
{
const int WM_NCHITTEST = 0x0084;
const int HTTRANSPARENT = (-1);
if (m.Msg == WM_NCHITTEST)
{
m.Result = (IntPtr)HTTRANSPARENT;
}
else
{
base.WndProc(ref m);
}
}
Je l'ai testé dans Visual Studio 2010 avec .NET Framework 4 Client Profile.
Autres conseils
Vous devez écrire une méthode publique / protégée dans la classe de base qui soulèvera l'événement pour vous. Ensuite, appelez cette méthode de la classe dérivée.
ou
Est-ce que vous voulez?
public class MyLabel : Label
{
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
//Do derived class stuff here
}
}
Le style de fenêtre WS_EX_TRANSPARENT
étendue ne fait cela (c'est ce que infobulles en place utilisent). Vous voudrez peut-être envisager d'appliquer ce style plutôt que de coder beaucoup de gestionnaires à faire pour vous.
Pour ce faire, passer outre la méthode CreateParams
:
protected override CreateParams CreateParams
{
get
{
CreateParams cp=base.CreateParams;
cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
Pour en savoir plus: