Как сделать окно поверх всех окон c

Обновлено: 01.05.2024

Я хочу, чтобы мое окно было поверх всех остальных окон только в моем приложении . Если я устанавливаю свойство TopMost окна, оно становится поверх всех окон всех приложений, а я этого не хочу.

Хотя вопрос довольно старый, мне просто нужно сделать этот комментарий . Ваш вопрос плюс комментарий довольно странный, вы хотите, чтобы ваше окно было вверху вашего приложения, но в своем комментарии вы указываете, что приложение не запущено так как это первое окно (заставка), так как же ваше окно может быть поверх несуществующего приложения. Это просто заставляет меня задаться вопросом, как вообще этот вопрос мог получить 16 голосов.

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

Вам нужно установить свойство владельца окна.

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

вот пример кода части codebehind - я пропустил все очевидные вещи:


Это именно то, что я искал - как открыть новое окно, которое сохраняет фокус / активность до закрытия. Спасибо.

Вместо этого вы можете использовать Popup, который всегда будет TopMost, украсить его, как Window, и полностью присоединить его к вашему приложению, обработать событие LocationChanged вашего основного окна и установить для свойства IsOpen Popup значение false.

Редактировать:

Надеюсь, вам нужно что-то вроде этого:

Надеюсь, это поможет.


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

У меня не сработало "исключение нулевой ссылки". Мой диалог - это окно WPF, но приложение и главное окно - это WinForms.

Это сделает его модальным. Хотите, чтобы вторичное окно находилось перед главным окном, но могло взаимодействовать с главным окном.

Просто сделать это в XAML и удивлен, что никто еще не опубликовал этот ответ. В следующем примере Window объект определен в ResourceLibrary (обратите внимание на x:Key ), но вы также можете использовать эту привязку XAML для автономного Page ресурса WPF в стиле.


используйте метод Activate (). Это пытается вывести окно на передний план и активировать его. например, Window wnd = new xyz (); wnd.Activate ();

Я столкнулся с очень похожей ситуацией, как и вы. Большинство поисковых запросов, с которыми я сталкивался, утверждали, что все, что мне нужно было сделать, это установить Владелец окон, которые я хочу быть наверху, для главного окна или любого другого окна, которое называлось Show.

В любом случае, я опубликую решение, которое хорошо сработало для меня.

Я создал обработчики событий для Window.Activated и Window.Deactived в окне, которое должно было быть самым верхним по отношению к моему приложению.

У меня это отлично работает. Надеюсь, это будет полезно кому-то еще. : o)


Когда я нажимаю на другое приложение, мое окно перестает быть активным, поэтому Topmost никогда не получает значение false.

Мне удалось заставить это работать, проверив Topmost в операторе if, а не IsActive: if (ownWindow.Topmost) .

Во всплывающем окне перегружает метод Show () параметром:

Затем в главном окне вызовите свой перегруженный метод Show ():

Лучше всего установить эти два события для всех окон вашего приложения:

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

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

Есть несколько тем, есть даже «самый верхний» тег. Выполните поиск по нему или перейдите прямо к этой публикации, которая выглядит хорошо:


Я не могу установить свойство Owner, потому что в моем случае окно создается раньше любых других окон. Поэтому у меня нет другого окна, чтобы установить его владельцем.

Я ОП. После некоторого исследования и тестирования ответ таков:

Нет, нет никакого способа , чтобы сделать именно это.

@ BurakYeniçeri 9 лет спустя . Не знаю. Тогда я пришел к выводу, что это невозможно после множества попыток. Гораздо позже Йоханнес придумал решение, за которое набиралось много голосов, и я полагаю, что это хорошее решение. Я снял флажок "принять" в своем собственном ответе.

Вот способ сделать это: сделать так, чтобы ваше «самое верхнее» окно подписывалось на события GotFocus и LostFocus других окон, и используйте следующие элементы в качестве обработчиков событий:

Вы можете добавить это в свои теги Windows

Затем вы также можете отобразить его, если хотите, чтобы ваши пользователи подтвердили его, чтобы продолжить

