前言
窗口置顶有两种情况
- 应用内的窗口置顶
- 应用外的窗口置顶
一般我们这样设置窗口置顶
1 | <Window Topmost="True"></Window> |
但是如果其他程序也置顶,后来的置顶就会覆盖之前的置顶,所以我们要保证我们的窗口永远置顶就要做如下设置。
窗口永远置顶
窗口置顶只设置Topmost = true
,有时并不能生效,比如有多个置顶的窗口,比如系统底部的任务栏,当有多个置顶的窗口,谁激活了,谁就在最顶部。
一个应用中不要设置多个窗口永远置顶。
Deactivated
既然谁激活谁在顶部,那我们可以在失去激活的时候再调用一下置顶即可。
您可以Topmost = true
在Window.Deactivated
事件的处理程序中设置:
Window.Deactivated
在窗口成为后台窗口时发生。
XAML:
1 | <Window |
或者
1 | Deactivated += Window_Deactivated; |
代码
1 | private void Window_Deactivated(object sender, EventArgs e) |
Deactivated
只要您的应用程序失去焦点(通常在另一个应用程序请求时Topmost
),就会调用该事件,因此这将在此之后重置您的应用程序.
这里为什么先取消置顶再置顶是因为
已经在置顶状态的窗口再次设置置顶是无效的。
这种方案不能保证窗口永远置顶,是因为:
假如我们先点击了其他窗口,再点击任务栏,就会发现置顶又失效了,这是因为,第一次失去焦点确实置顶生效了,但是失去焦点后另一个窗口再获取焦点,原来失去焦点的窗口事件就不会再触发了,原来的这个窗口就不再置顶了。
既然如此,我们在非激活的时候重新激活就行了,但是一定要添加延迟。
1 | private void Window_Deactivated(object sender, EventArgs e) |
但是
这样虽然可以保证窗口一直置顶,但是影响别的窗口的操作,特别是输入文字。
定时检测+WindowAPI
注意
这种方式还是比较完美的。不但能保证窗口置顶,还不影响其他窗口的输入。
WPF窗体的句柄然后调用WindowAPI使窗口置顶。
搞个线程,每隔500ms设置一下窗体置顶
1 | public SelectAreaWin() |
窗口置顶工具类
1 | namespace z_screen_recorder.Utils |
外部应用窗口置顶
工具类
1 | public class ZWinUtil |
调用
1 | ZWinUtil.SetWinShow("文件资源管理器"); |
当前窗口句柄
1 | IntPtr handle; |