Bring a window to the front in WPF

Viewed 204669

How can I bring my WPF application to the front of the desktop? So far I've tried:

SwitchToThisWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle, true);

SetWindowPos(new WindowInteropHelper(Application.Current.MainWindow).Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);

None of which are doing the job (Marshal.GetLastWin32Error() is saying these operations completed successfully, and the P/Invoke attributes for each definition do have SetLastError=true).

If I create a new blank WPF application, and call SwitchToThisWindow with a timer, it works exactly as expected, so I'm not sure why it's not working in my original case.

Edit: I'm doing this in conjunction with a global hotkey.

19 Answers
myWindow.Activate();

Attempts to bring the window to the foreground and activates it.

That should do the trick, unless I misunderstood and you want Always on Top behavior. In that case you want:

myWindow.TopMost = true;

I have found a solution that brings the window to the top, but it behaves as a normal window:

if (!Window.IsVisible)
{
    Window.Show();
}

if (Window.WindowState == WindowState.Minimized)
{
    Window.WindowState = WindowState.Normal;
}

Window.Activate();
Window.Topmost = true;  // important
Window.Topmost = false; // important
Window.Focus();         // important

If the user is interacting with another application, it may not be possible to bring yours to the front. As a general rule, a process can only expect to set the foreground window if that process is already the foreground process. (Microsoft documents the restrictions in the SetForegroundWindow() MSDN entry.) This is because:

  1. The user "owns" the foreground. For example, it would be extremely annoying if another program stole the foreground while the user is typing, at the very least interrupting her workflow, and possibly causing unintended consequences as her keystrokes meant for one application are misinterpreted by the offender until she notices the change.
  2. Imagine that each of two programs checks to see if its window is the foreground and attempts to set it to the foreground if it is not. As soon as the second program is running, the computer is rendered useless as the foreground bounces between the two at every task switch.

Well I figured out a work around. I'm making the call from a keyboard hook used to implement a hotkey. The call works as expected if I put it into a BackgroundWorker with a pause. It's a kludge, but I have no idea why it wasn't working originally.

void hotkey_execute()
{
    IntPtr handle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(delegate
        {
            Thread.Sleep(10);
            SwitchToThisWindow(handle, true);
        });
    bg.RunWorkerAsync();
}

The problem could be that the thread calling your code from the hook hasn't been initialized by the runtime so calling runtime methods don't work.

Perhaps you could try doing an Invoke to marshal your code on to the UI thread to call your code that brings the window to the foreground.

This is a combination of a few suggestions above that works well and is simple. It only comes to front when those events fire, so any window that pops up after the event will stay on top of course.

public partial class MainWindow : Window
{
    protected override void OnContentRendered(EventArgs e)
    {
        base.OnContentRendered(e);

        Topmost = true;
        Topmost = false;
    }
    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);

        Topmost = true;
        Topmost = false;
    }

    ....
}
Related