Ich erstelle eine benutzerdefinierte Dropdown-Box, und ich möchte registrieren, wenn die Maus außerhalb der Dropdown-Box geklickt wird, um sie zu verbergen. Ist es möglich, einen Klick außerhalb eines Steuerelements zu erkennen? oder sollte ich einen Mechanismus auf dem enthaltenden Formular machen und nach einem Mausklick suchen, wenn eine Dropdown-Box geöffnet ist?
Ich verstehe schließlich, dass Sie nur schließen möchten, wenn der Benutzer darauf klickt. In diesem Fall sollte das Leave
-Ereignis nur funktionieren OK ... Aus irgendeinem Grund hatte ich den Eindruck, dass Sie möchten, dass die Maus geschlossen wird, wenn Sie die Maus außerhalb des benutzerdefinierten Dropdown-Menüs bewegen. Das Leave
-Ereignis wird immer dann ausgelöst, wenn das Steuerelement den Fokus verliert. Wenn der Benutzer auf etwas anderes klickt, wird es den Fokus verlieren, da das Objekt, auf das er geklickt hat, den Fokus erhält.
In der Dokumentation wird außerdem darauf hingewiesen, dass dieses Ereignis bei Bedarf die Steuerungskette auf und ab kaskadiert:
Die Ereignisse
Enter
undLeave
sind hierarchisch und kaskadieren die Stammkette auf und ab, bis das entsprechende Steuerelement erreicht ist. Angenommen, Sie haben ein Formular mit zwei GroupBox-Steuerelementen und jedes GroupBox-Steuerelement hat ein TextBox-Steuerelement. Wenn das Einfügemarke von einem Text zu dem anderen Textfeld verschoben wird, wird dasLeave
-Ereignis für das TextBox und das GroupBox ausgelöst und das% Co_de% -Ereignis wird für das andere GroupBox und das TextBox ausgelöst.
Das Überschreiben der Enter
-Methode Ihres UserControl ist die beste Methode, dies zu umgehen:
Und dann habe ich zu Testzwecken ein Formular erstellt, das den Dropdown-Befehl "UserControl on" anzeigt:
%Vor% Alles funktioniert perfekt mit dem obigen Code, außer für eine Sache: Wenn der Benutzer auf einen leeren Bereich des Formulars klickt, wird das UserControl nicht geschlossen. Hmm, warum nicht? Nun, weil die Form selbst den Fokus nicht will. Nur Steuerelemente können den Fokus erhalten, und wir haben nicht auf ein Steuerelement geklickt. Und weil nichts anderes den Fokus gestohlen hat, wurde das OnLeave
-Ereignis nie ausgelöst, was bedeutet, dass das UserControl nicht wusste, dass es sich selbst schließen sollte.
Wenn Sie das Benutzersteuerelement benötigen, um sich selbst zu schließen, wenn der Benutzer auf einen leeren Bereich im Formular klickt, benötigen Sie dafür spezielle Sonderfälle. Da Sie sagen, dass Sie nur über Klicks besorgt sind, können Sie einfach das Ereignis Leave
für das Formular behandeln und den Fokus auf ein anderes Steuerelement setzen:
Ja, dieser letzte Teil fühlt sich an wie ein Hack. Die bessere Lösung, wie bereits erwähnt, besteht darin, die Funktion Click
zu verwenden, um Windows zu instruieren um die Maus über das UserControl-Fenster zu halten. Die Eigenschaft SetCapture
des Steuerelements bietet einen noch einfacheren Weg mach das Gleiche.
Behandeln Sie das MouseDown
-Ereignis des Formulars oder überschreiben Sie das OnMouseDown
des Formulars.
Methode:
Und dann:
%Vor% Die Contains-Methode alt System.Drawing.Rectangle
kann verwendet werden, um anzugeben, ob
Ein Punkt ist in einem Rechteck enthalten. Die Bounds-Eigenschaft eines Controls ist
das äußere Rectangle
, das von den Kanten des Controls definiert wird. Der Standort
Eigenschaft des MouseEventArgs
ist der Punkt relativ zum Control welcher
empfing das Ereignis MouseDown
. Die Bounds-Eigenschaft eines Controls in einer Form ist
relativ zum Formular.
Technisch gesehen müssen Sie SetCapture () aufrufen / aufrufen, um empfangen zu können Klicken Sie auf Ereignisse, die außerhalb Ihrer Kontrolle passieren.
Aber in Ihrem Fall sollten Sie das Ereignis behandeln , wie @Martin vorschlägt, sollte ausreichen.
BEARBEITEN: Bei der Suche nach einem Anwendungsbeispiel für SetCapture()
stieß ich auf Control.Capture Eigenschaft, von der ich nicht wusste. Wenn Sie diese Eigenschaft verwenden, müssen Sie nichts p / aufrufen, was in meinem Buch immer eine gute Sache ist.
Sie müssen also Capture
auf true
setzen, wenn Sie das Dropdown-Menü einblenden. Dann bestimmen Sie, ob der Mauszeiger innerhalb des Steuerelements in Ihrem Click-Ereignishandler liegt. Ist dies nicht der Fall, setzen Sie Capture
zu false
und schließe das Dropdown.
Ich habe das selbst gemacht, und so habe ich es gemacht.
Wenn die Dropdown-Liste geöffnet ist, registrieren Sie ein Klickereignis im übergeordneten Formular des Steuerelements:
%Vor%Aber das dauert nur den halben Weg. Wahrscheinlich möchten Sie, dass das Dropdown-Menü auch geschlossen wird, wenn das aktuelle Fenster deaktiviert wird. Der zuverlässigste Weg, dies zu erkennen, war für mich ein Timer, der prüft, welches Fenster gerade aktiv ist:
%Vor%und
%Vor%Sie sollten den Timer natürlich nur laufen lassen, wenn das Dropdown sichtbar ist. Außerdem gibt es wahrscheinlich einige andere Ereignisse auf dem übergeordneten Formular, das Sie beim Öffnen des Dropdown-Menüs registrieren möchten:
%Vor%Vergessen Sie nicht, alle diese Ereignisse in der CloseDropDown-Methode aufzuheben:)
BEARBEITEN:
Ich habe vergessen, Sie sollten auch das Leave-Ereignis auf Ihrem Steuerelement registrieren, um zu sehen, ob ein anderes Steuerelement aktiviert / geklickt wird:
%Vor%Ich denke, ich habe es jetzt, das sollte alle Grundlagen abdecken. Lass es mich wissen, wenn ich etwas verpasse.
Tags und Links c# winforms mouseevent user-controls