我有一个时钟应用程序。我已经设置了 Window 的 TopMost 属性。但是,随机地,其他一些窗口或视觉工作室出现在时钟之上。
有没有其他方法可以让我的窗口(时钟应用程序)始终显示在所有其他应用程序之上。
我知道这个问题很老,但我不太明白为什么接受的答案得到了投票......或者为什么它被接受......它并没有真正回答这个问题,或者提供一个解决方案并发布答案这些短暂的日子几乎总是被社区否决和/或删除。嗯,我猜它是在不同的时间发布的。
无论哪种方式,尽管它已经很老了,但对于将来可能会遇到这篇文章的任何人,我都有一个可能的解决方案。您可以简单地处理Window.Deactivated
Event和/或Application.Deactivated
Event。当一个窗口变成背景窗口时发生Window.Deactivated
事件 ,当应用程序不再是前台应用程序时发生事件。Application.Deactivated
这个想法是在每次您的应用程序或失去焦点时设置相关TopMost
属性:true
Window
private void Window_Deactivated(object sender, EventArgs e)
{
// The Window was deactivated
this.TopMost = true;
}
值得注意的是,其他开发人员也可以使用此技术,因此这并不能保证您Window
将始终保持领先,但它对我有用,并且使用它肯定会改善情况。
在大多数情况下,这应该可以解决问题
private void Window_Deactivated(object sender, EventArgs e)
{
// The Window was deactivated
Topmost = false; // set topmost false first
Topmost = true; // then set topmost true again.
}
在已经存在的窗口上设置 Window.Topmost = true 时,我也遇到了这个问题,有时有效,有时无效。下面是我的解决方法,如果 WS_EX_TOPMOST 样式在运行时丢失,您可以将其与其他人提到的 Window_Deactivated 方法结合使用。
App.Current.MainWindow.Topmost = true;
// Get this window's handle
IntPtr hwnd = new WindowInteropHelper(App.Current.MainWindow).Handle;
// Intentionally do not await the result
App.Current.Dispatcher.BeginInvoke(new Action(async () => await RetrySetTopMost(hwnd)));
额外代码:
private const int RetrySetTopMostDelay = 200;
private const int RetrySetTopMostMax = 20;
// The code below will retry several times before giving up. This always worked with one retry in my tests.
private static async Task RetrySetTopMost(IntPtr hwnd)
{
for (int i = 0; i < RetrySetTopMostMax; i++)
{
await Task.Delay(RetrySetTopMostDelay);
int winStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
if ((winStyle & WS_EX_TOPMOST) != 0)
{
break;
}
App.Current.MainWindow.Topmost = false;
App.Current.MainWindow.Topmost = true;
}
}
internal const int GWL_EXSTYLE = -20;
internal const int WS_EX_TOPMOST = 0x00000008;
[DllImport("user32.dll")]
internal static extern int GetWindowLong(IntPtr hwnd, int index);
你确定这是一个随机窗口?如果另一个窗口也是最顶层的窗口,它可能会出现在您的窗口上方。