Скрыть форму вместо закрытия при нажатии кнопки закрытия - PullRequest
56 голосов
/ 07 января 2010

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

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

Ответы [ 7 ]

90 голосов
/ 07 января 2010

Вот так:

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

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

53 голосов
/ 07 января 2010

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

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

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

8 голосов
/ 07 января 2010

С MSDN :

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

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

4 голосов
/ 29 ноября 2012

Если вы хотите использовать метод 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
    }

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

3 голосов
/ 07 января 2010

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

Я решил это путем проверки трассировки стека - существуют различия между тем, когда пользователь пытается нажать 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;
    }
}
2 голосов
/ 07 января 2010

Это поведение модальных форм. Когда вы используете 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() вернется.

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

1 голос
/ 08 сентября 2014

На основании другого ответа вы можете указать его в коде формы:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...