Как мне заставить окно WPF оставаться поверх другого?

#c# #wpf #window #owner

#c# #wpf #окно #владелец

Вопрос:

Вместо использования традиционной заставки я хочу отобразить окно входа, чтобы позволить пользователю вводить свои учетные данные. Тем временем в фоновом режиме я хочу инициализировать приложение, а затем загрузить главное окно. Проблема в том, что окно входа в систему после отображения закрывается главным окном.

 private void App_OnStartup(object sender, StartupEventArgs e)
{
    Current.MainWindow = new LoginWindow();
    Current.MainWindow.Show();

    Task.Run(() => { /*do app startup background stuff*/ }).ContinueWith(t =>
    {
       var appWindow = new ApplicationWindow();
       appWindow.Show();
       Current.MainWindow.Owner = appWindow;

    }, TaskScheduler.FromCurrentSynchronizationContext());
  

Окно входа в систему с самого начала становится главным окном. Я предполагал, что, установив владельца ApplicationWindow в окно входа, окно входа останется сверху. Если я делаю это неправильно, есть ли способ достичь того, чего я хочу? Самый верхний флаг работает, но тогда окно становится, ну, самым верхним, что нежелательно.

Ответ №1:

Предположим, у вас есть MainWindow:

 <Window x:Class="SO40189046.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SO40189046"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
    <TextBlock Name="TimeText" />
  </Grid>
</Window>
  

с кодом за:

 using System;
using System.Threading;
using System.Windows;

namespace SO40189046
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
      Loaded  = MainWindow_Loaded;

      // Background thread initializing the MainWindow
      ThreadPool.QueueUserWorkItem((state) =>
      {
        for (int i = 0; i < 10; i  )
        {
          Dispatcher.Invoke(() =>
          {
            TimeText.Text = DateTime.Now.ToString();
          });
          Thread.Sleep(1000);
        }
      });

    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {

      LoginWindow login = new LoginWindow();
      login.Owner = App.Current.MainWindow;
      login.WindowStartupLocation = WindowStartupLocation.CenterOwner;
      if (!login.ShowDialog().GetValueOrDefault())
      {
        Close();
      }
    }
  }
}
  

Затем вы можете инициализировать свое MainWindow, показывая диалоговое окно входа.

И вы загружаете MainWindow как обычно через StartupUri в App.xaml

Комментарии:

1. Спасибо за вашу помощь. Моя проблема заключалась в том, что я надеялся создать MainWindow с необходимыми параметрами. Кроме того, я надеялся немного больше понять всю суть «Владельца». В конце концов, ваше решение может быть лучшим.

2. Спасибо, что вернули меня на землю. То, что я пытался спроектировать, было слишком сложным.