2009-10-08 15 views
37

Comment afficher une fenêtre de dialogue (par exemple, login/options etc.) avant la fenêtre principale?Fenêtre d'affichage WPF avant la fenêtre principale

Voici ce que j'ai essayé (il semble has once worked, mais pas plus):

XAML:

<Application ... 
    Startup="Application_Startup"> 

application:

public partial class App : Application 
{ 
    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     Window1 myMainWindow = new Window1(); 
     DialogWindow myDialogWindow = new DialogWindow(); 
     myDialogWindow.ShowDialog(); 
    } 
} 

Résultat: myDialogWindow est montré fi premier Lorsqu'il est fermé, Window1 est affiché comme prévu. Mais lorsque je ferme Window1, l'application ne se ferme pas du tout.

Répondre

67

est ici la solution complète qui a fonctionné pour moi:

Dans App.xaml, je retire les choses StartupUri, et ajouter un Startup gestionnaire:

<Application x:Class="MyNamespace.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Startup="ApplicationStart"> 
</Application> 

Dans App.xaml.cs, I définie le gestionnaire comme suit:

public partial class App 
{ 
    private void ApplicationStart(object sender, StartupEventArgs e) 
    { 
     //Disable shutdown when the dialog closes 
     Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; 

     var dialog = new DialogWindow(); 

     if (dialog.ShowDialog() == true) 
     { 
      var mainWindow = new MainWindow(dialog.Data); 
      //Re-enable normal shutdown mode. 
      Current.ShutdownMode = ShutdownMode.OnMainWindowClose; 
      Current.MainWindow = mainWindow; 
      mainWindow.Show(); 
     } 
     else 
     { 
      MessageBox.Show("Unable to load data.", "Error", MessageBoxButton.OK); 
      Current.Shutdown(-1); 
     } 
    } 
} 
+1

Il n'est pas nécessaire d'enlever StartupUri pour obtenir le même résultat. Le bit important est de changer le mode d'arrêt avant le dialogue, puis de le changer après le dialogue. Là où nous le pouvons nous devrions viser à utiliser le code derrière pour augmenter le concepteur seulement quand il est trop complexe ou inefficace à exprimer dans xaml. Dans ce cas, une propriété dans Xaml que nous attendons tous est meilleure que 2 lignes cachées dans la logique conditionnelle. –

2

Vous souhaitez donc afficher une fenêtre, puis une autre, mais fermer l'application lorsque cette fenêtre est fermée? Vous devrez peut-être régler le ShutdownMode à OnMainWindowClose et définir le MainWindow à Window1, le long des lignes ok:

Window1 myMainWindow = new Window1(); 
Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose; 
Application.Current.MainWindow = myMainWindow; 
DialogWindow myDialogWindow = new DialogWindow(); 
myDialogWindow.ShowDialog(); 
+0

Pourriez-vous coller toute la classe d'applications? (Cela n'a pas fonctionné (l'application ne se ferme jamais), ni la version modifiée que j'ai essayée) Aussi, si vous regardez le lien que j'ai collé, cela indique que MainWindow est déjà défini ... – Ciantic

+0

Le débogage facile a confirmé la MainWindow, et tout ce que je mettre en ShutdownMode n'a pas d'importance. – Ciantic

0

ici, fais comme ça. Cela modifiera votre fenêtre principale et fonctionnera correctement sans avoir à modifier les paramètres de votre application.

Assurez-vous de supprimer le gestionnaire d'événements pour le démarrage de l'application et de définir votre StartupUri dans votre fichier app.xaml.

public partial class App : Application 
{ 
    bool init = false; 
    protected override void OnActivated(EventArgs e) 
    { 
     base.OnActivated(e); 
     if (!init) 
     { 
     this.MainWindow.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing); 
     init = true; 
     } 
    } 

    void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
    { 
     Window toClose = this.MainWindow; 
     this.MainWindow = new Window2(); 
     this.MainWindow.Show(); 
    } 
} 
+0

Je vais essayer, mais vous vous rendez compte que cela ne peut pas être la "bonne" façon de le faire. Il doit y avoir un bon moyen de le faire. Chaque endroit où je recherche OnStartup est peuplé ou surchargé ... il obtient même les arguments de la ligne de commande. En outre, j'ai essayé de créer la fonction "Exécuter" à ma classe d'application, et si je le fais, rien n'apparaît à moins que je mette base.Run (...). Donc, cela pourrait être quelque chose à surveiller. – Ciantic

+0

vous pouvez toujours remplacer l'OnStartup pour gérer vos arguments d'exécution et autres. pourquoi ne peut-il pas être le "bon" moyen de le faire? Cela fonctionne à merveille. –

+0

Ce n'est pas élégant, cette chose * devrait * être facile. Comme c'était le cas, mais je m'excuse à vous aussi, j'ai raté avec ma question le "..." dans l'étiquette de l'application était trop. – Ciantic

6

excuses Ok, voici la solution:

Ma question initiale a travaillé presque, une seule chose à ajouter, retirer le StartupUri de l'application XAML et après le salon ajouter à la fenêtre principale.

C'est:

<Application x:Class="DialogBeforeMainWindow.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Startup="Application_Startup"> 

Au-dessus, StartupUri enlevé.

Ajouter myMainWindow.Show() aussi:

public partial class App : Application 
{ 

    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     Window1 myMainWindow = new Window1(); 
     DialogWindow myDialogWindow = new DialogWindow(); 
     myDialogWindow.ShowDialog(); 
     myMainWindow.Show(); 
    } 

} 
+2

Cela n'a pas fonctionné pour moi, l'arrêt de l'application après la fermeture de DialogWindow. – Gleno

+0

N'a pas fonctionné pour moi non plus - OK = Main montré bien. Annuler = se bloque, c'est-à-dire ne ferme pas. La réponse doit être retravaillée. – Bertie

3

WPF définit App.Current.MainWindow à la première fenêtre ouverte. Si vous avez le contrôle sur le constructeur de la fenêtre secondaire, réglez simplement App.Current.MainWindow = Null là. Une fois votre fenêtre principale construite, elle sera affectée à la propriété App.Current.MainWindow comme prévu sans aucune intervention.

public partial class TraceWindow : Window 
{ 
    public TraceWindow() 
    { 
     InitializeComponent(); 
     if (App.Current.MainWindow == this) 
     { 
      App.Current.MainWindow = null; 
     } 
    } 
} 

Si vous n'avez pas accès, vous pouvez toujours définir MainWindow dans le constructeur de la fenêtre principale.

3

Si vous mettez Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; dans le constructeur de la boîte de dialogue, et d'ajouter

protected override void OnClosed(EventArgs e) { 
    base.OnClosed(e); 
    Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose; 
} 

dans la classe de dialogue, vous n'avez pas besoin de vous soucier de faire des modifications au comportement par défaut de l'application. Cela fonctionne très bien si vous voulez simplement insérer un écran de connexion dans une application déjà existante sans modifier les procédures de démarrage.

+0

Sans doute la solution la plus simple à mettre en œuvre. Ce ne sont peut-être pas les puristes mvvm (c.-à-d. Absolument aucun code dans le code), mais je ne pense pas que l'ajout de ce petit peu fait beaucoup de différence et a au moins le grand avantage d'être retrouvé. –

Questions connexes