Сначала попробуйте без параметров TopMost и посмотрите результаты.

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

Кстати, WindowStartupLocation влияет только на начальные значения свойств Top и Left окна, когда оно открыто; это не влияет на Z-порядок.

В общем, так работают окна инструментов. Например, вы можете отстыковать панель инструментов «Инструменты» в Visual Studio и разместить ее поверх окна кода. Вы по-прежнему можете вводить текст в окнах кода, даже если это окно находится наверху. Если вы поместите Блокнот поверх Visual Studio, Блокнот скроет окно Инструменты. Следовательно, эти окна находятся поверх всех окон в Visual Studio, но не поверх всех окон системы.


Как насчет htis:

Я тоже столкнулся с той же проблемой и ответил на этот вопрос Google. Недавно я обнаружил, что у меня работает следующее.


Я только что столкнулся с этой же проблемой. У меня есть настольное приложение с несколькими окнами WPF, и мне нужно, чтобы мой настраиваемый экран-заставка находился поверх других окон только в моем приложении. Когда появляется мой экран-заставка, другие окна не открываются, но я открываю MainWindow из экрана-заставки после некоторой аутентификации. Итак, я просто сделал что-то похожее на то, что сделал @GlenSlayden, но в коде, поскольку, как я уже сказал, MainWindow не для меня, чтобы я мог привязаться к:

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


1) Начать новый проект.

2) перейдите в Project, затем в New Windows form, затем выберите Windows Form и назовите Splash.

3) установите размер, фон, текст и т. Д. По желанию.

4) В свойствах формы Splash.cs установите Start Position: CenterScreen и TopMost: true.

5) form1 добавить "using System.Threading;"

6) form1 в классе добавить "Splash splashscreen = new Splash ();"

7) form1 добавить "splashscreen.Show ();" и «Application.DoEvents ()»;

8) form1 В разделе События >> Фокус >> Активировано добавьте «Thread.Sleep (4000); splashscreen.Close ();»

9) Добавьте Splash.cs в «Public Splash» добавьте this.BackColor = Color.Aqua; / можно использовать любой цвет

10) Это код для Form1.cs

11) это код на Splash.cs

12) Я обнаружил, что если вы НЕ сделаете что-то в заставке, экран не будет оставаться наверху, пока первая форма должна активироваться. Счетчик потоков исчезнет, ​​всплеск исчезнет через x секунд, поэтому ваша программа работает нормально.

Добрый день, коллеги!
Столкнулся с таким нюансом (с некоторой спецификой) и стандартные способы, описанные в различных источниках, для такого моего "особого" случая не подошли. А примеры с похожей ситуацией мне найти не удалось.
Ситуация такова. Из начальной формы своего приложения, вызываем новую форму (назовём её "окно с анимацией", чтоб дальше меньше путаться), которая должна находиться поверх этой (начальной) формы, вызвавшей её. Что бы, во-первых, если щёлкнуть указателем мыши в окно уровнем ниже оно не переносилось на верх, во-вторых что бы, если в процессе работы с этим приложением, в этот момент, открыли какое-либо другое окно, другой программы (например Word во весь экран), после чего захотели вернуться обратно к нашему приложению, но не Alt+Tab'ом, а просто выбрав его иконку на панели задач, чтоб опять же "окно с анимацией" отображалось поверх главной формы, а не так, что главная форма активировалась "наверх", а вызванное ею "окно анимации" где-то затерялось за остальными окнами. Надеюсь не сильно запутал вступлением.
Так вот, всё бы ни чего, если бы не следующий нюанс. Вызываемая форма ("окно с анимацией") в моём случае не на прямую в главном потоке класса начальной формы вызывается. Т.е. не так:

ибо в таком случае, я бы передал в метод .Show(), вызываемой формы, this, и всё было бы как раз так, как мне надо. Т.е. оговорю сразу, что вариант с использованием TopMost формы WaitingRead мне не подходит, т.к. мне нужно, чтоб это окно не поверх всех окон рабочей среды в целом отображалось, а только по верх окон одного моего приложения.
Так вот, форма эта в моём обработчике вызывается в отдельном потоке, используя BackgroundWorker.
Приведу основную выжимку кода для наглядности:

