Winforms: закрыть модальное диалоговое окно при нажатии за пределами диалогового окна - PullRequest
16 голосов
/ 22 декабря 2010

У меня есть открытый модальный диалог (Windows Forms). Я хочу, чтобы диалог закрывался при нажатии вне диалога (на родительской форме). Как я могу это сделать?

Ответы [ 5 ]

25 голосов
/ 22 декабря 2010

Вы должны изменить его на немодальное диалоговое окно (откройте его с помощью Show(..)), а затем используйте событие Deactivate и закройте его.

6 голосов
/ 22 декабря 2010

Это не может работать, вы должны использовать Show (), чтобы вызвать событие Deactivate.

Диалог отключает все остальные окна, чтобы сделать себя модальным.Так что за пределами диалогового окна ничего нельзя щелкнуть с развернутым родительским элементом.Соответственно, событие Деактивировать не сработает.Когда вы вместо этого используете метод Show (owner), этот побочный эффект ShowDialog () больше не мешает, и с Deactivate все в порядке.Используйте событие FormClosing / Closed, чтобы делать то, что вы будете делать после вызова ShowDialog ().

Способ, которым это обычно сделано, например, с полосой контекстного меню или раскрывающимся меню,захватывая мышь, свойство Control.Capture.Так что вы можете обнаружить события мыши даже за пределами окна.Но это не может надежно работать с формами, элементы управления внутри формы будут использовать свойство Capture для собственного использования.Так что придерживайтесь Show и Deactivate.

4 голосов
/ 09 сентября 2015

Существуют причины (например, обходные пути и т. Д.), Которые заставляют использовать модальное диалоговое окно.Вы можете эмулировать событие 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).Если вы щелкнете где-нибудь на родительской форме, ваш модальный диалог начнет «мигать с активностью», сообщая вам, что это сейчас более важно.Это достигается путем отправки ранее упомянутых сообщений несколько раз (деактивировать -> активировать -> деактивировать -> ... -> активировать).

Но будьте осторожны, если метод handleDeactivate() не завершает вашформа, она будет вызываться каждый раз, когда приходят сообщения деактивации.Вы должны справиться с этим самостоятельно.

Ссылки: MSDN Forum Документация MSDN

2 голосов
/ 01 апреля 2016

Используйте .Show () вместо .ShowDialog ().

Ручка Деактивировать событие в дочерней форме.

private void frmAdvancedSearch_Deactivate(object sender, EventArgs e)
    {
        this.Close();
    }

Это закрывает дочернюю форму, когда пользователь щелкает вне дочернего элемента.

Если вы используете .ShowDialog () для выполнения каких-либо действий после закрытия дочернего элемента, используйте .show () и переопределите событие 'formclosing' child в родительском элементе. Так что, когда дочерняя форма закроется, ты будешь делать там свои вещи.

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;
        }
    }

Надеюсь, это поможет.

0 голосов
/ 22 декабря 2010

привет, я думаю, что вы можете использовать событие нажатия мыши или событие нажатия клавиши вниз в случае, если вы найдете местоположение мыши, если это местоположение находится в минус значениях, что означает, что вы выбрали внешнюю область окон, а затем закройте эти окна, надеясь, что этопомощь.

...