Как установить событие click для формы?

У меня есть форма ac # (назовем это MainForm) с рядом пользовательских элементов управления. Я хотел бы, чтобы метод MainForm.OnClick () запускался в любое время, когда кто-то нажимает на форму независимо от того, был ли щелчок на форме или был щелчок на одном из настраиваемых элементов управления. Я ищу поведение, подобное функции KeyPreview форм, за исключением щелчков мыши, а не нажатия клавиш.

В событии ControlAdded формы добавьте обработчик MouseClick к элементу управления с адресом события клика формы. Я не тестировал это, но это может сработать.

Private Sub Example_ControlAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles Me.ControlAdded AddHandler e.Control.MouseClick, AddressOf Example_MouseClick End Sub Private Sub Example_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick MessageBox.Show("Click") End Sub 

Я рекомендую создать базовую форму для других форм в приложении для наследования. Добавьте этот код в свою базовую форму, чтобы создать новое событие GlobalMouseClickEventHandler:

 namespace Temp { public delegate void GlobalMouseClickEventHander(object sender, MouseEventArgs e); public partial class TestForm : Form { [Category("Action")] [Description("Fires when any control on the form is clicked.")] public event GlobalMouseClickEventHander GlobalMouseClick; public TestForm() { InitializeComponent(); BindControlMouseClicks(this); } private void BindControlMouseClicks(Control con) { con.MouseClick += delegate(object sender, MouseEventArgs e) { TriggerMouseClicked(sender, e); }; // bind to controls already added foreach (Control i in con.Controls) { BindControlMouseClicks(i); } // bind to controls added in the future con.ControlAdded += delegate(object sender, ControlEventArgs e) { BindControlMouseClicks(e.Control); }; } private void TriggerMouseClicked(object sender, MouseEventArgs e) { if (GlobalMouseClick != null) { GlobalMouseClick(sender, e); } } } } 

Это решение будет работать не только для элементов управления верхнего уровня, но и вложенных элементов управления, таких как элементы управления, расположенные внутри панелей.

Единственный способ, которым мне когда-либо удалось это сделать, – обработать событие [c] Click [/ c] для каждого элемента управления. Я не верю, что событие возбуждается до того, как управление обработает его.

В WPF есть «туннелирование» событий предварительного просмотра, которые предоставляют эту функциональность, но это действительно не помогает вам в WinForms.

Вы можете подключить все события управления, если хотите, и затем отслеживать этот путь. Я предполагаю, что есть какой-то uber fancy Win32 api способ заманить их в ловушку, но это сейчас вне меня.

  public Form1() { InitializeComponent(); HookEvents(); } private void HookEvents() { foreach (Control ctl in this.Controls) { ctl.MouseClick += new MouseEventHandler(Form1_MouseClick); } } void Form1_MouseClick(object sender, MouseEventArgs e) { LogEvent(sender, "MouseClick"); } // and then this just logs to a multiline textbox you have somwhere on the form private void LogEvent(object sender, string msg) { this.textBox1.Text = string.Format("{0} {1} ({2}) \n {3}", DateTime.Now.TimeOfDay.ToString(), msg, sender.GetType().Name, textBox1.Text ); } 

Результат – это что-то вроде этого, показывая все события и кто «отправил» их:

 14:51:42.3381985 MouseClick (Form1) 14:51:40.6194485 MouseClick (RichTextBox) 14:51:40.0100735 MouseClick (TextBox) 14:51:39.6194485 MouseClick (Form1) 14:51:39.2131985 MouseClick (RichTextBox) 14:51:38.8694485 MouseClick (Button) 

НТН.

Ловить щелчок на открытом пространстве в форме легко, но чтобы получить щелчок, который на самом деле находится на элементе управления, вам понадобится сотрудничество этого элемента управления, чтобы отправить его в форму.

Одна из возможностей состоит в том, чтобы поместить прозрачный контроль над всей формой и принять клики на них, справиться с ними, а затем передать их на соответствующий элемент управления под ним.

Это общая закономерность в развитии, называемая шаблоном Observer. Существует множество примеров шаблонов Observer, а c # здесь – 1 пример http://msdn.microsoft.com/en-us/library/ms954621.aspx, но у вас хороший google.