当用户在表单窗口外单击时如何关闭表单?
我想关闭一个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 }
然后,在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); }
在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(); } } }
如果它是MDI应用程序中的子表单,则可以在父表单中捕获单击,否则解决方案将变得混乱。
我不相信你的建议代表了直观的UI行为。 你确定这是最好的设计吗?
如果您尝试创建一个类似于菜单的弹出窗口,除了它允许您与控件进行交互,您可以尝试在工具条下拉列表中托管用户控件。
SIMPLY WAY:在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
这很简单:
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(); }