2010-01-07 3 views

ответ

79

Как так:

private void MyForm_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if (e.CloseReason == CloseReason.UserClosing) 
    { 
     e.Cancel = true; 
     Hide(); 
    } 
} 

(через Tim Huffman)

+0

спасибо вам большое обоим. – iTEgg

+0

Как я могу включить e.cancel = false? так что я могу закрыть форму позже? – iTEgg

+0

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

8

От MSDN:

Чтобы отменить закрытие формы, установите Cancel свойство FormClosingEventArgs передается в обработчик событий для true.

Так отмените, затем скройте.

3

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

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

private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    StackTrace trace = new StackTrace(); 
    StackFrame frame; 
    bool bFoundExitCommand = false; 
    for (int i = 0; i < trace.FrameCount; i++) 
    { 
     frame = trace.GetFrame(i); 
     string methodName = frame.GetMethod().Name; 
     if (methodName == "miExit_Click") 
     { 
      bFoundExitCommand = true; 
      Log("FormClosing: Found Exit Command ({0}) - will allow exit", LogUtilityLevel.Debug3, methodName); 
     } 
     if (methodName == "PeekMessage") 
     { 
      bFoundExitCommand = true; 
      Log("FormClosing: Found System Shutdown ({0}) - will allow exit", LogUtilityLevel.Debug3, methodName); 
     } 
     Log("FormClosing: frame.GetMethod().Name = {0}", LogUtilityLevel.Debug4, methodName); 
    } 
    if (!bFoundExitCommand) 
    { 
     e.Cancel = true; 
     this.Visible = false; 
    } 
    else 
    { 
     this.Visible = false; 
    } 
} 
+0

полностью согласен с тем, что вы сказали. – Alex

+0

им говорил о вашем предыдущем комментарии не последний. да, хотя приведенный выше код работает с моей дочерней формой. но из-за e.Cancel я больше не могу закрыть родительскую форму! любые подсказки? – iTEgg

+0

для приведенного выше кода для работы. Мне нужно добавить пространство имен для StackTrace. помогите, указав пространство имен. – iTEgg

2

Это поведение модальных форм. Обсуждение: form.ShowDialog() Вы найдете , обратившись с вопросом:. Причиной этого является то, что form.ShowDialog не возвращается, пока форма не будет скрыта или уничтожена. Поэтому, когда форма скрыта, насос внутри формы. ShowDialog уничтожает его, чтобы он мог вернуться.

Если вы хотите, чтобы показать и скрыть форму, то вы должны использовать диалоговую модель Немодальной http://msdn.microsoft.com/en-us/library/39wcs2dh(VS.80).aspx

form.Show() возвращается немедленно, вы можете показать и скрыть это окно все, что вы хотите, и он не будет уничтожен до вы явно уничтожаете его.

Когда вы используете немодальные формы, которые не являются дочерними элементами модальной формы, вам также необходимо запустить насос сообщений, используя Application.Run или Application.DoEvents в цикле. Если поток, который создает форму, завершается, форма будет уничтожена. Если эта нить не запускает насос, тогда формы, которыми он владеет, будут невосприимчивы.

Редактировать: это похоже на то, что ApplicationContext предназначен для решения. http://msdn.microsoft.com/en-us/library/system.windows.forms.applicationcontext.aspx

В принципе, вы черпаете класс от ApplicationContext, передать экземпляр вашего ApplicationContext в качестве аргумента Application.Run()

// Create the MyApplicationContext, that derives from ApplicationContext, 
// that manages when the application should exit. 

MyApplicationContext context = new MyApplicationContext(); 

// Run the application with the specific context. 
Application.Run(context); 

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

Не зная больше о гирархии ваших форм и ваших правилах для принятия решения о том, когда скрывать формы и когда выходить, невозможно быть более конкретным.

+0

Можете ли вы продолжить заявку Application.doevents? Мне кажется, мне это нужно. добавление e.Cancel = false; в закрытии родительской формы тоже не работало. – iTEgg

+0

Это ваша единственная форма? твоя единственная тема? –

+0

жаль, что я не был чист. приложение отключается, когда я нажимаю X. , но Application.Exit(); не работает. – iTEgg

51

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

private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if (e.CloseReason == CloseReason.UserClosing) 
    { 
     e.Cancel = true; 
     Hide(); 
    } 
} 

Если пользователь просто ударять X в окне, форма скрывает; если что-либо еще, например диспетчер задач, Application.Exit() или выключение Windows, форма будет закрыта должным образом, так как будет выполнен оператор return.

+2

Ваше использование e.CloseReason спасло меня! хороший ответ! –

4

Если вы хотите использовать метод показать/скрыть Я на самом деле сделал это сам для структуры меню игры я недавно сделал ... Вот как я это сделал:

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

btnNext.Enabled = true; //This enabled the button obviously 
this.Hide(); //Here is where the hiding of the form will happen when the button is clicked 
Form newForm = new newForm(); //This creates a new instance object for the new form 
CurrentForm.Hide(); //This hides the current form where you placed the button. 

Вот фрагмент кода, я использовал в своей игре, чтобы помочь вам понять, что я пытаюсь объяснить:

private void btnInst_Click(object sender, EventArgs e) 
    { 
     btnInst.Enabled = true; //Enables the button to work 
     this.Hide(); // Hides the current form 
     Form Instructions = new Instructions(); //Instantiates a new instance form object 
     Instructions.Show(); //Shows the instance form created above 
    } 

Таким образом, метод show/hide имеет несколько строк кода, а не делает массивную часть кода для такой простой задачи. Надеюсь, это поможет решить вашу проблему.

1

Основываясь на другой ответ, вы можете поместить его в виде кода:

protected override void OnFormClosing(FormClosingEventArgs e) 
    { 
     base.OnFormClosing(e); 
     if (e.CloseReason == CloseReason.UserClosing) 
     { 
      e.Cancel = true; 
      Hide(); 
     } 
    } 

Процентовка является предпочтительным: MSDN «Метод OnFormClosing также позволяет производным классам обрабатывать событие, не подключая делегат Это. предпочтительный способ обработки события в производном классе ».

Смежные вопросы