我想关闭一个System.Windows.Forms.Form,如果用户点击它以外的任何地方.我尝试过使用IMessageFilter,但即使这样,也没有任何消息传递给PreFilterMessage.如何在表单窗口外收到点击?
在表单的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
}
Run Code Online (Sandbox Code Playgroud)
然后,在Volume按钮的Click事件中(也在主窗体上),使VolumeSlider显示如下:
VolumeSlider slider = new VolumeSlider();
slider.Show(this); // the "this" is needed for the next step
Run Code Online (Sandbox Code Playgroud)
在VolumeSlider表单中,当用户使用(我猜)滚动条时,您将此代码放在滚动条的ValueChanged事件中(我认为它就是这样):
MainForm owner = (MainForm)this.Owner;
owner.SetVolume(scrollbar.Value);
Run Code Online (Sandbox Code Playgroud)
然后在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);
}
Run Code Online (Sandbox Code Playgroud)