Registrar todos los clics de botones en la aplicación Win Forms

Estoy buscando agregar una statement de registro para cada clic en el botón de WinForms en el que el usuario haga clic, e idealmente, un identificador del formulario principal (como la barra de título). He visto publicaciones que registran todos los clics del mouse, pero estoy interesado en solo registrar los clics de los botones. He leído la respuesta aceptada aquí y la he adaptado:

public class ButtonLogger { private static readonly ILog Logger = LogManager.GetLogger(typeof(ButtonLogger)); public static void AttachButtonLogging(Control.ControlCollection controls) { foreach (var button in controls.OfType

Esta clase se usa al final de un constructor en un formulario, por ejemplo:

 ButtonLogger.AttachButtonLogging(this.Controls); 

El problema al que me enfrento es que la propiedad Controls no parece tener una referencia a mis botones. Presumiblemente esto se debe a que los botones no se agregan directamente al formulario, sino a otro control que se encuentra en la propiedad Controles. Sin embargo, la propiedad Controls solo contiene un control único, un ToolStrip.

¿Hay alguna forma de poder utilizar todos los botones en un formulario, independientemente de su contenedor principal? Mi objective final es agregar una statement de registro a mis botones, por lo que si esto se puede lograr de otra manera además de los métodos de evento de clic de botón, también estoy abierto a eso

Creo que necesitas buscar botones recursivamente:

 public static void AttachButtonLogging(Control.ControlCollection controls) { foreach (var control in controls.Cast()) { if (control is Button) { Button button = (Button)control; button.Click += LogButtonClick; } else { AttachButtonLogging(control.Controls); } } } 

Una cosa que podría considerar es crear una subclase de la clase de Button estándar y dejar que los botones mismos hagan el registro. Por supuesto, tendría que ir y sustituir todos los botones en la aplicación para su propia implementación, pero debería ser posible hacerlo con una búsqueda global + reemplazar.

Aquí hay una implementación de ejemplo:

 public class LoggerButton : Button { private static readonly ILog Logger = LogManager.GetLogger(typeof(LoggerButton)); protected override void OnClick(EventArgs e) { base.OnClick(e); Logger.InfoFormat("Button clicked: {0} ({1})", this.Text, this.Parent.Text); } }