Ich habe ein C# -Formular (nennen wir es MainForm) mit einer Reihe von benutzerdefinierten Steuerelementen darauf. Ich möchte, dass die MainForm.OnClick() -Methode immer dann ausgelöst wird, wenn jemand auf das Formular klickt, unabhängig davon, ob der Klick auf dem Formular erfolgt ist oder ob der Klick auf einem der benutzerdefinierten Steuerelemente erfolgt ist. Ich suche nach einem ähnlichen Verhalten wie die KeyPreview-Funktion von Formularen, mit Ausnahme von Mausklicks anstelle von Tastendrücken.Wie lege ich ein Click-Ereignis für ein Formular fest?
Antwort
Fügen Sie im ControlAdded-Ereignis des Formulars dem Steuerelement einen MouseClick-Handler mit der Adresse des click-Ereignisses des Formulars hinzu. Ich habe das nicht getestet, aber es könnte funktionieren.
Ein Klick auf einen offenen Bereich im Formular ist einfach, aber um einen Klick zu erhalten, der tatsächlich auf einem Steuerelement ist, benötigen Sie die Zusammenarbeit dieses Steuerelements, um es an das Formular zu senden.
Eine Möglichkeit besteht darin, ein transparentes Steuerelement über das gesamte Formular zu platzieren und Klicks darauf zu akzeptieren, mit ihnen umzugehen und sie dann an das richtige Steuerelement darunter zu übergeben.
Ich habe das Gefühl, dass es eine elegantere Lösung als diese geben muss. – Mykroft
Dies ist ein übliches Muster in der Entwicklung, das Observer-Muster genannt wird. Es gibt viele Beispiele von Observer-Mustern und C# hier ist 1 Beispiel http://msdn.microsoft.com/en-us/library/ms954621.aspx, aber haben Sie eine gute google um.
Die einzige Möglichkeit, die ich jemals geschafft habe, ist die Behandlung des [c] Click [/ c] -Ereignisses jedes Steuerelements. Ich glaube nicht, dass das Ereignis ausgelöst wird, bevor es von der Steuerung verarbeitet wird.
In WPF gibt es "Tunneling" Vorschau-Ereignisse, die diese Funktionalität bieten, aber das hilft Ihnen nicht wirklich in WinForms.
Nun, es ist zu spät, jetzt zu WPF zu wechseln, aber ich werde ernsthaft darüber nachdenken, es in Zukunft zu verwenden. – Mykroft
Sie können alle Ereignisse des Steuerelements haken, wenn Sie möchten, und dann auf diese Weise überwachen. Ich nehme an, es gibt einige übermäßig Win32 api Weg, sie alle zu fangen, aber das ist im Moment über mich.
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
);
}
Der Ausgang ist so etwas, alle Ereignisse zeigt, und die "gesendet", um sie nach oben:
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.
Ich empfehle das Erstellen eines Basisformulars für die anderen Formulare in Ihrer Anwendung zu erben. Fügen Sie diesen Code auf Ihre Basis bildet ein neues Ereignis erstellen GlobalMouseClickEventHandler genannt:
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);
}
}
}
}
Diese Lösung funktioniert nicht nur für die Top-Level-Kontrollen, aber auch Kontrollen verschachtelt wie Kontrollen innerhalb der Platten angeordnet.
Vielen Dank! Eine einfache und elegante Lösung. Ich frage mich, warum es nicht so etwas wie "KeyPreview" für Mausklicks gibt –
- 1. Wie lege ich ein Google-Suchergebnisfenster fest?
- 2. Wie lege ich ein Hintergrundbild für eine gruppierte Tabellenansicht fest?
- 3. Wie lege ich Titel für UIBarButtonItem fest?
- 4. Wie lege ich ein globales HttpWebRequest Timeout fest?
- 5. Wie lege ich ein HTML-Klassenattribut in Markdown fest?
- 6. Wie lege ich ein benutzerdefiniertes Symbol für ein statisches UIApplicationShortcutItem in meiner iOS 9 App fest?
- 7. Wie lege ich Standardvariablen für gebundene Formulare fest?
- 8. Wie lege ich Standard-Widget-Attribute für ein Django ModelForm fest?
- 9. Wie lege ich den ersten Responder fest?
- 10. Wie lege ich eine Rückwärtsauswahl fest?
- 11. Wie lege ich Smarttags für meine Steuerung fest?
- 12. Wie lege ich einen Standardpinsel für SyntaxHighlighter fest?
- 13. Wie lege ich eine eindeutige ID für Checkboxen in einem Multi-Record-Rails-Formular fest?
- 14. Wie lege ich Laravel Carbon Zeitzone für Zeitstempel fest?
- 15. Wie lege ich eine CSS-Regel für zwei Tags fest?
- 16. Wie lege ich den li Stil fest?
- 17. Wie lege ich den Wert XamDateTimeEditor fest?
- 18. Wie lege ich eine bedingte Kompiliervariable fest?
- 19. Wie lege ich eine Dateierweiterung fest?
- 20. Wie lege ich ein anderes Thema für das Dropdown-Menü eines Spinner fest?
- 21. Wie lege ich die Mindesthöhe für ein Div in IE7 fest?
- 22. Wie lege ich eine Standardschriftart und -größe für ein Steuerelement in Visual Studio fest?
- 23. Wie lege ich die Standardeinstellungen (Sprache & Tastatur) für ein Android AVD (SDK 2.1 & 2.2) fest
- 24. Wie lege ich das richtige anfängliche Gebietsschema für ein C++ - Programm unter Windows fest?
- 25. Wie lege ich die Visual Studio Installer-Bedingungen fest?
- 26. Wie lege ich den Benutzeragenten für Rubys RestClient fest?
- 27. Wie lege ich das Bild für VideoCastControllerActivity fest
- 28. Wie lege ich den Protokollierlevel für HikariCP fest?
- 29. Wie lege ich verschiedene Layouts für Hoch- und Querformat fest?
- 30. Wie lege ich das Datum für eine Datumsauswahl fest?
Dies scheint immer noch ein bisschen ein Hack zu sein, aber das scheint die beste Option zu sein, die ich habe. – Mykroft