c # ouvrir un nouveau formulaire puis fermer le formulaire actuel?


89

Par exemple, supposons que je suis dans la forme 1 alors je veux:

  1. Ouvrir le formulaire 2 (à partir d'un bouton du formulaire 1)
  2. Fermer le formulaire 1
  3. Focus sur la forme 2

18
Terrible utilisabilité. Si vous utilisez WinForms, créez simplement une fenêtre conteneur et remplacez les panneaux à la place. Vos utilisateurs vous aimeront pour cela (et vous détesteront de ne pas le faire)
Claus Jørgensen

1
Écoutez Claus! Ce que vous essayez de réaliser est peut-être a) Une implémentation winforms d'une série d'étapes séquentielles de type assistant ou b) Une tentative d'afficher un formulaire "résultat" après un formulaire "saisie / soumission de données". Indépendamment du fait qu'il s'agisse de a) ou b), le comportement de l'interface utilisateur que vous essayez d'implémenter est une solution sous-optimale.
Simen S

Merci beaucoup à Clause et Simen S. Vos commentaires sont très utiles pour un débutant comme moi. Je vais lire plus de tutoriels sur l'interface graphique et la convivialité. Pouvez-vous m'en recommander quelques-uns utiles?
tnhan07


Vérifiez également [réponses ici] ( stackoverflow.com/questions/4759334/… ), si votre véritable intention était simplement d'avoir un formulaire de connexion (ou similaire).
ilias iliadis

Réponses:


193

La solution de Steve ne fonctionne pas. Lors de l'appel de this.Close (), le formulaire actuel est supprimé avec form2. Par conséquent, vous devez le masquer et définir l'événement form2.Closed pour appeler this.Close ().

private void OnButton1Click(object sender, EventArgs e)
{
    this.Hide();
    var form2 = new Form2();
    form2.Closed += (s, args) => this.Close(); 
    form2.Show();
}

2
il n'y a pas d'événement Closed dans les formulaires Windows dans dot net. Pouvez-vous me dire est-ce FormClosed event
Anjali

2
Le fait de cacher le premier formulaire ne le garde-t-il pas encore en mémoire? Comment pouvons-nous libérer cette ressource?
user2635088

5
form2.Closed += (s, args) => this.Close();Puis-je savoir comment fonctionne cette déclaration? qu'est-ce que (s,args)c'est exactement ?
Yash Saraiya le

1
(s, args) => this.Close();est une expression lambda. Il crée une fonction "en place" qui est appelée lorsque l' form2.Closedévénement est déclenché. (s, args)ne sont que des noms pour les paramètres du lambda. Lesquels pour un gestionnaire d'événements sont généralement quelque chose comme (object sender, EventArgs e). Étant donné que la Closedsignature du délégué à l' événement décrit leurs types, les types ne sont pas donnés (quelqu'un s'il vous plaît corriger mon libellé si nécessaire). // Dans l'ensemble, c'est juste un moyen délicat de ne pas avoir à déclarer une fonction entière (gestionnaire d'événements) en dehors de celle qui gère l' Form2.Closedévénement.
KDecker

1
il cache juste la première forme et ouvre une nouvelle forme mais ne ferme pas la première forme
Uddyan Semwal

25

Essayez de faire ceci ...

{
    this.Hide();
    Form1 sistema = new Form1();
    sistema.ShowDialog();
    this.Close();
}

Voici la chose. J'ai un formulaire principal. mais j'utilise un petit formulaire pour une connexion. Ce formulaire appelle le formulaire principal avec cette méthode. Ok nous sommes bien ici. Le problème était lorsque le formulaire principal affiche un formulaire enfant et à la fermeture du formulaire enfant ... il ferme également le formulaire principal. Donc puisque j'utilise la méthode publiée par Nihique. Le code fonctionnait si bien! ...
MontDeska

ce code fonctionne pour moi.
J'utilise

21

