TopMost 并不总是 TopMost - WPF

发布于 2024-09-19 23:35:28 字数 113 浏览 6 评论 0原文

我有一个时钟应用程序。我已经设置了窗口的 TopMost 属性。但是,随机地,其他一些窗口或视觉工作室出现在时钟之上。

有没有其他方法可以使我的窗口(时钟应用程序)始终显示在所有其他应用程序之上。

I have a clock application. I have set the Window's TopMost property. But, randomly, some other window or visual studio comes above clock.

Is there any other way to make my window (clock app) to display always on top of all other applications.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苏佲洛 2024-09-26 23:35:28

我知道这个问题已经很老了,但我不太明白为什么接受的答案已经获得了投票......或者为什么它被接受......它并没有真正回答这个问题,或者提供最近发布的这么短的解决方案和答案,几乎总是被社区投票和/或删除。嗯,我猜它是在不同时间发布的。

不管怎样,尽管它已经很老了,但我为将来可能遇到这篇文章的任何人提供了一个可能的解决方案。您可以简单地处理窗口。停用事件和/或Application.Deactivated 事件Window.Deactivated 事件当窗口成为背景窗口并且Application.Deactivated 事件 当应用程序不再是前台应用程序时发生

这个想法是在每次应用程序或 Window 失去焦点时将相关的 TopMost 属性设置为 true

private void Window_Deactivated(object sender, EventArgs e)
{
    // The Window was deactivated 
    this.TopMost = true;
}

值得注意的是,其他开发人员也可以使用这种技术,所以这并不能保证您的Window始终保持在顶部,但它对我有用,并且通过使用它,情况肯定会得到改善。

I know that this question is old, but I don't quite understand why the accepted answer has received up votes... or why it was accepted... it doesn't really answer the question, or provide a solution and answers posted these days that are that short are almost always down voted and/or deleted by the community. Ah well, I guess it was posted in different times.

Either way, as old as it is, I have a possible solution for anyone who may come across this post in the future. You can simply handle the Window.Deactivated Event and/or the Application.Deactivated Event. The Window.Deactivated Event occurs when a window becomes a background window and the Application.Deactivated Event occurs when an application stops being the foreground application.

The idea is to set the relevant TopMost property to true each time your application or Window loses focus:

private void Window_Deactivated(object sender, EventArgs e)
{
    // The Window was deactivated 
    this.TopMost = true;
}

It's worth noting that other developers can also use this technique, so this doesn't guarantee that your Window will always remain on top, but it works for me and the situation is still certainly improved by using it.

熟人话多 2024-09-26 23:35:28

在大多数情况下这应该可以解决问题

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.
}

This should do the trick in most cases

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.
}
一笑百媚生 2024-09-26 23:35:28

在现有窗口上设置 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);

I also had this problem when setting Window.Topmost = true on already existing window sometimes worked, sometimes not. Below is my workaround, you can probably combine it with Window_Deactivated approach mentioned by other people, if WS_EX_TOPMOST style is lost at runtime.

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)));

Extra code:

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);
自由范儿 2024-09-26 23:35:28

你确定这是一个随机窗口吗?如果另一个窗口也是最顶层窗口,则它有可能位于您的窗口上方。

Are you sure it's a random window? If another window is also a topmost window, it is possible for it to come above your window.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文