Проходные события мыши для родительского контроля
Среда:.NET Framework 2.0, VS 2008.
Я пытаюсь создать подкласс определенных элементов управления .NET(label, panel), которые пройдут через определенные события мыши (MouseDown
, MouseMove
, MouseUp
) в свой родительский элемент управления (или, альтернативно, вверху -уровневая форма). Я могу сделать это, создав обработчики для этих событий в экземплярах стандартных элементов управления, например:
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);
}
}
Я не могу переместить обработчик событий в подкласс элемента управления, потому что методы, которые поднимают события в родительском элементе управления, защищены и у меня нет определителя для родительского элемента управления:
Невозможно получить доступ к защищенному элементу System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)
через квалификатор типа System.Windows.Forms.Control
; квалификатор должен иметь тип TheProject.NoCaptureLabel
(или полученный из него).
Я рассматриваю переопределение метода WndProc
элемента управления в моем подклассе, но, надеюсь, кто-то может дать мне более чистое решение.
Ответы
Ответ 1
Да. После многого поиска я нашел статью "Плавающие элементы управления, стиль подсказки" , в которой используется WndProc
для изменения сообщения от WM_NCHITTEST
до HTTRANSPARENT
, делая Control
прозрачным для событий мыши.
Для этого создайте элемент управления, унаследованный от Label
, и просто добавьте следующий код.
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);
}
}
Я тестировал это в Visual Studio 2010 с .NET Client 4. Клиентский профиль.
Ответ 2
Вам нужно написать общедоступный/защищенный метод в базовом классе, который поднимет для вас событие. Затем вызовите этот метод из производного класса.
ИЛИ
Это то, что вы хотите?
public class MyLabel : Label
{
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
//Do derived class stuff here
}
}
Ответ 3
Расширяемый стиль WS_EX_TRANSPARENT
на самом деле делает это (это то, что используют всплывающие подсказки на месте). Вы можете захотеть применить этот стиль, а не кодировать множество обработчиков, чтобы сделать это за вас.
Чтобы сделать это, переопределите метод CreateParams
:
protected override CreateParams CreateParams
{
get
{
CreateParams cp=base.CreateParams;
cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
Для дальнейшего чтения: