Как узнать, что пользователь нажал «X» или кнопку «Закрыть»? - PullRequest
80 голосов
/ 21 апреля 2010

В MSDN я обнаружил, что CloseReason.UserClosing знает, что пользователь решил закрыть форму, но я полагаю, она одинакова как для нажатия кнопки X, так и для нажатия кнопки закрытия.Так как же я могу различить эти два в моем коде?

Спасибо всем.

Ответы [ 8 ]

84 голосов
/ 21 апреля 2010

Если вы запрашиваете WinForms, вы можете использовать событие FormClosing () . Событие FormClosing () срабатывает каждый раз, когда форма закрывается.

Чтобы определить, нажал ли пользователь X или вашу кнопку CloseButton, вы можете получить его через объект отправителя. Попробуйте привести отправителя в качестве элемента управления Button и, возможно, проверить его имя, например, «CloseButton».

private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
    if (string.Equals((sender as Button).Name, @"CloseButton"))
        // Do something proper to CloseButton.
    else
        // Then assume that X has been clicked and act accordingly.
}

В противном случае мне никогда не требовалось различать, был ли нажат X или CloseButton, поскольку я хотел выполнить что-то определенное для события FormClosing, например, закрыть все MdiChildren перед закрытием MDIContainerForm или проверить событие на наличие несохраненных изменений. В этих условиях, по моему мнению, нам не нужно отличать ни одну из кнопок.

Закрытие по ALT + F4 также вызовет событие FormClosing (), так как оно отправляет сообщение в форму, в котором говорится о закрытии. Вы можете отменить событие, установив

FormClosingEventArgs.Cancel = true. 

В нашем примере это будет означать

e.Cancel = true.

Обратите внимание на разницу между событиями FormClosing () и FormClosed () .

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

FormClosed возникает, когда форма действительно закрыта, поэтому после ее закрытия.

Помогает ли это?

74 голосов
/ 21 апреля 2010

Перечисление CloseReason, которое вы нашли в MSDN, просто для того, чтобы проверить, закрыл ли пользователь приложение, или оно было вызвано завершением работы, или закрыто диспетчером задач и т. Д ...

Вы можете выполнять различные действия в зависимости от причины, например:

void Form_FormClosing(object sender, FormClosingEventArgs e)
{
    if(e.CloseReason == CloseReason.UserClosing)
        // Prompt user to save his data

    if(e.CloseReason == CloseReason.WindowsShutDown)
        // Autosave and clear up ressources
}

Но, как вы уже догадались, нет разницы между нажатием кнопки x или щелчком правой кнопкой мыши на панели задач и нажатием кнопки «Закрыть», или нажатием Alt F4 и т. Д. в CloseReason.UserClosing причина.

38 голосов
/ 01 декабря 2011

Кнопка «X» регистрируется как DialogResult.Cancel, поэтому другим вариантом является оценка DialogResult.

Если в вашей форме несколько кнопок, вы, вероятно, уже связываете различные DialogResult с каждой из них, и это даст вам возможность определить разницу между каждой кнопкой.

(Пример: btnSubmit.DialogResult = DialogResult.OK, btnClose.DialogResult = Dialogresult.Abort)

    public Form1()
    {
        InitializeComponent();

        this.FormClosing += Form1_FormClosing;
    }

    /// <summary>
    /// Override the Close Form event
    /// Do something
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Form1_FormClosing(Object sender, FormClosingEventArgs e)
    {
        //In case windows is trying to shut down, don't hold the process up
        if (e.CloseReason == CloseReason.WindowsShutDown) return;

        if (this.DialogResult == DialogResult.Cancel)
        {
            // Assume that X has been clicked and act accordingly.
            // Confirm user wants to close
            switch (MessageBox.Show(this, "Are you sure?", "Do you still want ... ?", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
            {
                //Stay on this form
                case DialogResult.No:
                    e.Cancel = true;
                    break;
                default:
                    break;
            }
        }
    }
6 голосов
/ 19 октября 2012

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

    private void MyForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        if (Application.OpenForms.Count == 0) Application.Exit();
    }
5 голосов
/ 14 мая 2018

Я всегда использую метод закрытия формы в моих приложениях, который ловит alt + x из моей кнопки выхода, alt + f4 или другое событие закрытия формы было инициировано. Все мои классы имеют имя класса, определенное как Закрытая строка mstrClsTitle = "grmRexcel" в этом случае, метод Exit, который вызывает метод закрытия формы и метод закрытия формы. У меня также есть заявление для метода закрытия формы - this.FormClosing = My Form Closing Form Closing method name.

Код для этого:

namespace Rexcel_II
{
    public partial class frmRexcel : Form
    {
        private string mstrClsTitle = "frmRexcel";

        public frmRexcel()
        {
            InitializeComponent();

            this.FormClosing += frmRexcel_FormClosing;
        }

        /// <summary>
        /// Handles the Button Exit Event executed by the Exit Button Click
        /// or Alt + x
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExit_Click(object sender, EventArgs e)
        {            
            this.Close();        
        }


        /// <summary>
        /// Handles the Form Closing event
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmRexcel_FormClosing(object sender, FormClosingEventArgs e)
        {

            // ---- If windows is shutting down, 
            // ---- I don't want to hold up the process
            if (e.CloseReason == CloseReason.WindowsShutDown) return;
            {

                // ---- Ok, Windows is not shutting down so
                // ---- either btnExit or Alt + x or Alt + f4 has been clicked or
                // ---- another form closing event was intiated
                //      *)  Confirm user wants to close the application
                switch (MessageBox.Show(this, 
                                    "Are you sure you want to close the Application?",
                                    mstrClsTitle + ".frmRexcel_FormClosing",
                                    MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {

                    // ---- *)  if No keep the application alive 
                    //----  *)  else close the application
                    case DialogResult.No:
                        e.Cancel = true;
                        break;
                    default:
                        break;
                }
            }
        }
    }
}
2 голосов
/ 25 августа 2016

Вы можете попробовать добавить обработчик событий из дизайна следующим образом: откройте форму в представлении дизайна, откройте окно свойств или нажмите F4, нажмите кнопку на панели инструментов событий, чтобы просмотреть события в объекте формы, найдите событие FormClosing в группе «Поведение» и дважды щелкните его. Справка: https://social.msdn.microsoft.com/Forums/vstudio/en-US/9bdee708-db4b-4e46-a99c-99726fa25cfb/how-do-i-add-formclosing-event?forum=csharpgeneral

1 голос
/ 12 января 2012
if (this.DialogResult == DialogResult.Cancel)
        {

        }
        else
        {
            switch (e.CloseReason)
            {
                case CloseReason.UserClosing:
                    e.Cancel = true;
                    break;
            }
        }

, если условие будет выполнено, когда пользователь нажмет «X» или кнопку «Закрыть» в форме. Остальное можно использовать, когда пользователь нажимает Alt + f4 для любых других целей

0 голосов
/ 01 декабря 2018
namespace Test
{
    public partial class Member : Form
    {
        public Member()
        {
            InitializeComponent();
        }

        private bool xClicked = true;

        private void btnClose_Click(object sender, EventArgs e)
        {
            xClicked = false;
            Close();
        }

        private void Member_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (xClicked)
            {
                // user click the X
            } 
            else 
            {
                // user click the close button
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...