我有一个打开的模式对话框(Windows窗体)。我想,在对话框外部(在父窗体上)单击时关闭对话框。我怎么能这样做?
答案 0 :(得分:25)
您应该将其更改为非模态对话框(使用Show(..)
打开它),然后使用Deactivate
事件并关闭它。
答案 1 :(得分:6)
这不起作用,您必须使用Show()来触发Deactivate事件。
一个对话框禁用所有其他窗口以使其自身成为模态。因此,在父对象最大化的情况下,没有任何内容可以在对话框窗口外单击。因此,Deactivate事件不会触发。当您使用Show(所有者)方法时,ShowDialog()的这种副作用不再妨碍并且Deactivate很好。使用FormClosing / Closed事件执行ShowDialog()调用后的操作。
通常使用上下文菜单条或菜单下拉列表正常完成的方式是捕获鼠标Control.Capture属性。这样您甚至可以在窗口外检测鼠标事件。但是这对表单无法可靠地工作,表单内的控件将使用Capture属性供自己使用。坚持使用Show和Deactivate。
答案 2 :(得分:4)
有一些原因(例如框架解决方法等)迫使人们使用模态对话框。您可以通过覆盖表单方法Deactivate
来模拟WndProc
事件:
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
)。如果您单击父窗体上的某个位置,您的模式对话框将开始“#34;闪烁活动"告诉你,现在它更重要。这可以通过发送前面提到的消息几次来实现(取消激活 - >激活 - >取消激活 - > ... - >激活)。
但请注意,如果handleDeactivate()
方法没有终止您的表单,则每次停用消息时都会调用它。你必须亲自处理。
答案 3 :(得分:2)
使用.Show()代替.ShowDialog()。
Handle以子窗体形式停用事件。
private void frmAdvancedSearch_Deactivate(object sender, EventArgs e)
{
this.Close();
}
当用户点击孩子外面时,这会关闭子表单。
如果您在孩子关闭后使用.ShowDialog()做某事 使用.show()并覆盖' formclosing'父母的孩子的事件。因此,当儿童表格关闭并在那里做你的东西时会发生。
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;
}
}
希望这有帮助。
答案 4 :(得分:0)
嗨我认为你可以在事件中使用鼠标按下事件或keydown事件找到鼠标的位置,如果该位置是负值,这意味着你已经选择了窗口的外部区域,然后关闭那些窗口 希望这有帮助。
答案 5 :(得分:0)
您可以使用 this.ParentForm.MouseClick += ParentForm_MouseClick
也
this.ParentForm.Click += ParentForm_Click
然后关闭您的表单。
private void ParentForm_MouseClick(object sender, MouseEventArgs e)
{
this.Close();
}