




Вы можете обработать событие FormClosing и установить FormClosingEventArgs.Cancel на true.
Это делает свою работу:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
Обновлено: в ответ на беспокойство pix0rs - да, вы правы, что не сможете программно закрыть приложение. Однако вы можете просто удалить обработчик событий для события form_closing перед закрытием формы:
this.FormClosing -= new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Close();
Я подозреваю, что большинство людей реализуют этот метод в рассматриваемой форме (Form1). В этом случае рекомендуется не присоединять делегат, а вместо этого переопределить метод OnFormClosing. «Метод OnFormClosing также позволяет производным классам обрабатывать событие без подключения делегата. Это предпочтительный метод обработки события в производном классе». tinyurl.com/3dzzljq
Я бы сделал обработчик событий таким: e.Cancel = (e.Reason == CloseReason.UserClosing);. Таким образом вы гарантируете, что не закроетесь только тогда, когда ПОЛЬЗОВАТЕЛЬ попытается закрыть форму.
У этого подхода есть одна большая проблема: если вы хотите выключить / перезагрузить компьютер, он также отменит этот запрос (по крайней мере, в Windows XP).
Это блестяще! Мне особенно нравится удалять событие, когда вы хотите закрыть форму. Это так ПРОСТО !!!
@Will: Я отредактировал ответ. Теперь есть решение, которое работает без удаления обработчика событий.
Будет ли вызываться FormClosing, даже когда вы программно закрываете окно? Если это так, вы, вероятно, захотите добавить код, позволяющий закрыть форму, когда вы закончите с ней (вместо того, чтобы всегда отменять операцию)
Ответ на ваш вопрос - «да». Пожалуйста, не задавайте дополнительных вопросов в качестве ответа. Уже есть действительно хороший, получивший высокую оценку и принятый ответ. Если вы не против, удалите, пожалуйста, свой? На самом деле это не добавляет ценности. Я проголосовал за 3 ваших ответа, чтобы компенсировать удаление.
Обратите внимание, что для приложения считается дурным тоном полностью предотвращать закрытие. Вы должны проверить аргументы события для события Closing, чтобы определить, как и почему ваше приложение было предложено закрыть. Если это произошло из-за выключения Windows, не следует предотвращать закрытие.
I am using a form as a popup dialog to display a progress bar and I do not want the user to be able to close it.
Если пользователь настроен закрыть ваше приложение (и достаточно осведомлен), чтобы нажать alt + f4, он, скорее всего, также будет достаточно осведомлен, чтобы запустить диспетчер задач и вместо этого убить ваше приложение.
По крайней мере, с помощью alt + f4 ваше приложение может плавно завершить работу, а не просто заставить людей убить его. По опыту, люди, убивающие ваше приложение, означают поврежденные файлы конфигурации, сломанные базы данных, незавершенные задачи, которые вы не можете возобновить, и многие другие болезненные вещи.
По крайней мере, напомните им: «Вы уверены?», А не решительно препятствуйте этому.
Если вы посмотрите на ценитьFormClosingEventArgs e.CloseReason, он расскажет вам, почему форма закрывается. Затем вы можете решить, что делать, возможные значения:
Имя члена - Описание
Никто - причина закрытия не была определена или не может быть определена.
WindowsShutDown - Операционная система закрывает все приложения перед завершением работы.
MdiFormClosing - родительская форма этой формы многодокументного интерфейса (MDI) закрывается.
UserClosing - пользователь закрывает форму через пользовательский интерфейс (UI), например, нажав кнопку «Закрыть» в окне формы, выбрав «Закрыть» в меню управления окна или нажав ALT + F4.
TaskManagerClosing - Диспетчер задач Microsoft Windows закрывает приложение.
FormOwnerClosing - Форма владельца закрывается.
ApplicationExitCall - был вызван метод Exit класса Application.
Если бы только они разбили UserClosing, чтобы быть более детализированным, чтобы вы могли целенаправленно использовать Alt + F4 ...
если (e.CloseReason == CloseReason.UserClosing) {e.Cancel = true; }
Комбинируйте CloseReason и DialogResult для достижения наилучших результатов.
Я считаю, что это правильный способ:
protected override void OnFormClosing(FormClosingEventArgs e)
{
switch (e.CloseReason)
{
case CloseReason.UserClosing:
e.Cancel = true;
break;
}
base.OnFormClosing(e);
}
лучше заменить перерыв на возврат
На самом деле я считаю, что правильный шаблон - установить флаг отмены в значение true, а затем вызвать базовый класс. При переопределении методов On [Event] важно вызвать базовый класс, чтобы все подписчики событий также были уведомлены о событии. Да, в этом случае легко подумать, что, поскольку вы отменили мероприятие, больше никому не нужно об этом знать, но я не считаю правильным делать это предположение.
Я не уверен в причине, но если я вызываю базовый класс, мое приложение вылетает после следующего нажатия Alt + F4. Сначала я подумал, что это потому, что простой F4 имеет другое значение в моем приложении, но длительный сеанс отладки показал обратное. В любом случае, это может быть конкретный случай с моей стороны. Спасибо за отличный ответ.
Вызов базового класса также приводит к сбою моего приложения при последующих нажатиях клавиш Alt + F4. Я подозреваю, что базовый класс не проверяет e.Cancel и все равно пытается уничтожить форму.
Вам нужно выяснить, почему ваше приложение дает сбой - вероятно, вы делаете что-то не так в другом месте. В документации говорится: «Событие FormClosing происходит при закрытии формы. Когда форма закрывается, она удаляется, освобождая все ресурсы, связанные с формой. Если вы отмените это событие, форма останется открытой. Чтобы отменить закрытие формы form, установите для свойства Cancel объекта FormClosingEventArgs, переданного обработчику событий, значение true. " tinyurl.com/3tb7y9q
Вы не должны вызывать base.OnFormClosing (e) внутри закрывающейся формы. Это вызывает исключение переполнения стека, и ваше приложение выйдет из строя.
Подписаться на событие FormClosing
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = e.CloseReason == CloseReason.UserClosing;
}
Только одна строка в теле метода.
Скрыть кнопку закрытия в форме, используя в конструкторе формы следующее:
this.ControlBox = false;
Это хак для отключения Alt + F4.
private void test_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.ModifierKeys == Keys.Alt || this.ModifierKeys == Keys.F4)
{
e.Cancel = true;
}
}
Я могу подтвердить, что это работает. Однако при использовании System.Windows.Forms вам нужно будет проверить статическое свойство Control.ModifierKeys вместо свойства this.ModifierKeys (как показано во фрагменте выше).
Этот подход лучше, потому что таким образом вы можете разрешить закрытие приложения с помощью метода Close (), который разделяет причину CloseReason.UserClosing. Меня беспокоит этот подход, всегда ли информация о нажатых клавишах всегда точна?
Это делает свою работу:
bool myButtonWasClicked = false;
private void Exit_Click(object sender, EventArgs e)
{
myButtonWasClicked = true;
Application.Exit();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (myButtonWasClicked)
{
e.Cancel = false;
}
else
{
e.Cancel = true;
}
}
В обработчике событий FormClosing не могли бы вы запросить буфер клавиатуры (есть ли у вас вообще доступ к нему?), Чтобы найти, если [Alt] + [F4] был нажат, отменить, если истина, продолжить, если нет?