Так вот, если я достаточно понятно изложил суть проблемы, подскажите, как вызывая окно в таком случае, заставив его корректно отображаться поверх главного, пока не выполнится bw.CancelAsync(); или выход по ESC, когда его нажатие отловится.

Мне нужно, чтобы форма появлялась поверх всех окон, при этом чтобы не перехватывала фокус (типа всплывашки). Но проблема в глючном шарпу в том, что если установить свойство формы TopMost в True, тогда форма перехватывает фокус, даже если переоверрайдить свойство ShowWithoutActivation в True. Приходится прибегать к API-шной функции SetWindowPos:

тогда форма будет поверх всех окон и фокус не будет перехватываться. Я добавил этот вызов в обработчик события FormLoad, но форма всеравно перехватывает фокус. Что я делаю не так?

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

Потом нагуглил, что эта штука не работает, если TopMost == True. Теперь вот с этой апишной функцией играюсь и ничего не получается.

Никогда не думал, что будет такой большой проблемой вывести форму поверх всех окон без активации.


Окно поверх всех без фокуса!
Задача такова, что нужно создать окно которое будет по верх всех окон(приложений) находящихся на.

Окно без фокуса, поверх других окон
Подскажите, как сделать что бы окно, будучи даже без фокуса, находилось поверх других окон.

Форма поверх всех окон (даже после потери фокуса).
К примеру есть две формы: form1 и form2. form2 запускается из form1, и должна всегда оставаться.


Две формы поверх всех окон. Вторая не хочет быть поверх
Ребят, поиск юзал, всё пробовал. Вторая форма не хочет быть наверху, первая нормально наверху.

при нажатии на текстбок - пишется true, при клике в ту же студию - форма остаётся на переднем плане, а текст - false

Добавлено через 1 минуту
никаких winAPI, просто topMost=true;

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

Вот я создал проект с формой с установленным TopMost=True и переписанным свойством ShowWithoutActivation

Компилируем и запускаем программу и быстро открываем блокнот и печатаем в нем текст. Когда через 3 секунды откроется форма, то она перехватит на себя фокус и текст станет печататься не в блокноте, а на форме! что жутко мне не нужно (я пытаюсь сделать всплывающее окно со своими кнопками)

Вот вторая форма для теста с WinAPI функцией:

Форма устанавливается поверх всех окон, но фокус также перехватывается. И я не могу понять почему! Наверное я не там, где надо вызываю эту функцию. Помогите разобраться! Я уже столько намучился с этим тошнотным перехватом фокуса.

Ниже этот проект с двумя формами. Попробуйте его у себя запустить.

обрати внимание что у тебя стоит
Form1 form2=new Form1();
что не есть хорошо

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

Добавлено через 2 минуты

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

Возникла вторая проблема. Форма не хочет быть поверх окон, если она создается в обработчике таймера System.Timers.Timer и я не знаю, чем это вызвано. Если вместо этого таймера использовать System.Windows.Forms.Timer, тогда форма ведет себя так, как от нее ожидается. Но в моей задаче нужно использовать первый таймер System.Timers.Timer. Почему в нем форма ведет себя непредсказуемо и не отображается поверх всех окон?

честно, не знаю почему вызывается настолько странная ошибка, но ты уверен что каждые 5 секунд хочешь создавать по новой форме?

Добавлено через 56 секунд
а хотя возможно из-за ShowDialog процесс не возвращается к таймерам и ждёт пока закроют приложения, да..

Это просто для тестов я задал такой интервал, чтобы хорошо было видно, что при каждом создании формы она почему-то не поверх всех окон.. В реальном приложении этот интервал будет произвольным в зависимости от предпочтений пользователя

в любом случае, попробуй:

Я забыл уточнить, что поместил на саму форму тоже один таймер, который автоматически закрывает форму через одну секунду, так что не в этом проблема.

Добавлено через 1 минуту

а где здесь в вашем коде вообще вызов формы? Тут не то что компилятор, здесь и невооруженным глазом видно, что теперь форма вообще не будет появляться.