De nombreuses manières différentes ont déjà été décrites par les autres réponses. Cependant, bon nombre d'entre eux sont impliqués ShowDialog()ou form1restent ouverts mais cachés. Le moyen le meilleur et le plus intuitif à mon avis est simplement de fermer form1puis de créer à form2partir d'un emplacement extérieur (c'est-à-dire pas à partir de l'une ou l'autre de ces formes). Dans le cas où a form1été créé dans Main, form2peut simplement être créé en utilisant Application.Runcomme form1avant. Voici un exemple de scénario:

J'ai besoin que l'utilisateur entre ses informations d'identification pour que je puisse les authentifier d'une manière ou d'une autre. Ensuite, si l'authentification a réussi, je souhaite montrer l'application principale à l'utilisateur. Pour ce faire, j'utilise deux formes: LogingFormet MainForm. Le LoginForma un indicateur qui détermine si l'authentification a réussi ou non. Cet indicateur est ensuite utilisé pour décider de créer MainFormou non l' instance. Aucun de ces formulaires n'a besoin de connaître l'autre et les deux formulaires peuvent être ouverts et fermés gracieusement. Voici le code pour cela:

class LoginForm : Form
{
    public bool UserSuccessfullyAuthenticated { get; private set; }

    void LoginButton_Click(object s, EventArgs e)
    {
        if(AuthenticateUser(/* ... */))
        {
            UserSuccessfullyAuthenticated = true;
            Close();
        }
    }
}

static class Program
{
    [STAThread]
    static void Main()
    {
        LoginForm loginForm = new LoginForm();
        Application.Run(loginForm);

        if(loginForm.UserSuccessfullyAuthenticated)
        {
            // MainForm is defined elsewhere
            Application.Run(new MainForm());
        }
    }
}

C'est une belle astuce que de cacher des formes. Lorsque nous avons des formulaires masqués pour quitter l'application, il ne suffit pas de fermer le formulaire actuel. Nous devons utiliser Application.Exit (0) etc.
Peck_ Balconyon

C'est bien, mais je pense que cela ne convient que pour 2 formulaires. Qu'en est-il de plusieurs formulaires basculant entre eux?
Dr MAF le

Ceci est limité à l'exécution des formulaires en séquence, pas en parallèle ou les uns sur les autres, comme le PO l'a demandé. Je ne sais pas pourquoi cela serait limité à seulement 2 formulaires, cependant. Le code extérieur est libre de générer autant de formulaires en séquence que vous le souhaitez. Le basculement entre eux peut également être fait par le code extérieur. Il pourrait vérifier un état sur le formulaire principal (comme loginForm.UserSuccessfullyAuthenticatedauparavant) ou peut-être un état global pour décider s'il faut réexécuter le formulaire de connexion, ou exécuter un autre formulaire, ou peut-être mettre fin au processus.
Manuzor le

11

Le problème réside dans cette ligne:

Application.Run(new Form1()); Ce qui se trouve probablement dans votre fichier program.cs.

Cette ligne indique que form1 doit gérer la boucle de messages - en d'autres termes, form1 est responsable de continuer à exécuter votre application - l'application sera fermée lorsque form1 sera fermé.

Il existe plusieurs façons de gérer cela, mais toutes ne fermeront pas form1 d'une manière ou d'une autre.
(Sauf si nous changeons le type de projet pour autre chose que l'application Windows Forms)

Celui que je pense être le plus simple dans votre situation est de créer 3 formulaires:

  • form1 - restera invisible et agira en tant que gestionnaire, vous pouvez l'affecter pour gérer une icône de barre si vous le souhaitez.

  • form2 - aura le bouton, qui une fois cliqué fermera form2 et ouvrira form3

  • form3 - aura le rôle de l'autre formulaire qui doit être ouvert.

Et voici un exemple de code pour accomplir cela:
(J'ai également ajouté un exemple pour fermer l'application à partir du 3ème formulaire)

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1()); //set the only message pump to form1.
    }
}


public partial class Form1 : Form
{
    public static Form1 Form1Instance;

