如果用户在窗口外单击,我想关闭 System.Windows.Forms.Form 窗体。我尝试使用 IMessageFilter,但即使如此,也没有将任何消息传递到 PreFilterMessage。如何接收窗体窗口外的点击?
public void SetVolume(int volume)
{
// do something with the volume - whatever you did before with it
}
接着,在音量按钮的单击事件中(也在主表单上),您可以使音量滑块出现:
VolumeSlider slider = new VolumeSlider();
slider.Show(this); // the "this" is needed for the next step
MainForm owner = (MainForm)this.Owner;
owner.SetVolume(scrollbar.Value);
感谢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();
}
}
}
ShowDialog()
打开的窗体之外时,会发送三个消息:WM_NCACTIVATE
、WM_ACTIVATE
和 WM_ACTIVATEAPP
。不要使用第三个,而第二个 (WM_ACTIVATE
) 可能比第一个更好。还要记得设置 DialogResult
! - Bitterblueprivate void Form2_Deactivate(object sender, EventArgs e)
{
this.Close();
}
简单的方法: 在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
如果它是在MDI应用程序中的子窗体,您可以在父窗体中捕获单击事件,否则解决方案将变得混乱。
我并不认为您建议的代表了直观的UI行为。您确定这是最佳设计吗?
如果你正在尝试制作一个弹出窗口,它的行为有点像菜单,除了它让你与控件交互,你可以尝试在工具栏下拉菜单中托管一个用户控件。
这很简单:
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();
}