В этом случае та же самая проблема - форма не поверх окон.

Добавлено через 7 минут
Я так полагаю, что проблема в том, что таймер System.Timers.Timer работает в другом потоке (в отличие от таймера System.Windows.Forms.Timer). Потому нужно как-то заставить создаться форме и показать ее не в потоке таймера, а в главном потоке. Может тогда проблема решится. Но как это сделать?

Еще, на msdn читал, что если этот таймер используется на UI-элементе, тогда его свойству SynchronizingObject нужно присвоить ссылку на сам UI-элемент, который содержит таймер. То есть, что-то типа:

Но в моем случае загвозда в том, что не таймер должен быть привязан к форме, а форма к таймеру, так как таймер генерирует события, создающие формы одну за другой. И я чисто физически не могу присвоить свойству SynchronizingObject ссылку на форму, так как тогда в тот отрезок времени форма еще не создана.

хм. ну, раз 1 таймер не работает как нужно а второй не подходит по каким-то причинам, предлагаю создать поток:

по идее тоже самое, только параметров меньше)

Добавлено через 1 минуту
а-а, опять забылся, в вечном цикле добавь сон:

ладно. это оставим на потом.. Спасибо. (ваш пример с потоками пока не тестировал)
Просто, сказать по правде, мне уже чисто спортивно интересно, чем вызвано то, что при втором таймере форма ведет себя мистически непредсказуемо. Я не успокоюсь, пока не найду ответ на этот вопрос.

Форма не хочет быть поверх окон, если она создается в обработчике таймера System.Timers.Timer и я не знаю, чем это вызвано. Если вместо этого таймера использовать System.Windows.Forms.Timer, тогда форма ведет себя так, как от нее ожидается. Но в моей задаче нужно использовать первый таймер System.Timers.Timer. Почему в нем форма ведет себя непредсказуемо и не отображается поверх всех окон?

Были у меня догадки по этому поводу, а вы их утвердили..) Получается, надо использовать Windows.Forms.Timer и от него никуда не убежишь.
Я вчера пробовал dotPeek-ом просмотреть реализацию этих двух таймеров, чтобы понять их различие в середине, но там оказалось не все так просто, как я думал. разбираться придется очень долго..))

А такой вопрос: как на счет производительности этих таймеров? Есть различия или нет? по этому вопросу что-то ничего не нагуглил, может плохо искал. Просто вот в чем суть, почему я сначала так упорно не хотел использовать Windows.Forms.Timer. Программа фоновая и в ней постоянно работает таймер, который генерирует через определенные промежутки некоторые действия(которые с UI вообще никак не связаны и пользователю вообще ничего не выводится). Но если пользователь поменяет в настройках одну вещь(это 1% из 100. ), тогда при каждой генерации события этого таймера должна выводиться всплывашка возле трея (типа напоминание - то есть эта неактивированная форма поверх всех окон). То есть, в большинстве случаев таймер вообще не имеет ничего общего с интерфейсом. А на мсдн говорится, что Windows.Forms.Timer должен использоваться на форме. А в моей программе это условие выполняется лишь может один раз из 100.

То ничего нет плохого в производительности, что я буду использовать таймер для форм в такой ситуации?

Я создаю небольшое приложение, которое выполняет обновления программных файлов другого программного обеспечения, а затем запускает это программное обеспечение. После запуска приложения во втором потоке графического интерфейса отображается всплывающее окно, а в основном потоке создается и отображается главное окно второго приложения:

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

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

Ничего не делает . Как правильно этого добиться?

3 ответа

Благодаря ответам Майка и Шеридана я нашел решение просто активировать окно в потоке, в котором оно создано. Итак

Делает свое дело.

Если я правильно помню, я решил эту проблему в WPF Smart Client с помощью внешнего модуля запуска, выполнив следующие действия:

После запуска основного приложения программа запуска вызывает AllowSetForegroundWindow через P / Invoke, чтобы позволить главному приложению установить окно переднего плана (это разрешено, если программа запуска активна).