    public Form1()
    {
        //Everyone eveywhere in the app should know me as Form1.Form1Instance
        Form1Instance = this;

        //Make sure I am kept hidden
        WindowState = FormWindowState.Minimized;
        ShowInTaskbar = false;
        Visible = false;

        InitializeComponent();

        //Open a managed form - the one the user sees..
        var form2 = new Form2();
        form2.Show();
    }

}

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var form3 = new Form3(); //create an instance of form 3
        Hide();             //hide me (form2)
        form3.Show();       //show form3
        Close();            //close me (form2), since form1 is the message loop - no problem.
    }
}

public partial class Form3 : Form
{
    public Form3()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form1.Form1Instance.Close(); //the user want to exit the app - let's close form1.
    }
}


Remarque: travailler avec des panneaux ou charger dynamiquement des contrôles utilisateur est plus académique et préférable en tant que normes de production de l'industrie - mais il me semble que vous essayez simplement de raisonner avec le fonctionnement des choses - à cette fin, cet exemple est meilleur.

Et maintenant que les principes sont compris, essayons-le avec seulement deux formes:

  • Le premier formulaire prendra le rôle du gestionnaire comme dans l'exemple précédent mais présentera également le premier écran - il ne sera donc pas fermé juste caché.

  • Le deuxième formulaire aura le rôle d'afficher l'écran suivant et en cliquant sur un bouton fermera l'application.


    public partial class Form1 : Form
    {
        public static Form1 Form1Instance;

        public Form1()
        {
            //Everyone eveywhere in the app show know me as Form1.Form1Instance
            Form1Instance = this;
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Make sure I am kept hidden
            WindowState = FormWindowState.Minimized;
            ShowInTaskbar = false;
            Visible = false;

            //Open another form 
            var form2 = new Form2
            {
                //since we open it from a minimezed window - it will not be focused unless we put it as TopMost.
                TopMost = true
            };
            form2.Show();
            //now that that it is topmost and shown - we want to set its behavior to be normal window again.
            form2.TopMost = false; 
        }
    }

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form1.Form1Instance.Close();
        }
    }

Si vous modifiez l'exemple précédent, supprimez form3 du projet.

Bonne chance.


6

Vous n'étiez pas précis, mais il semble que vous essayiez de faire ce que je fais dans mes applications Win Forms: commencez par un formulaire de connexion, puis après une connexion réussie, fermez ce formulaire et concentrez-vous sur un formulaire principal. Voici comment je fais:

  1. make frmMain le formulaire de démarrage; voici à quoi ressemble mon Program.cs:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new frmMain());
    }
    
  2. dans mon frmLogin, créez une propriété publique qui est initialisée à false et définie sur true uniquement si une connexion réussie se produit:

    public bool IsLoggedIn { get; set; }
    
  3. mon frmMain ressemble à ceci:

    private void frmMain_Load(object sender, EventArgs e)
    {
        frmLogin frm = new frmLogin();
        frm.IsLoggedIn = false;
        frm.ShowDialog();
    
        if (!frm.IsLoggedIn)
        {
            this.Close();
            Application.Exit();
            return;
        }
    

Pas de connexion réussie? Quittez l'application. Sinon, continuez avec frmMain. Puisqu'il s'agit du formulaire de démarrage, lorsqu'il se ferme, l'application se termine.


3

utilisez cet extrait de code dans votre formulaire1.

public static void ThreadProc()
{
Application.Run(new Form());
}

private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));
t.Start();
this.Close();
}

J'ai eu ça d' ici


Notez que les réponses liées uniquement aux liens sont déconseillées, les réponses SO devraient être le point final de la recherche d'une solution (par rapport à une autre escale de références, qui ont tendance à devenir obsolètes avec le temps). Veuillez envisager d'ajouter un synopsis autonome ici, en gardant le lien comme référence.
kleopatra

2

Si vous avez deux formes: frm_form1 et frm_form2 .Le code suivant est utilisé pour ouvrir frm_form2 et fermer frm_form1. (Pour l'application de formulaire Windows)

        this.Hide();//Hide the 'current' form, i.e frm_form1 
        //show another form ( frm_form2 )   
        frm_form2 frm = new frm_form2();
        frm.ShowDialog();
        //Close the form.(frm_form1)
        this.Close();

1

Je fais généralement cela pour basculer entre les formulaires.

Tout d'abord, dans le fichier programme , je garde ApplicationContext et j'ajoute une méthode d' assistance SwitchMainForm .

        static class Program
{
    public static ApplicationContext AppContext { get;  set; }


    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        //Save app context
        Program.AppContext = new ApplicationContext(new LoginForm());
        Application.Run(AppContext);
    }

    //helper method to switch forms
      public static void SwitchMainForm(Form newForm)
    {
        var oldMainForm = AppContext.MainForm;
        AppContext.MainForm = newForm;
        oldMainForm?.Close();
        newForm.Show();
    }


}

Puis n'importe où dans le code, j'appelle maintenant la méthode SwitchMainForm pour passer facilement au nouveau formulaire.

// switch to some other form
var otherForm = new MyForm();
Program.SwitchMainForm(otherForm);

0
private void buttonNextForm(object sender, EventArgs e)
{
    NextForm nf = new NextForm();//Object of the form that you want to open
    this.hide();//Hide cirrent form.
    nf.ShowModel();//Display the next form window
    this.Close();//While closing the NextForm, control will come again and will close this form as well
}

Ça ne marchera pas. Il n'y a aucun sens à se cacher avant d'afficher le formulaire suivant. Il sera exécuté sametime et le programme sera terminé.
Ahmet Karabulut

0
//if Form1 is old form and Form2 is the current form which we want to open, then
{
Form2 f2 = new Form1();

this.Hide();// To hide old form i.e Form1
f2.Show();
}


0
                     this.Visible = false;
                        //or                         // will make LOgin Form invisivble
                        //this.Enabled = false;
                         //  or
                       // this.Hide(); 



                        Form1 form1 = new Form1();
                        form1.ShowDialog();

                        this.Dispose();

1
Qu'en est-il de cette réponse ajoute à cette discussion? C'est reformuler sans ajouter aucune information d'explication présente dans les 9 autres réponses.
Edward le

0

Je pense que c'est beaucoup plus facile :)

    private void btnLogin_Click(object sender, EventArgs e)
    {
        //this.Hide();
        //var mm = new MainMenu();
        //mm.FormClosed += (s, args) => this.Close();
        //mm.Show();

        this.Hide();
        MainMenu mm = new MainMenu();
        mm.Show();

    }

Cette solution n'est pas une réponse connexe à cette question. Votre solution ne fermera pas le formulaire actuel, cela signifie que le formulaire actuel est toujours en cours.
Ahmet Karabulut

-1

Supposons que vous ayez deux formulaires, le premier nom du formulaire est Form1 et le deuxième nom du formulaire est Form2.Vous devez passer de Form1 à Form2, entrez le code ici. Écrivez le code comme suit:

Sur Form1, j'ai un bouton nommé Button1, et sur son option de clic, écrivez le code ci-dessous:

protected void Button1_Click(Object sender,EventArgs e)
{
    Form frm=new Form2();// I have created object of Form2
    frm.Show();
    this.Visible=false;
    this.Hide();
    this.Close();
    this.Dispose();
}

J'espère que ce code vous aidera


Ces quatre méthodes: this.Visible=false; this.Hide(); this.Close(); this.Dispose();sont redondantes. Vous n'avez besoin de rien de plus Close(). La fermeture d'un formulaire en élimine, la définition de la visibilité du formulaire revient à le masquer, et le masquage d'un formulaire est inutile quand il n'existera pas avant le prochain événement de peinture.
Servy

-3

Je le résoudrais en faisant:

private void button1_Click(object sender, EventArgs e)
{
    Form2 m = new Form2();
    m.Show();
    Form1 f = new Form1();
    this.Visible = false;
    this.Hide();
}

3
this.Visible = falseet puis this.Hide? Pourquoi faire la même chose deux fois?
Neolisk

8
Aussi, pourquoi créez-vous un nouveau Form1et ne faites rien avec?
Servy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.