如何使 WPF 窗口位于我的应用程序的所有其他窗口之上(不是系统范围)?
我希望我的窗口位于仅在我的应用程序中的所有其他窗口之上。如果我设置窗口的 TopMost 属性,它就会位于所有应用程序的所有窗口之上,但我不希望这样。
I want my window to be on top of all other windows in my application only. If I set the TopMost property of a window, it becomes on top of all windows of all applications and I don't want that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(20)
您需要设置窗口的所有者属性。
您可以通过 showdialog 显示一个窗口以阻止主窗口,或者您可以正常显示它并将其置于所有者之上而不阻止所有者。
这是代码隐藏部分的代码示例 - 我省略了所有明显的内容:
You need to set the owner property of the window.
You can show a window via showdialog in order to block your main window, or you can show it normal and have it ontop of the owner without blocking the owner.
here is a codeexample of the codebehind part - I left out all obvious stuff:
相反,您可以使用始终位于 TopMost 的 Popup,将其装饰为类似于窗口,并将其完全附加到您的应用程序中,处理主窗口的 LocationChanged 事件并将 Popup 的 IsOpen 属性设置为 false。
编辑:
我希望你想要这样的东西:
希望它有帮助!
Instead you can use a Popup that will be TopMost always, decorate it similar to a Window and to attach it completely with your Application handle the LocationChanged event of your main Window and set IsOpen property of Popup to false.
Edit:
I hope you want something like this:
Hope it helps!!!
在XAML中很容易做到这一点,令人惊讶的是还没有人发布这个答案。在以下示例中,
Window
在ResourceLibrary
中定义(请注意x:Key
),但您也可以在以下位置使用此 XAML 绑定:独立的Page
样式 WPF 资源。Simple to do it in XAML, and surprised that nobody posted this answer yet. In the following example, the
Window
is defined in aResourceLibrary
(notice thex:Key
), but you can also use this XAML binding on a standalonePage
-style WPF resource.使用Activate()方法。这会尝试将窗口带到前台并激活它。
例如窗口wnd = new xyz();
wnd.Activate();
use the Activate() method. This attempts to bring the window to the foreground and activate it.
e.g. Window wnd = new xyz();
wnd.Activate();
在弹出窗口中,使用参数重载方法 Show():
然后在主窗口中,调用重载方法 Show():
In the popup window, overloads the method Show() with a parameter:
Then in the Main window, call your overloaded method Show():
我遇到了和你非常相似的情况。大多数搜索 我发现我需要做的就是将我希望成为最顶层的窗口的所有者设置为主窗口或任何名为“显示”的窗口。
无论如何,我会继续发布一个对我来说效果很好的解决方案。
我在窗口中为 Window.Activated 和 Window.Deactived 创建了事件处理程序,该窗口应该位于我的应用程序的最顶层。
这对我来说非常有用。希望这对其他人有用。 :o)
I ran into a very similar situation as you. Most of the searches I came across stated all I needed to do was set the Owner of the windows I wish to be Topmost to the main window or whatever window that called Show.
Anyways, I'll go ahead and post a solution that worked well for me.
I created event handlers for Window.Activated and Window.Deactived in the window that was supposed to be Topmost with respect to my application.
It works great for me. Hopefully this is useful to someone else out there. :o)
最好的方法是将这两个事件设置为应用程序的所有窗口:
以这种方式:
就我而言,我有一个基本窗口和另一个应该位于基本窗口顶部的窗口,因此这对于我的基本窗口具有每个其他窗口的实例来说并不坏。
The best way is set this two events to all of windows of your app:
in this way:
in my case I have a base window and another some windows that should be top of my base window, so this was not bad to my base window has instance of each another windows.
有几个线程,甚至还有一个“最顶层”标签。搜索一下,或者直接转到这篇看起来不错的文章:
如何仅将窗口保留在我的应用程序中所有其他窗口之上?
There are several threads, there's even a "topmost" tag. Search on that, or go directly to this post which looks good:
How to keep a window on top of all other windows in my application only?
我是OP。经过一些研究和测试,答案是:
不,没有办法完全做到这一点。
I'm the OP. After some research and testing, the answer is:
No, there is no way to do exactly that.
有一种方法可以做到这一点:让您的“最顶层”窗口订阅其他窗口的 GotFocus 和 LostFocus 事件,并使用以下内容作为事件处理程序:
Here's a way to do it: make your "topmost" window subscribe to your other windows GotFocus and LostFocus events and use the following as the event handlers:
您可以将其添加到您的 Windows 标签中
然后,如果您希望用户确认它以便继续,您也可以显示它。
首先尝试不使用 TopMost 参数并查看结果。
You can add this to your windows tags
Then you can also display it if you want your users to acknowledge it in order to proceed
First try it without TopMost parameters and see the results.
试试这个:
Try this:
怎么样:
How about htis:
我也遇到了同样的问题,并跟随谷歌解决了这个问题。最近我发现以下内容对我有用。
I too faced the same problem and followed Google to this question. Recently I found the following worked for me.
我刚刚遇到了同样的问题。我有一个具有多个 WPF 窗口的桌面应用程序,并且我只需要将自定义启动屏幕置于应用程序中其他窗口的顶部。当我的启动屏幕出现时,没有其他窗口打开,但经过一些身份验证后,我确实从启动屏幕打开了主窗口。所以我只是做了一些类似于 @GlenSlayden 所做的事情,但在代码后面,因为就像我说的那样,主窗口不适合我绑定到:
现在,当我的程序正在从主窗口加载所有其他窗口时,启动屏幕位于顶部,但是当程序对用户进行身份验证时,它不是最顶部的,因此您可以单击其他程序,它会隐藏在其后面。这是我能找到的最接近解决这个问题的方法。它并不完美,因为当我的程序在身份验证后加载时,它仍然超越所有其他应用程序,但就我而言,这种情况不会持续很长时间。
I just ran into this same issue. I have a desktop app that has multiple WPF windows, and I needed my custom splash screen to be on top of the other windows in my app only. No other windows are open when my splash screen comes up, but I do open the MainWindow from my splash screen after some authentication. So I just did something similar to what @GlenSlayden did but in code behind since, like I said, the MainWindow isn't up for me to bind to:
Now while my program is loading all the other windows from the MainWindow, the splash screen is on top, but while the program is authenticating the user, it's not topmost, so you can click away on some other program and it will hide behind it. It's the closest thing I could find to a solution for this problem. It's not perfect because it still goes over top of all other applications while my program is loading after authentication, but that's not for very long in my case.
我刚刚遇到了同样的问题,发现使用 MVVM 设置所有者时遇到了麻烦,而不会导致应用程序在生产中崩溃。我有一个窗口管理器视图模型,其中包含使用窗口的 uri 打开窗口的命令 - 并且我无法将所有者设置为 App.MainWindow 而不导致应用程序崩溃。
因此,我没有设置所有者,而是将窗口的 TopMost 属性绑定到窗口管理器视图模型中的一个属性,该属性指示应用程序当前是否处于活动状态。如果应用程序处于活动状态,窗口将按照我的意愿位于顶部。如果它不活动,其他窗口可以覆盖它。
这是我添加到视图模型中的内容:
这是实现它的 XAML(我使用 MVVM light 和 ViewModelLocator 作为我的应用程序中名为 Locator 的静态资源):
I just ran into the same problem and found trouble setting the owner using MVVM without causing the app to crash in production. I have a Window Manager View Model that includes a command to open a window using the uri of the window - and I wasn't able to set the owner to App.MainWindow without the app crashing.
So - Instead of setting the owner, I bound the TopMost property of the window to a property in my Window Manager View model which indicates whether the application is currently active. If the application is active, the window is on top as I would like. If it is not active, other windows can cover it.
Here is what I added to my View Model:
Here is the XAML that implements it (I use MVVM light with a ViewModelLocator as a static resource in my app called Locator):
这对我有帮助:
This is what helped me:
这是我对这个问题的第二个回答;我发现了另一种非常有效的技术,用于管理属于单个
Application
的多个Window
实例正如许多人所指出的,
Window.Owner
属性是关键。每当您的应用处于活动状态(即其中一个窗口IsActive
)时,您都希望所有窗口的Owner
属性为null
。这允许在应用程序中的各个窗口之间进行平等的切换。但是,当您的应用未处于活动状态时,您需要为每个非<代码>Window.Owner 属性code>MainWindow 窗口设置为您的
MainWindow
。这样,您就可以使用任何应用程序的窗口来重新激活,并且您的所有应用程序的窗口都将在所有其他应用程序之前恢复。每次重新激活应用程序时,将
Window.Owner
值切换回null
。Application.OnActivated
和Application.OnDeactivated
方法非常适合此目的。您必须单独保留所有窗口的列表,因为使用此解决方法意味着您将无法在
MainWindow
上方便地使用Window.OwnedWindows
属性,当需要执行这些调整时。This is my second answer to the question; I have found another very effective technique for managing multiple
Window
instances belonging to a singleApplication
As many have noted, the
Window.Owner
property is key. Whenever your app is active--meaning one of its windowsIsActive
--you want theOwner
property of all your windows to benull
. This allows equal switching between the various windows in your app.But when your app is not active, you want the
Window.Owner
property for each of your non-MainWindow
windows to be set to yourMainWindow
. This way, you can use any of your app's windows to re-activate, and all your app's windows will be restored in front of all other apps.Each time the app is re-activated, switch the
Window.Owner
values back tonull
. theApplication.OnActivated
andApplication.OnDeactivated
methods are perfect for this.You'll have to separately keep a list of all your windows, since using this workaround means you won't have the convenience of the
Window.OwnedWindows
property on yourMainWindow
, for when it comes time to perform these adjustments.刚学C#,也遇到过类似的情况。但找到了一个我认为可能有帮助的解决方案。你可能很久以前就想到了这一点。这将来自开始一个新项目,但您可以在任何项目中使用它。
1)开始新项目。
2) 转到“项目”,然后“新建 Windows 窗体”,然后选择“Windows 窗体”并命名为“Splash”。
3)根据需要设置大小、背景、文本等。
4) 在 Splash.cs 表单的属性下设置 Start Position: CenterScreen 和 TopMost: true
5) form1 添加“using System.Threading;”
6)form1类下添加“Splash flashscreen = new Splash();”
7) form1 添加“splashscreen.Show();”和“Application.DoEvents();”
8)form1在Events>>Focus>>Activated下添加“Thread.Sleep(4000);splashscreen.Close();”
9) Splash.cs 在“Public Splash”下添加“this.BackColor = Color.Aqua;” /可以使用任何颜色
10) 这是 Form1.cs 的代码
11) 这是 Splash.cs 上的代码
12) 我发现如果你不在启动画面中执行某些操作,那么屏幕将不会停留在顶部第一个表单需要激活的时间。
线程计数将在 x 秒后消失,因此您的程序正常。
Just learning C# and ran across similar situation. but found a solution that I think may help. You may have figured this a long time ago. this will be from starting a new project but you can use it in any.
1) Start new project.
2) go to Project, then New Windows form, then select Windows Form and name Splash.
3) set size, background, text, etc as desired.
4) Under Properties of the Splash.cs form set Start Position: CenterScreen and TopMost: true
5) form1 add "using System.Threading;"
6) form1 under class add "Splash splashscreen = new Splash();"
7) form1 add "splashscreen.Show();" and "Application.DoEvents();"
8) form1 Under Events>>Focus>>Activated add "Thread.Sleep(4000); splashscreen.Close();"
9) Splash.cs add under "Public Splash" add "this.BackColor = Color.Aqua;" /can use any color
10) This is the code for Form1.cs
11) this is the code on Splash.cs
12) I found that if you do NOT do something in the splash then the screen will not stay on the top for the time the first form needs to activate.
The Thread count will disappear the splash after x seconds, so your program is normal.