2009-10-05 6 views
0

J'ai une boîte de dialogue affichant des informations sur un objet. Je veux fermer ce dialogue pour montrer le même dialogue mais maintenant avec le frère de l'objet. C'est un dialogue complexe qui charge différents composants en fonction de l'objet assigné, je ne peux pas changer la référence à un autre objet J'ai essayé de lancer le nouveau dans l'événement Closed, mais le premier n'a pas disparu de l'écran et continue de s'afficher. Également essayé une méthode statique qui est appelée dans la boîte de dialogue, en passant la même boîte de dialogue comme un paramètre, de sorte qu'il ferme la boîte de dialogue 'dialogue.Close()' et ouvre un nouveau avec le nouvel objet à afficher. Mais toujours l'ancien reste ouvert derrière. Existe-t-il un moyen d'accomplir cela, en fermant la première fenêtre et en ouvrant la seconde?Comment puis-je ouvrir un dialogue Winform lors de la fermeture d'un autre?

(CECI EST L'approche statique, la fenêtre adoptée par le paramètre ne se ferme pas jusqu'à ce que le nouveau créé est fermé)

// From the Dialog try to launch the second one closing this. 
private void btnSibling_Click(object sender, EventArgs e) 
     { 
       SwitchToSibling(this); 
     } 

private static void SwitchToSibling(SiblingDialog window) 
     { 
      try 
      { 
       double id = 0; 
       id = window.SelectedSibling(); 
       if (id != 0) 
       { 
        // Get's the same Parent so to the new Dialog 
        Control owner = window.Owner; 
        window.Close(); 
        Sibling sibling= Sibling.Get(id); 
        SiblingDialog.ShowSibling(sibling, false, owner); 
       } 
      } 
      catch (GroupException ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 

     } 
+0

Les dialogues impliqués sont-ils modaux ou modélisés? –

Répondre

0

La seule façon que je pouvais trouver un moyen est autour en appelant ma boîte de dialogue à partir d'une méthode statique (en utilisant une sorte de singleton Pattern), puis en utilisant une variable statique pour marquer lorsque le dialogue doit être rouvert. Ainsi, lorsqu'une exécution de dialogue est terminée dans la méthode statique, elle vérifie si elle doit être rouverte. Sinon, je ne vois pas un moyen possible.

0

Sans connaître les détails à l'intérieur des classes et SiblingSiblingDialog, que vous pouvez. La seule contrainte serait que si vous fermez la fenêtre qui est la fenêtre principale de l'application, l'application va quitter.

Vous pouvez, par exemple, fournir une méthode comme ceci:

private static void CloseAndShow(Form formToClose, Form formToShow) 
{ 
    formToClose.Close(); 
    formToShow.Show(); 
} 

qui fermerait formToClose et montrer formToShow.

+0

C'est à peu près la même chose que dans ma méthode statique, je ferme un Dialog et montre le nouveau. Comme j'appelle cette méthode dans la première boîte de dialogue, elle ne se ferme pas lorsque la méthode est exécutée, mais lorsque la fonction (où la méthode Close() est appelée) se termine. On dirait que la méthode Dispose ou autre pour libérer des ressources n'est appelée qu'après la fin de la méthode. – jmayor

0

Si vous avez défini le propriétaire pour la première boîte de dialogue, et vous savez ce type, vous devriez être en mesure de résoudre ce problème comme suit:

  • Ecrire un événement personnalisé sur propriétaire de la boîte de dialogue.
  • Lorsque l'utilisateur clique sur le bouton de fermeture , appelez l'événement.
  • Ne pas fermez la boîte de dialogue à partir du bouton. La fenêtre propriétaire ferme la boîte de dialogue lorsque le gestionnaire d'événements est invoqué. Ensuite, le dialogue propriétaire affiche le dialogue de frère.

0

Une extension de Fredrik Mork's answer, qui porte sur le fait que la forme de fermeture peut être sous la forme contrôler l'état de sortie du programme.

private static void CloseAndShow(Form formToClose, Form formToShow) 
{ 
    Application.Run(formToShow); 
    formToClose.Close(); 
    formToShow.Show(); 
} 

Application.Run indique au programme de sortie lorsque le formulaire est passé à elle ferme

0

Comme il semble que vous définissez le propriétaire de la boîte de dialogue, vous pouvez essayer d'utiliser owner.BeginInvoke() dans le gestionnaire d'événements FormClosed() de la classe MyForm.:

public partial class MyForm : Form 
{ 
    static int count = 0; 
    public MyForm() 
    { 
     InitializeComponent(); 
    } 

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

    public static void ShowMyDialog(MyForm form, IWin32Window owner) 
    { 
     count++; 
     form.Text = "My ID: " + count; 
     form.ShowDialog(owner); 
    } 

    delegate void MyDel(MyForm form, IWin32Window owner); 

    private void MyForm_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     MyDel del = ShowMyDialog; 
     MyForm mySecondForm = new MyForm(); 
     this.Owner.BeginInvoke(del, mySecondForm, this.Owner); 
    } 
} 
1

J'ai eu le même problème, et après beaucoup de dépannage j'ai réussi à le résoudre d'une manière tout à fait différente: j'attendre d'abord l'événement Forms.Application.LeaveThreadModal de se produire, puis-je attendre l'événement Forms.Application.Idle suivant à se produire. À ce moment-là, le premier dialogue a complètement disparu, il est donc possible de lancer le second dialogue sans aucun problème. L'attente uniquement de l'événement inactif ou uniquement de l'événement leave-thread-modal ou des deux événements dans l'ordre inverse ne fonctionnera pas. ATTENTION: Attendre uniquement que l'événement inactif APPEARS fonctionne, mais seulement tant que l'activation de la deuxième boîte de dialogue est effectuée en cliquant sur un bouton du premier dialogue avec la souris. Si vous activez le bouton en appuyant sur la touche mnémonique de ce bouton sur le clavier, la deuxième boîte de dialogue apparaît au-dessus du premier dialogue! Vous devez passer par la séquence que j'ai décrite afin d'éviter cela! Après y avoir réfléchi un peu plus, il me semble que ma solution est un peu "magique", ce qui veut dire qu'elle pourrait cesser de fonctionner dans une future version du framework dotnet, donc je pense que je vais l'abandonner et suivez les conseils de Mike Hoffer, qui, pour autant que je sache, est essentiellement la même que la réponse que jmayor a donnée pour lui-même et marquée comme acceptée. (La vérité est que la réponse de Mike Hoffer est un peu difficile à suivre.)

Questions connexes