Как знать, что пользователь нажал "X" или кнопку “Close”?

Это похоже на запах кода ... Но, тем не менее, есть более чистые способы сделать это.

Если вы хотите представить объект данных, то есть объект, содержащий только ключи и значения, вы можете встроить его в отображаемую веб-страницу, сделать его доступным через некоторую конечную точку API, которую клиент может получить с помощью запроса AJAX, или выставить необработанный файл Javascript, который можно включить через

4 ответа

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

Это поможет?

89
ответ дан 24 November 2019 в 08:46
поделиться

Я соглашаюсь с DialogResult - Решение как более прямое.

В VB.NET однако, преобразование типа требуется, чтобы добираться CloseReason - Свойство

    Private Sub MyForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing

        Dim eCast As System.Windows.Forms.FormClosingEventArgs
        eCast = TryCast(e, System.Windows.Forms.FormClosingEventArgs)
        If eCast.CloseReason = Windows.Forms.CloseReason.None Then
            MsgBox("Button Pressed")
        Else
            MsgBox("ALT+F4 or [x] or other reason")
        End If

    End Sub
0
ответ дан 24 November 2019 в 08:46
поделиться

Можно использовать любую из следующих опций:

  • Дескриптор WM_SYSCOMMAND и проверка на SC_CLOSE и набор флаг.
  • Проверка StackTrace , чтобы видеть, содержит ли какой-либо из кадров Close вызов метода.

Пример 1 - Дескриптор WM_SYSCOMMAND

public bool ClosedByXButtonOrAltF4 = false;
public const int SC_CLOSE = 0xF060;
public const int WM_SYSCOMMAND = 0x0112;
protected override void WndProc(ref Message msg)
{
    if (msg.Msg == WM_SYSCOMMAND && msg.WParam.ToInt32() == SC_CLOSE)
        ClosedByXButtonOrAltF4 = true;
    base.WndProc(ref msg);
}

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (ClosedByXButtonOrAltF4)
        MessageBox.Show("Closed by X or Alt+F4");
}

Пример 2 - Проверка StackTrace

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (new StackTrace().GetFrames().Any(x => x.GetMethod().Name == "Close"))
        MessageBox.Show("Closed by calling Close()");
    else
        MessageBox.Show("Closed by X or Alt+F4");
}
0
ответ дан 24 November 2019 в 08:46
поделиться

Перечисление 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 .

76
ответ дан 24 November 2019 в 08:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: