簡體   English   中英

當用戶在窗體窗口外單擊時如何關閉窗體?

[英]How do I close a form when a user clicks outside the form's window?

如果用戶單擊 System.Windows.Forms.Form 之外的任何地方,我想關閉它。 我試過使用 IMessageFilter,但即使如此,也沒有任何消息傳遞給 PreFilterMessage。 如何接收表單窗口外的點擊?

在表單的 Deactivate 事件中,放置“this.Close()”。 只要您單擊 Windows 中的其他任何位置,您的表單就會關閉。

更新:我認為您現在擁有的是一個 Volume 按鈕,在 Click 事件中,您創建了 VolumeSlider 表單的一個實例,並通過調用 ShowDialog() 使其出現,該實例會阻塞直到用戶關閉彈出的表單。 在下一行中,您讀取用戶選擇的卷並在您的程序中使用它。

這沒問題,但正如您已經注意到的那樣,它會強制用戶顯式關閉彈出窗口以返回主程序。 Show() 是您真正想在彈出窗體上使用的方法,但 Show() 不會阻塞,這意味着主窗體上的 Click 事件在不知道新卷應該是什么的情況下完成。

一個簡單的解決方案是在主窗體上創建一個公共方法,如下所示:

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

然后,在您的 Volume 按鈕的 Click 事件(也在主窗體上)中,您使 VolumeSlider 看起來像這樣:

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

在 VolumeSlider 表單中,當用戶操作(我猜)滾動條時,您將此代碼放在滾動條的 ValueChanged 事件中(我認為就是這樣):

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

然后在 VolumeSlider 表單的 Deactivate 事件中,您將如上所述放置 this.Close()。 您的表單將按預期運行。

感謝p-daddy這個問題中,我找到了這個允許我使用 ShowDialog 的解決方案:

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);
}

使用西蒙的解決方案,我得到了與諾姆相同的問題描述。 使用以下代碼,我避免了“點擊”問題...

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();
        }
    }
}

如果它是 MDI 應用程序中的子窗體,則可以在父窗體中捕獲單擊,否則解決方案會很混亂。

無論如何,我不相信你的建議代表了直觀的 UI 行為。 你確定這是最好的設計嗎?

如果您正在嘗試制作一個行為有點像菜單的彈出窗口,除了它允許您與控件交互之外,您可以嘗試在工具條下拉列表中托管用戶控件。

簡單的方法:在 Form1 上使用此代碼調用 form2:

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

然后再次在 form1 上使用此代碼:

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

您應該使用Deactivate
我有一個名為Form2的表單。
在“屬性”窗口的“停用”部分。
您聲明名稱Form2_Deactivate
Form2.cs文件中:

private void Form2_Deactivate(object sender, EventArgs e)
{
    this.Close();
}

這很簡單:

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();
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM