Владелец окна в WPF без постоянного поведения

Можно ли получить некоторые функции Window.Owner, не используя их все?

Есть два окна, окно A и окно B. Я хочу сделать так, чтобы при выборе любого из них они выводились поверх других приложений, но одно из них могло перекрывать другое. (На самом деле их больше двух, но все они должны вести себя одинаково.)

Если я установлю окно B Owner на A, то переключение на любое окно приведет к тому, что оба окна будут перед другими приложениями (что я хочу), но также заставит B всегда сидеть поверх A (чего я не хочу).

На самом деле у меня уже есть код, который отслеживает иерархию окон независимо от Owner/OwnedWindows, поэтому я, вероятно, могу расширить его, чтобы решить проблему активации. Итак, если это упрощает проблему, я ищу альтернативный ответ:

Как мне на самом деле сделать «когда это окно активируется пользователем, привести определенный набор окон (все остальные в приложении) к Z-порядку чуть ниже меня, сохраняя при этом их существующие Z-порядки относительно друг друга» ?


person Miral    schedule 28.03.2011    source источник
comment
+1 У меня такое же требование; ты уже нашел решение? Для вашего вопроса z-порядка: вы можете сделать это, сохранив стек (просто список‹Window›) и зарегистрировавшись на событие Activated всех ваших окон. При каждом событии вы удаляете winodw из стека и кладете его обратно наверх (== list.Add). Окно foreach в списке выводит его на передний план (используя взаимодействие).   -  person stijn    schedule 30.12.2011
comment
Я пока не нашел другого решения. Ответ Тодда ниже кажется многообещающим и, вероятно, я буду использовать (если не появится что-то лучшее), но мне еще не удалось его протестировать, поскольку проект, для которого он был, был отложен. (Вот почему я еще не отметил ответ. Я обещаю, что в конце концов вернусь к нему!)   -  person Miral    schedule 18.01.2012


Ответы (1)


Одним из возможных решений было бы иметь скрытое окно, которому принадлежат все окна в вашем приложении.

Вы бы объявили это примерно так:

<Window
    Opacity="0"
    ShowInTaskbar="False"
    AllowsTransparency="true"
    WindowStyle="None">

Обязательно удалите StartupUri из файла App.xaml. И в вашем App.xaml.cs вы должны переопределить OnStartup, чтобы он выглядел примерно так:

protected override void OnStartup(StartupEventArgs e)
{
    HiddenMainWindow window = new HiddenMainWindow();
    window.Show();

    Window1 one = new Window1();
    one.Owner = window;
    one.Show();

    Window2 two = new Window2();
    two.Owner = window;
    two.Show();
}

Еще одна трудность будет заключаться в том, как вы хотите справиться с закрытием фактического приложения. Если одно из этих окон считается основным окном, вы можете просто изменить приложение ShutdownMode на ShutdownMode.OnMainWindowClose, а затем установить свойство MainWindow для любого из этих окон. В противном случае вам нужно будет определить, когда все окна закрыты, и явно вызвать Shutdown.

person Todd White    schedule 08.04.2011
comment
это на самом деле почти идеально. Обработка закрытия/минимизации/восстановления не слишком сложна, так как я использую агрегатор событий, я просто публикую события при создании/изменении окон и сохраняю центральный список всех из них. Единственный недостаток, который я обнаружил, заключается в том, что в окнах с альтернативной вкладкой будет отображаться пустая запись (кроме значка) из-за прозрачного окна владельца. - person stijn; 30.12.2011