Ответ 1
Вы должны изменить его на немодальный диалог (откройте его с помощью Show(..)
), а затем используйте событие Deactivate
и закройте его.
У меня есть открытый модальный диалог (Windows Forms). Я хочу, чтобы диалог закрывался при нажатии вне диалогового окна (в родительской форме). Как я могу это сделать?
Вы должны изменить его на немодальный диалог (откройте его с помощью Show(..)
), а затем используйте событие Deactivate
и закройте его.
Это не сработает, вы должны использовать Show(), чтобы запустить событие Deactivate.
Диалоговое окно отключает все остальные окна, чтобы сделать себя модальным. Таким образом, нет ничего, что можно было бы щелкнуть вне диалогового окна с максимальным размером родителя. Соответственно, событие Deactivate не будет срабатывать. Когда вы используете метод Show (owner), этот побочный эффект ShowDialog() больше не мешает, и Deactivate в порядке. Используйте событие FormClosing/Closed, чтобы сделать то, что вы сделали бы после вызова ShowDialog().
Как обычно это делается, с полосой контекстного меню или выпадающим меню, например, путем захвата мыши, свойство Control.Capture. Чтобы вы могли обнаружить события мыши даже вне окна. Но это не может надежно работать с формами, элементы управления внутри формы будут использовать свойство Capture для собственного использования. Поэтому придерживайтесь Show и Deactivate.
Есть причины (например, обходные пути и т.д.), которые заставляют использовать модальный диалог. Вы можете эмулировать событие Deactivate
, переопределив метод формы WndPrc
следующим образом:
protected override void WndProc(ref Message m) {
const UInt32 WM_NCACTIVATE = 0x0086;
bool handled = false;
if (m.Msg == WM_NCACTIVATE && m.WParam.ToInt32() == 0) {
handleDeactivate();
}
if (!handled)
base.WndProc(ref m);
}
Сообщение WM_NCACTIVATE
отправляется, чтобы сообщить форме, чтобы указать, активна ли она (WParam == 1
) или неактивна (WParam == 0
). Если вы щелкните где-нибудь в родительской форме, ваш модальный диалог начнет "мигать с активностью", говоря вам, что это более важно прямо сейчас. Это достигается путем отправки ранее упомянутых сообщений несколько раз (деактивировать → активировать → деактивировать → ... → активировать).
Но будьте осторожны, если метод handleDeactivate()
не завершает вашу форму, он будет вызываться каждый раз, когда приходят деактивирующие сообщения. Вы должны справиться с этим сами.
Ссылки:
Форум MSDN
Документация MSDN
Используйте .Show() вместо .ShowDialog().
Обработать деактивировать событие в дочерней форме.
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;
}
}
Надеюсь, что это поможет.
hi Я думаю, что вы можете использовать событие мыши или событие keydown в случае поиска местоположения мыши, если это местоположение находится в минус значениях, что означает, что вы выбрали внешнюю область окон, а затем закройте эти окна надеюсь эта помощь.