2009-10-08 10 views
37

¿Cómo se puede mostrar la ventana de diálogo (por ejemplo, inicio de sesión/opciones, etc.) antes de la ventana principal?WPF que muestra el cuadro de diálogo antes de la ventana principal

Aquí es lo que he intentado (aparentemente has once worked, pero ya no):

XAML:

<Application ... 
    Startup="Application_Startup"> 

Aplicación:

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

Resultado: myDialogWindow se muestra fi primera Cuando está cerrado, la ventana1 se muestra como se esperaba. Pero cuando cierro Window1 la aplicación no se cierra en absoluto.

Respuesta

67

Aquí es la solución completa que trabajó para mí:

En App.xaml, elimino las cosas StartupUri, y añadir una Startup manejador:

<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> 

En App.xaml.cs, que definen el controlador de la siguiente manera:

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

No es necesario eliminar StartupUri para lograr el mismo resultado. Lo importante es cambiar el modo de apagado antes del diálogo y luego volver a cambiarlo después del diálogo. Donde podamos debemos apuntar a usar código detrás para aumentar al diseñador solo cuando es demasiado complejo o ineficiente para expresarlo en xaml. En este caso, una propiedad en Xaml que todos esperamos es mejor que 2 líneas ocultas dentro de la lógica condicional. –

2

Entonces, ¿desea mostrar una ventana y luego otra, pero cierre la aplicación cuando se cierre esa ventana? Es posible que necesite ajustar la ShutdownMode a OnMainWindowClose y establecer el MainWindow a Window1, a lo largo de las líneas ok:

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

¿Podría pegar toda la clase de aplicación? (Eso no funcionó (la aplicación nunca se cierra), ni tampoco la versión modificada lo intenté) Además, si miras el enlace que pegué, dice que MainWindow ya está configurado ... – Ciantic

+0

La depuración fácil confirmó la ventana principal, y todo lo que poner en ShutdownMode no importa. – Ciantic

0

aquí, hacerlo de esta manera. esto cambiará de hecho la ventana principal y funcionará correctamente sin tener que cambiar la configuración de su objeto de aplicación.

asegúrese de quitar el controlador de eventos para el inicio de la aplicación y configurar su StartupUri en su archivo 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

Lo intentaré, pero te das cuenta de que esta no puede ser la forma "correcta" de hacerlo. Tiene que haber alguna buena forma de hacer esto. Cada lugar que busco en OnStartup se rellena o se reemplaza ... incluso obtiene los argumentos de la línea de comando. Además, traté de crear la función "Ejecutar" para mi clase de aplicación, y si lo hago, no aparece nada a menos que coloque base.Run (...). Entonces eso podría ser algo para cuidar. – Ciantic

+0

aún puede anular OnStartup para manejar sus argumentos de tiempo de ejecución y demás. ¿Por qué no puede ser esta la forma "correcta" de hacerlo? esto funciona maravillosamente –

+0

No es elegante, esta cosa * debería * ser fácil. Tal como estaba, pero también te pido disculpas, me equivoqué con mi pregunta: "..." en la etiqueta de la aplicación era demasiado. – Ciantic

6

disculpa Bueno, aquí está la solución:

Mi pregunta original trabajó casi, sólo una cosa que añadir, quitar el StartupUri de la aplicación XAML y después de que añadir el show a la ventana principal.

Eso es:

<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"> 

arriba, StartupUri eliminado.

Añadir myMainWindow.Show() también:

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

Esto no funcionó, el cierre de la aplicación después de cerrar DialogWindow. – Gleno

+0

No funcionó para mí tampoco - OK = Principal se muestra bien. Cancelar = se bloquea, es decir, no se cierra. La respuesta necesita una nueva versión. – Bertie

3

WPF establece App.Current.MainWindow a la primera ventana abierta. Si tiene control sobre el constructor de la ventana secundaria, simplemente configure App.Current.MainWindow = Null allí. Una vez que se construya la ventana principal, se asignará a la propiedad App.Current.MainWindow como se esperaba sin ninguna intervención.

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

Si usted no tiene acceso, se puede ajustar todavía MainWindow en el constructor de la ventana principal.

3

Si pones Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; en el constructor del diálogo, y añadir

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

en la clase de diálogo, no es necesario que preocuparse de hacer cualquier cambio en el comportamiento predeterminado de la aplicación. Esto funciona muy bien si solo quiere ajustar una pantalla de inicio de sesión en una aplicación ya existente sin ajustar los procedimientos de inicio.

+0

Sin dudas la solución más fácil de implementar. Puede que no sea el mvvm de los puristas (es decir, absolutamente ningún código en el código), pero no creo que agregar este poquito tenga mucha o ninguna diferencia y, al menos, tenga la gran ventaja de ser también una retroadaptación. –

Cuestiones relacionadas