web-dev-qa-db-fra.com

Remplacer le bouton de fermeture standard (X) dans un Windows Form

Comment puis-je changer ce qui se passe lorsqu'un utilisateur clique sur le bouton de fermeture (X rouge) d'une application Windows Forms (en C #)?

69
Alex S

Vous pouvez remplacer OnFormClosing pour le faire. Veillez simplement à ne rien faire de trop inattendu, car cliquer sur le 'X' pour fermer est un comportement bien compris.

protected override void OnFormClosing(FormClosingEventArgs e)
{
    base.OnFormClosing(e);

    if (e.CloseReason == CloseReason.WindowsShutDown) return;

    // Confirm user wants to close
    switch (MessageBox.Show(this, "Are you sure you want to close?", "Closing", MessageBoxButtons.YesNo))
    {
    case DialogResult.No:
        e.Cancel = true;
        break;
    default:
        break;
    }        
}
123
Jon B

Remplacez la méthode OnFormClosing .

ATTENTION: Vous devez vérifier CloseReason et ne modifier le comportement que s'il s'agit de UserClosing. Vous ne devriez rien mettre ici qui pourrait bloquer la routine d’arrêt de Windows.

Modifications de l'arrêt de l'application dans Windows Vista

C’est issu du Conditions requises pour le programme du logo Windows 7 .

18
Philip Wallace

Une chose qui manque à ces réponses, et que les débutants recherchent probablement, est qu’il est agréable d’organiser un événement

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // do something
}

Cela ne fera rien du tout sauf si vous enregistrez l'événement . Mettez ceci dans le constructeur de la classe:

this.FormClosing += Form1_FormClosing;
17
Jason Thaxter

Remplacez/ OnFormClosing ou inscrivez-vous pour l'événement FormClosing

Voici un exemple de remplacement de la fonction OnFormClosing dans le formulaire dérivé:

protected override void OnFormClosing(FormClosingEventArgs e)
{
   e.Cancel = true;
}

Voici un exemple du gestionnaire de l'événement pour arrêter la fermeture du formulaire, qui peut être dans n'importe quelle classe:

private void FormClosing(object sender,FormClosingEventArgs e)
{  
   e.Cancel = true;
}

Pour aller plus loin, vérifiez la propriété CloseReason sur FormClosingEventArgs pour vous assurer que l'action appropriée est effectuée. Vous souhaiterez peut-être effectuer l'action alternative uniquement si l'utilisateur tente de fermer le formulaire.

10
Chap

comme l'a dit Jon B, mais vous voudrez aussi vérifier les ApplicationExitCall et TaskManagerClosing CloseReason

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (  e.CloseReason == CloseReason.WindowsShutDown 
        ||e.CloseReason == CloseReason.ApplicationExitCall
        ||e.CloseReason == CloseReason.TaskManagerClosing) { 
       return; 
    }
    e.Cancel = true;
    //assuming you want the close-button to only hide the form, 
    //and are overriding the form's OnFormClosing method:
    this.Hide();
}
7
Lorenz Lo Sauer

Une situation dans laquelle il est très utile de pouvoir gérer l'événement de clic du bouton x est lorsque vous utilisez un formulaire qui est un conteneur MDI. La raison en est que les événements de clôture et de clôture sont abordés en premier avec les enfants et enfin avec le parent. Ainsi, dans un scénario, un utilisateur clique sur le bouton x pour fermer l'application et le parent MDI demande une confirmation pour continuer. Au cas où il déciderait de ne pas fermer l’application mais de poursuivre ses activités, les enfants auront déjà traité l’événement de clôture, ce qui pourrait entraîner une perte d’informations ou de travail, etc. formulaire principal de demande (c'est-à-dire qui ferme, met fin à la demande) comme suit:

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0010) // WM_CLOSE
        {
            // If we don't want to close this window 
            if (ShowConfirmation("Are you sure?") != DialogResult.Yes) return;
        }

        base.WndProc(ref m);
    }
3
Bartymaeus

Override OnFormClosing ?

3
kd7

C'est une question assez communément posée. Une bonne réponse est ici:

VB.NET surcharge la fonctionnalité par défaut lorsque l'utilisateur clique sur le X (Fermer le programme)


Si vous ne vous sentez pas à l'aise de mettre votre code dans l'événement Form_Closing, la seule autre option que je connaisse est un "hack" que j'ai utilisé une ou deux fois. Il ne devrait pas être nécessaire de recourir à ce hack, mais le voici:


N'utilisez pas le bouton de fermeture normal. Au lieu de cela, créez votre formulaire de sorte qu'il n'ait pas de ControlBox. Vous pouvez le faire en définissant ControlBox = false sur le formulaire. Dans ce cas, vous aurez toujours la barre normale en haut du formulaire, ou vous pouvez définir FormBorderStyle du formulaire sur "Aucun. Si vous passez par ce deuxième itinéraire, il Il n'y aura pas de barre dans la partie supérieure ni aucune autre bordure visible. Vous devrez donc les simuler en dessinant sur le formulaire ou en utilisant les commandes de panneau de manière artistique.

Ensuite, vous pouvez ajouter un bouton standard et le rendre look comme un bouton de fermeture et y insérer votre code de nettoyage. À la fin de l'événement de bouton, appelez simplement this.Close() (C #) ou Me.Close() (VB)

1
David

La réponse acceptée fonctionne assez bien. Une méthode alternative que j'ai utilisée consiste à créer une méthode FormClosing pour le formulaire principal. Ceci est très similaire à la dérogation. Mon exemple concerne une application qui se réduit à la barre d'état système lorsque vous cliquez sur le bouton de fermeture du formulaire.

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason == CloseReason.ApplicationExitCall)
        {
            return;
        }
        else
        {
            e.Cancel = true;
            WindowState = FormWindowState.Minimized;
        }            
    }

Cela permettra ALT + F4 ou n’importe quoi dans l’application appelant Application.Exit (); pour agir normalement en cliquant sur (X) minimisera l'application.

0
Luke Eckley
protected override bool ProcessCmdKey(ref Message msg, Keys dataKey)
    {
        if (dataKey == Keys.Escape)
        {
            this.Close();
            //this.Visible = false;
            //Plus clear values from form, if Visible false.
        }
        return base.ProcessCmdKey(ref msg, dataKey);
    }
0
Kunal Goel