Environnement: .NET Framework 2.0, VS 2008.
J'essaie 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 alternativement à la forme de niveau supérieur). Je peux le faire en créant des gestionnaires pour ces événements dans les instances 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, car les méthodes qui déclenchent les événements dans le contrôle parent sont protégées et je n'ai pas de qualificateur pour le contrôle parent:
Impossible d'accéder au membre protégé
System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)
via un qualificatif de typeSystem.Windows.Forms.Control
; Le qualificatif doit être de typeTheProject.NoCaptureLabel
(Ou dérivé de celui-ci).
Je cherche à remplacer la méthode WndProc
du contrôle dans ma sous-classe, mais j'espère que quelqu'un pourra me donner une solution plus propre.
Oui. Après beaucoup de recherches, j'ai trouvé l'article "Floating Controls, tooltip-style" , qui utilise WndProc
pour changer le message de WM_NCHITTEST
à HTTRANSPARENT
, rendant le Control
transparent aux événements de la souris.
Pour cela, créez un contrôle hérité de Label
et ajoutez simplement 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);
}
}
J'ai testé cela dans Visual Studio 2010 avec .NET Framework 4 Client Profile.
Vous devez écrire une méthode publique/protégée dans votre classe de base qui déclenchera l'événement pour vous. Appelez ensuite cette méthode à partir de la classe dérivée.
OR
C'est ce que tu veux?
public class MyLabel : Label
{
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
//Do derived class stuff here
}
}
Le WS_EX_TRANSPARENT
le style de fenêtre étendue fait cela (c'est ce que les info-bulles sur place utilisent). Vous voudrez peut-être envisager d'appliquer ce style plutôt que de coder de nombreux gestionnaires pour le faire pour vous.
Pour ce faire, remplacez 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: