Скрыть форму вместо закрытия при нажатии кнопки Закрыть


когда пользователь нажимает X кнопка на форме, как я могу скрыть его вместо того, чтобы закрыть его?

Я пробовал this.hide() на FormClosing но он все равно закрывает форму.

7   51   2010-01-07 19:05:12

7 ответов:

вот так:

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

(через Тим Хаффман)

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

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

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

С MSDN:

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

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

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

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

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

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

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

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

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

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

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

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

Edit: это похоже на то, что 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() вернется.

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

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

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

предпочтительно переопределение: MSDN "метод OnFormClosing также позволяет производным классам обрабатывать событие без присоединения делегата. Это предпочтительный метод для обработки события в производном классе. "