Как отключить форму закрытия Alt + F4?

Как лучше всего отключить Alt + F4 в форме выигрыша C#, чтобы пользователь не закрыл форму?

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

В обработчике событий FormClosing не могли бы вы запросить буфер клавиатуры (есть ли у вас вообще доступ к нему?), Чтобы найти, если [Alt] + [F4] был нажат, отменить, если истина, продолжить, если нет?

TK. 18.08.2008 21:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
79
1
73 237
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Вы можете обработать событие 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

antsyawn 26.05.2011 08:09

Я бы сделал обработчик событий таким: e.Cancel = (e.Reason == CloseReason.UserClosing);. Таким образом вы гарантируете, что не закроетесь только тогда, когда ПОЛЬЗОВАТЕЛЬ попытается закрыть форму.

Paulo Santos 05.08.2011 15:37

У этого подхода есть одна большая проблема: если вы хотите выключить / перезагрузить компьютер, он также отменит этот запрос (по крайней мере, в Windows XP).

conceptacid 03.04.2014 17:59

Это блестяще! Мне особенно нравится удалять событие, когда вы хотите закрыть форму. Это так ПРОСТО !!!

Will 10.04.2014 19:10

@Will: Я отредактировал ответ. Теперь есть решение, которое работает без удаления обработчика событий.

Thomas Weller 02.09.2018 16:06

Будет ли вызываться FormClosing, даже когда вы программно закрываете окно? Если это так, вы, вероятно, захотите добавить код, позволяющий закрыть форму, когда вы закончите с ней (вместо того, чтобы всегда отменять операцию)

Ответ на ваш вопрос - «да». Пожалуйста, не задавайте дополнительных вопросов в качестве ответа. Уже есть действительно хороший, получивший высокую оценку и принятый ответ. Если вы не против, удалите, пожалуйста, свой? На самом деле это не добавляет ценности. Я проголосовал за 3 ваших ответа, чтобы компенсировать удаление.

Thomas Weller 02.09.2018 16:09

Обратите внимание, что для приложения считается дурным тоном полностью предотвращать закрытие. Вы должны проверить аргументы события для события 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 ...

blak3r 26.02.2010 00:24

если (e.CloseReason == CloseReason.UserClosing) {e.Cancel = true; }

adnan2nd 18.08.2018 13:30

Комбинируйте CloseReason и DialogResult для достижения наилучших результатов.

Thomas Weller 02.09.2018 16:11

Я считаю, что это правильный способ:

protected override void OnFormClosing(FormClosingEventArgs e)
{
  switch (e.CloseReason)
  {
    case CloseReason.UserClosing:
      e.Cancel = true;
      break;
  }

  base.OnFormClosing(e);
}

лучше заменить перерыв на возврат

Bahadır Yağan 25.04.2011 00:30

На самом деле я считаю, что правильный шаблон - установить флаг отмены в значение true, а затем вызвать базовый класс. При переопределении методов On [Event] важно вызвать базовый класс, чтобы все подписчики событий также были уведомлены о событии. Да, в этом случае легко подумать, что, поскольку вы отменили мероприятие, больше никому не нужно об этом знать, но я не считаю правильным делать это предположение.

antsyawn 28.04.2011 03:48

Я не уверен в причине, но если я вызываю базовый класс, мое приложение вылетает после следующего нажатия Alt + F4. Сначала я подумал, что это потому, что простой F4 имеет другое значение в моем приложении, но длительный сеанс отладки показал обратное. В любом случае, это может быть конкретный случай с моей стороны. Спасибо за отличный ответ.

Bahadır Yağan 29.04.2011 00:30

Вызов базового класса также приводит к сбою моего приложения при последующих нажатиях клавиш Alt + F4. Я подозреваю, что базовый класс не проверяет e.Cancel и все равно пытается уничтожить форму.

Natan Yellin 24.05.2011 19:46

Вам нужно выяснить, почему ваше приложение дает сбой - вероятно, вы делаете что-то не так в другом месте. В документации говорится: «Событие FormClosing происходит при закрытии формы. Когда форма закрывается, она удаляется, освобождая все ресурсы, связанные с формой. Если вы отмените это событие, форма останется открытой. Чтобы отменить закрытие формы form, установите для свойства Cancel объекта FormClosingEventArgs, переданного обработчику событий, значение true. " tinyurl.com/3tb7y9q

antsyawn 26.05.2011 08:06

Вы не должны вызывать base.OnFormClosing (e) внутри закрывающейся формы. Это вызывает исключение переполнения стека, и ваше приложение выйдет из строя.

Azade 29.12.2014 12:34

Подписаться на событие 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 (как показано во фрагменте выше).

Special Sauce 14.09.2019 03:14

Этот подход лучше, потому что таким образом вы можете разрешить закрытие приложения с помощью метода Close (), который разделяет причину CloseReason.UserClosing. Меня беспокоит этот подход, всегда ли информация о нажатых клавишах всегда точна?

Adam L. S. 11.11.2020 13:12

Это делает свою работу:

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


}

Другие вопросы по теме