Главное приложение вызывает SetForegroundWindow через P / Invoke, чтобы установить окно переднего плана в его главное окно оболочки.

. Или что-то вдоль этих линий. Это мог быть модуль запуска, который вызвал SetForegroundWindow после того, как дождался, пока главное окно приложения станет активным. Это было некоторое время назад, и у меня больше нет доступа к источнику.

Во втором примере нет смысла, поскольку пользовательский интерфейс не обновляется во время выполнения программы, и поэтому ваш вызов shell.Topmost = true; будет проигнорирован. Лучшим способом добиться желаемого может быть обработка Window.Deactivated и, возможно, Window.Activated событий:

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

необходимо задать свойство owner окна.

вы можете показать окно через showdialog, чтобы заблокировать главное окно, или вы можете показать его нормально и иметь его на вершине владельца без блокировки владельца.

вот пример codeexample части codebehind - я пропустил все очевидные вещи:

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

Я надеюсь, что вы хотите, что-то вроде этого:

надеюсь, что это помогает.

используйте метод Activate (). Это попытка вывести окно на передний план и активировать его. например, окно wnd = new xyz(); wnd.Активировать ();

лучший способ-это установить эти два события для всех окон приложения:

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

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

в любом случае, я пойду вперед и опубликую решение, которое хорошо сработало для меня.

Я создал обработчики событий для Window.Активировано и окно.Деактивирован в окне, которое должно было быть самым верхним по отношению к моему приложению.

Он отлично работает для меня. Надеюсь, это пригодится кому-то еще. : o)

во всплывающем окне перегружает метод Show () параметром:

затем в главном окне вызовите перегруженный метод Show ():

просто сделать это в XAML, и удивлен, что никто еще не опубликовал этот ответ. В следующем примере Window определена в ResourceLibrary (уведомление x:Key ), но вы также можете использовать эту привязку XAML для автономного Page -стиль ресурса WPF.

Я ОП. После некоторых исследований и тестирования ответ:

нет, нет никакого способа, чтобы сделать ровно что.

вы можете добавить это в свои теги windows

затем вы также можете отобразить его, если хотите, чтобы ваши пользователи признали его, чтобы продолжить

сначала попробуйте без верхних параметров и посмотрите результаты.

вот как это сделать: Сделайте ваше" верхнее " окно подписаться на другие события windows GotFocus и LostFocus и использовать следующие обработчики событий:

Как насчет htis:

Я тоже столкнулся с той же проблемой и последовал за Google на этот вопрос. Недавно я обнаружил, что для меня работает следующее.

Я только что столкнулся с этой же проблемой. У меня есть настольное приложение с несколькими окнами WPF, и мне нужно, чтобы мой пользовательский заставка была поверх других окон только в моем приложении. Никакие другие окна не открываются, когда появляется мой заставка, но я открываю главное окно из моего заставки после некоторой аутентификации. Поэтому я просто сделал что-то похожее на то, что сделал @GlenSlayden, но в коде позади, так как, как я сказал, MainWindow не для меня, чтобы привязаться к:

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

1) начать новый проект.

2) Перейдите в проект, затем в новую форму Windows, затем выберите Windows Form и Name Splash.

3) настроить размер, фон, текст и т. д. По желанию.

4) В разделе свойства всплеска.cs форма установить начальную позицию: Центральный экран и верхний: true

5) формы form1 добавить "с помощью системы.Нить;"

6) form1 в разделе класс добавить " Splash splashscreen = new Splash ();"

7) form1 добавить " splashscreen.Show (); "and" Application.DoEvents ();"

8) form1 в разделе События> > фокус> > активировано добавить " поток.Сон(4000); splashscreen.Close ();"

9) всплеск.cs добавить в разделе "Public Splash" добавить " это.Цвет Фона = Цвет.Aqua; " / может использовать любой цвет

10) это код для формы 1.cs

11) это код на Splash.cs

12) я обнаружил, что если вы не делаете что-то в заставке, то экран не будет оставаться на вершине в течение того времени, первая форма должна активировать. Количество потоков исчезнет всплеск через x секунд, так что ваша программа в норме.

Читайте также: