Manipulando um clique para todos os controles em um formulário

Eu tenho um .NET UserControl (FFX 3.5). Esse controle contém vários controles filho – um painel, alguns labels, um casal TextBoxes e outro controle personalizado. Eu quero lidar com um clique direito em qualquer lugar no controle base – então um clique direito em qualquer controle de criança (ou filho de uma criança no caso do painel). Eu gostaria de fazê-lo para que seja sustentável se alguém fizer alterações no Controle sem precisar conectar os manipuladores aos novos Controles, por exemplo.

Primeiro, tentei replace o WndProc, mas, como suspeitava, só recebo mensagens por cliques no Formulário diretamente, e não por nenhum de seus filhos. Como semi-hack, adicionei o seguinte após InitializeComponent:

foreach (Control c in this.Controls) { c.MouseClick += new MouseEventHandler( delegate(object sender, MouseEventArgs e) { // handle the click here }); } 

Isso agora recebe cliques para controles que suportam o evento, mas os labels, por exemplo, ainda não recebem nada. Existe uma maneira simples de fazer isso que eu estou negligenciando?

Se os labels estiverem em um subcontrole, você terá que fazer isso de forma recursiva:

 void initControlsRecursive(ControlCollection coll) { foreach (Control c in coll) { c.MouseClick += (sender, e) => {/* handle the click here */}); initControlsRecursive(c.Controls); } } /* ... */ initControlsRecursive(Form.Controls); 

Para manipular um evento MouseClick para clique direito em todos os controles em um UserControl personalizado:

 public class MyClass : UserControl { public MyClass() { InitializeComponent(); MouseClick += ControlOnMouseClick; if (HasChildren) AddOnMouseClickHandlerRecursive(Controls); } private void AddOnMouseClickHandlerRecursive(IEnumerable controls) { foreach (Control control in controls) { control.MouseClick += ControlOnMouseClick; if (control.HasChildren) AddOnMouseClickHandlerRecursive(control.Controls); } } private void ControlOnMouseClick(object sender, MouseEventArgs args) { if (args.Button != MouseButtons.Right) return; var contextMenu = new ContextMenu(new[] { new MenuItem("Copy", OnCopyClick) }); contextMenu.Show((Control)sender, new Point(args.X, args.Y)); } private void OnCopyClick(object sender, EventArgs eventArgs) { MessageBox.Show("Copy menu item was clicked."); } }