2009-10-08 5 views
37

Как можно открыть диалоговое окно (например, логин/параметры и т. Д.) Перед основным окном?WPF показывает диалог перед основным окном

Вот что я пытался (это, по-видимому has once worked, но не больше):

XAML:

<Application ... 
    Startup="Application_Startup"> 

Применение:

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

Результат: myDialogWindow это шо Сначала wn. Когда он закрыт, окно1 отображается как ожидалось. Но когда я закрываю Window1, приложение не закрывается вообще.

ответ

67

Вот полное решение, которое работает для меня:

В App.xaml, я удалить StartupUri вещи, и добавить Startup обработчик:

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

В App.xaml.cs, я определить обработчик следующим образом:

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

Нет необходимости удалять StartupUri для достижения того же результата. Важным битом является изменение режима выключения перед диалоговым окном, а затем изменение его после диалога. Где мы можем, мы должны стремиться использовать код для увеличения дизайнера только в том случае, если он слишком сложный или неэффективный для выражения в xaml. В этом случае одно свойство в Xaml, которое мы все ожидаем, лучше, чем две строки, скрытые внутри условной логики. –

2

Итак, вы хотите показать одно окно, а затем другое, но закрыть приложение, когда это окно будет закрыто? Вы, возможно, потребуется установить ShutdownMode к OnMainWindowClose и установите MainWindow в window1, вдоль линий ок:

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

Не могли бы вы вставить весь класс приложения? (Это не сработало (приложение никогда не закрывается), а также не была модифицированная версия, которую я пробовал) Также, если вы посмотрите на ссылку, которую я вставил, она говорит, что MainWindow уже установлен ... – Ciantic

+0

Простая отладка подтвердила MainWindow, и все, что угодно положить в ShutdownMode не имеет значения. – Ciantic

0

здесь, сделать это так. это приведет к изменению вашего главного окна и будет корректно работать без необходимости изменять настройки вашего объекта приложения.

Обязательно удалите обработчик событий для запуска приложения и установите StartupUri в файл 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

Я попробую, но вы понимаете, что это не может быть «правильным» способом сделать это. Должен быть хороший способ сделать это. Каждое место, которое я ищу в OnStartup, заполнено или переопределено ... он даже получает аргументы командной строки. Кроме того, я попытался создать функцию «Выполнить» для своего класса приложения, и если я это сделаю, ничего не появится, если я не ставил base.Run (...). Так что это может быть чем-то, что нужно ухаживать. – Ciantic

+0

вы все равно можете переопределить OnStartup для обработки ваших аргументов времени выполнения и т. Д. почему это не может быть «правильным» способом? это работает чудесно. –

+0

Это не элегантно, эта вещь * должна быть легкой. Как бы то ни было, но извиняюсь и вам, я перепутал с моим вопросом, что «...» в теге приложения было слишком много. – Ciantic

6

Okay извиняется, вот решение:

Мой первоначальный вопрос работал почти, только одна вещь, чтобы добавить, удалить StartupUri из приложения XAML и после этого добавить Показать в главном окне.

То есть:

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

Выше StartupUri удалены.

Добавить myMainWindow.Show() тоже:

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

Это не сработало для меня, закрытие приложения после закрытия DialogWindow. – Gleno

+0

Не работало для меня - OK = В целом показано хорошо. Отмена = зависает, т. Е. Не закрывается. Ответ требует переделки. – Bertie

3

WPF устанавливает App.Current.MainWindow в первом открывшемся окне. Если у вас есть контроль над дополнительным конструктором окна, просто установите здесь App.Current.MainWindow = Null. Как только ваше главное окно будет построено, оно будет присвоено объекту App.Current.MainWindow, как и ожидалось, без какого-либо вмешательства.

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

Если у вас нет доступа, вы можете установить MainWindow в конструкторе главного окна.

3

Если положить Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; в конструктор диалога, а также добавить

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

в классе диалога, вам не нужно беспокоиться о том, какие изменения в поведении по умолчанию приложения. Это отлично работает, если вы хотите просто щелкнуть экран входа в уже существующее приложение, не изменяя процедуры запуска.

+0

Без сомнения, самые простые решения для реализации. Возможно, это не пуристы mvvm (т.е. абсолютно никакого кода в коде позади), но я не думаю, что добавление этого немного делает многое, если есть какая-либо разница, и, по крайней мере, имеет большое преимущество для модернизации. –

Смежные вопросы