当用户在表单窗口外单击时,如何关闭表单?

时间:2008-11-18 11:29:21

标签: c# forms click

如果用户点击它以外的任何地方,我想关闭一个System.Windows.Forms.Form。我尝试过使用IMessageFilter,但即使这样,也没有任何消息传递给PreFilterMessage。如何在表单窗口外收到点击次数?

8 个答案:

答案 0 :(得分:7)

在表单的Deactivate事件中,输入“this.Close()”。单击Windows中的任何其他位置后,您的表单将立即关闭。

更新:我认为你现在拥有的是一个音量按钮,在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()如上所述。然后,您的表单将按预期运行。

答案 1 :(得分:5)

感谢p-daddy中的this question,我发现这个解决方案允许我使用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);
}

答案 2 :(得分:4)

在Simon的解决方案中,我有同样的问题由Noam描述。使用以下代码,我避免了“点击”问题...

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

答案 3 :(得分:0)

如果它是MDI应用程序中的子表单,您可以在父表单中捕获单击,否则解决方案将会很混乱。

我不相信你的建议代表了直观的UI行为。你确定这是最好的设计吗?

答案 4 :(得分:0)

如果您尝试创建一个类似于菜单的弹出窗口,除了它允许您与控件进行交互之外,您可以尝试在工具条下拉列表中托管用户控件。

答案 5 :(得分:0)

简单方式: 在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

答案 6 :(得分:0)

您应使用停用
我有一个名为 Form2 的表单。
属性窗口的停用部分中。
您声明名称 Form2_Deactivate
Form2.cs 文件中:

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

答案 7 :(得分:-1)

这很简单:

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