Wie schließe ich eine Form, wenn ein Benutzer klickt außerhalb des Fensters Form?

StackOverflow https://stackoverflow.com/questions/298491

  •  08-07-2019
  •  | 
  •  

Frage

Ich möchte ein System.Windows.Forms.Form schließen, wenn der Benutzer eine beliebige Stelle außerhalb es klickt. Ich habe mit IMessageFilter versucht, aber selbst dann keine der Nachrichten werden an PreFilterMessage weitergegeben. Wie erhalte ich Klicks außerhalb eines Fensters Form?

War es hilfreich?

Lösung 2

Mit Dank an p-daddy in diese Frage , ich diese Lösung gefunden habe, die mir erlaubt, Showdialog zu verwenden:

protected override void OnShown(EventArgs e)
{
    base.OnShown(e);
    this.Capture = true;
}

protected override void OnCaptureChanged(EventArgs e)
{
    if (!this.Capture)
    {
        if (!this.RectangleToScreen(this.DisplayRectangle).Contains(Cursor.Position))
        {
            this.Close();
        }
        else
        {
            this.Capture = true;
        }
    }

    base.OnCaptureChanged(e);
}

Andere Tipps

In Ihrem Formular Ereignis deaktivieren, setzen Sie "this.Close ()". Ihre Form wird geschlossen, sobald Sie irgendwo anders in Windows klicken.

Update: Ich denke, was Sie jetzt haben eine Lautstärketaste ist, und innerhalb des Click-Ereignis Sie eine Instanz Ihrer volume Formular erstellen und sie durch den Aufruf von Showdialog (), die blockiert, bis der Benutzer schließt die knallte-up Form erscheinen . In der nächsten Zeile lesen Sie die Lautstärke der Benutzer ausgewählt und verwenden Sie es in Ihrem Programm.

Das ist in Ordnung, aber wie Sie vielleicht bemerkt haben, zwingt es den Benutzer explizit das Popup zu schließen, um zurück zum Hauptprogramm zu bekommen. Show () ist die Methode, die Sie wirklich wollen, hier auf dem Popup-Formular verwenden, aber Show () nicht blockiert, die das Click-Ereignis wieder auf der Hauptform beendet bedeutet, ohne zu wissen, was das neue Volumen sein sollte.

Eine einfache Lösung ist eine öffentliche Methode auf Ihrer Hauptform wie diese zu erstellen:

public void SetVolume(int volume)
{
    // do something with the volume - whatever you did before with it
}

Dann in Ihrer Volume-Taste des Click-Ereignis (auch auf der Haupt-Form), Sie machen das volume erscheinen wie folgt:

VolumeSlider slider = new VolumeSlider();
slider.Show(this); // the "this" is needed for the next step

In der volume Form, wie der Benutzer funktioniert (ich glaube) Scrollbar, setzen Sie den Code in dem Valuechanged-Ereignisse des Scrollbar (ich glaube, das ist, was es ist):

MainForm owner = (MainForm)this.Owner;
owner.SetVolume(scrollbar.Value);

Und dann in der Deactivate-Ereignisse der volume Form würden Sie setzen this.Close (), wie oben erwähnt. Ihr Formular wird dann verhält sich wie erwartet.

Mit Simons Lösung hatte ich das gleiche Problem describt Noam. Mit folgendem Code ich vermeiden, habe die "Click through" Problem ...

protected override void WndProc(ref Message m)
{    
    base.WndProc(ref m);

    // if click outside dialog -> Close Dlg
    if (m.Msg == NativeConstants.WM_NCACTIVATE) //0x86
    {
        if (this.Visible)
        {
            if (!this.RectangleToScreen(this.DisplayRectangle).Contains(Cursor.Position))
                this.Close();
        }
    }
}

Wenn es ein Kind Form in einer MDI-Anwendung, könnten Sie trap den Klick in dem übergeordneten Formular, sonst wird die Lösung chaotisch sein wird.

Ich bin davon überzeugt, nicht das, was schlagen Sie trotzdem intuitive Benutzeroberfläche Verhalten darstellt. Sind Sie sicher, das ist das beste Design?

Wenn Sie versuchen, ein Popup-Fenster zu machen, die ein wenig wie ein Menü verhält, mit der Ausnahme, dass es läßt Dich mit Ihren Kontrollen in Wechselwirkung treten, könnten Sie versuchen, ein Benutzersteuerelement in einem Toolstrip Drop-Down-Hosting.

SIMPLY WEISE: auf Form1 diesen Code verwenden form2 zu nennen:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles     Button1.Click
    Form2.Owner = Me
    Form2.Show()
End Sub

und dann diesen Code auf form1 wieder verwenden:

Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
    If Form2.IsHandleCreated = True Then
        Form2.Close()
    End If
End Sub

ist einfach:

private void button1_Click(object sender, EventArgs e)
    {
        Form f = new Form();
        f.LostFocus +=new EventHandler(f_LostFocus);
        f.Show();
    }

    void f_LostFocus(object sender, EventArgs e)
    {
        Form f = sender as Form;
        f.Close();
        f.Dispose();
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top