我有一个打开的模态对话框(Windows Forms)。我想让它在点击对话框外部(父窗体)时关闭。我该怎么做?
我有一个打开的模态对话框(Windows Forms)。我想让它在点击对话框外部(父窗体)时关闭。我该怎么做?
你应该将它更改为非模态对话框(使用 Show(..)
打开),然后在使用 Deactivate
事件并关闭它。
有时候(例如,框架回避等原因)我们不得不使用模态对话框。你可以通过重写窗体方法WndProc
来模拟Deactivate
事件,像这样:
protected override void WndProc(ref Message m) {
const UInt32 WM_NCACTIVATE = 0x0086;
if (m.Msg == WM_NCACTIVATE && m.WParam.ToInt32() == 0) {
handleDeactivate();
} else {
base.WndProc(ref m);
}
}
WM_NCACTIVATE
消息被发送以告知窗体指示其是否处于活动状态(WParam == 1
)或非活动状态(WParam == 0
)。如果您在父窗体的某个位置单击,模态对话框会开始“闪烁显示活动”,告诉您它现在更为重要。这是通过多次发送上述消息实现的(非活动→活动→非活动→... →活动)。
但要小心,如果handleDeactivate()
方法没有终止您的窗体,则每次发送非活动消息时都将调用该方法。您必须自行处理。
无法使用此方法,您必须使用Show()来触发Deactivate事件。
对话框会禁用所有其他窗口以使自身模态。因此,在父窗口最大化时,外部无法单击任何内容。相应地,Deactivate事件不会触发。当您改用Show(owner)方法时,ShowDialog()的这种副作用不再成为问题,而Deactivate则正常工作。使用FormClosing / Closed事件来执行ShowDialog()调用后要执行的操作。
通常使用上下文菜单或菜单下拉列表等方式来实现此功能,是通过捕获鼠标(Control.Capture属性)来检测窗口外的鼠标事件。但是,对于窗体,这样做可能无法可靠地工作,因为窗体内的控件将使用Capture属性进行自身的操作。因此,请使用Show和Deactivate。
使用.Show()而不是.ShowDialog()。
在子窗体中处理Deactivate事件。
private void frmAdvancedSearch_Deactivate(object sender, EventArgs e)
{
this.Close();
}
advancedSearch.FormClosing += AdvancedSearch_FormClosing;
advancedSearch.ShowDialog();
private void AdvancedSearch_FormClosing(object sender, FormClosingEventArgs e)
{
var advanceSearch = sender as frmAdvancedSearch;
if (advanceSearch.SelectedItem != null)
{
myColumnComboBox.Text = advanceSearch.SelectedItem.Name;
}
}
嗨,我认为您可以在事件中使用鼠标按下事件或键按下事件来查找鼠标的位置,如果该位置为负值,则表示您选择了窗口的外部区域,然后关闭该窗口。希望这可以帮到您。
您可以使用 this.ParentForm.MouseClick += ParentForm_MouseClick
,同时也可以
this.ParentForm.Click += ParentForm_Click
然后关闭你的表单。
private void ParentForm_MouseClick(object sender, MouseEventArgs e)
{
this.Close();
}