Tengo un formulario C# (llamémoslo MainForm) con una serie de controles personalizados sobre él. Me gustaría que el método MainForm.OnClick() se active cada vez que alguien haga clic en el formulario independientemente de si el clic sucedió en el formulario o si el clic fue en uno de los controles personalizados. Estoy buscando un comportamiento similar a la característica KeyPreview de los formularios, excepto por los clics del mouse en lugar de presionar las teclas.¿Cómo configuro un evento de clic para un formulario?
Respuesta
En el evento ControlAdded del formulario, agregue un controlador MouseClick al control, con la dirección del evento click del formulario. No lo he probado, pero podría funcionar.
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
Hacer clic en un espacio abierto en el formulario es fácil, pero para obtener un clic que esté realmente en un control, necesitará la cooperación de ese control para enviarlo al formulario.
Una posibilidad es colocar un control transparente sobre todo el formulario, y aceptar clics sobre eso, tratar con ellos, y luego pasarlos al control adecuado debajo.
Creo que debe haber una solución más elegante que esta. – Mykroft
Este es un patrón común en el desarrollo, se llama el patrón Observer. Hay muchos ejemplos de patrones Observer y C# aquí hay 1 ejemplo http://msdn.microsoft.com/en-us/library/ms954621.aspx pero tiene un buen google alrededor.
La única forma en que he podido hacer esto es manejar el evento [c] Click [/ c] de cada control. No creo que el evento se haya planteado antes de que el control lo procese.
En WPF, hay eventos de vista previa "tunelización" que proporcionan esta funcionalidad, pero eso realmente no lo ayuda en WinForms.
Bueno, es demasiado tarde para cambiar a WPF ahora, pero tendré que considerar seriamente su uso en el futuro, supongo. – Mykroft
Puede enganchar todos los eventos del control, si lo desea, y luego monitorear de esa manera. Supongo que hay una gran manera de apostar Win32 para atraparlos a todos, pero eso está más allá de mí en este momento.
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
);
}
La salida es algo como esto, que muestra todos los eventos y que "enviado" a ellos:
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)
HTH.
Recomiendo crear un formulario base para que hereden los otros formularios en su aplicación. Añadir este código a su forma base para crear un nuevo evento llamado 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);
}
}
}
}
Esta solución va a trabajar no sólo para los controles de primer nivel, sino también anidado controles tales como controles colocados en el interior de los paneles.
¡Muchas gracias! Una solución simple y elegante. Me pregunto por qué no hay algo equivalente a 'KeyPreview' para los clics del mouse –
- 1. ¿Cómo vincular un evento para todas las entradas de formulario?
- 2. ¿Cómo tomar el evento onSubmit para un formulario?
- 3. agregando un evento de clic a fullcalendar
- 4. Activar un evento en `clic` y` enter`
- 5. Cómo agregar un evento de clic por nombre de clase?
- 6. Agregar un evento de clic a un elemento?
- 7. ¿Cómo disparo programáticamente un mx: evento de clic de botón?
- 8. Cómo puedo activar un evento de JavaScript, haga clic en
- 9. Un botón activando otros botones haga clic en el evento
- 10. ¿Cómo configuro la altura de un ComboBox?
- 11. enviar formulario al hacer clic en evento usando jquery
- 12. backbone.js - acceder a un modelo desde un evento de clic
- 13. ¿Cómo configuro un diálogo umanaged como el propietario de un formulario de WinForm?
- 14. ¿Cómo configuro log4j logging para un jar?
- 15. ¿Cómo configuro Go para usar un proxy?
- 16. Haga clic en evento en botón se activa al enviar un formulario con enter
- 17. jQuery mobile- ¿Para cada evento de toque en vivo debería haber un evento de clic equivalente?
- 18. Validar un formulario en el evento Click con validador jQuery
- 19. Esperar evento de clic para completar
- 20. ¿Cómo cancelar un formulario cerrar en Cerrar evento?
- 21. Cómo disparo un evento cuando se produce un clic fuera de un cuadro de diálogo
- 22. cómo desencadenar un evento de clic desde un iframe a un elemento de su elemento primario?
- 23. evento desencadenante teclado en un formulario con un campo
- 24. ¿Cómo restaurar un formulario mediante programación?
- 25. Secuencia de activación de evento para un botón de envío
- 26. ASP.NET: compruebe si hay un evento de clic en page_load
- 27. Activar un evento de clic con los parámetros
- 28. ¿Cómo acceder a un control de formulario para otro formulario?
- 29. Acordeón de JQuery - Desvincular clic en evento
- 30. Para mostrar un nuevo formulario al hacer clic en un botón en C#
Esto todavía parece ser un truco, pero esta parece ser la mejor opción que tengo. – Mykroft