Bring a window to the front in WPF
Asked Answered
P

20

243

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.

Paintbrush answered 2/11, 2008 at 23:42 Comment(3)
Have you verified that MainWindow is the window you want? From MSDN: MainWindow is automatically set with a reference to the first Window object to be instantiated in the AppDomain.Rothberg
Good thought, but it is the only Window in the application.Paintbrush
Can you give a bit more context code?Rothberg
P
3

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();
}
Paintbrush answered 3/11, 2008 at 1:40 Comment(3)
Just interested: Did you try Window.Activate (as suggested by Morten) and the other suggestions? They seem less hacky than this admitted kludge.Posterior
This has been quite awhile ago, but yes, at the time I did try thatPaintbrush
This does not work on my Windows XP. I recommend @Matthew Xavier 's answer.Aciculate
P
348
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;
Porpoise answered 20/12, 2008 at 20:32 Comment(10)
I was simply using myWindow.Show() and sometimes it wasn't on top. I placed a call to myWindow.Activate() immediately afterwards and it worked.Pretypify
Activate does not work on Windows XP sometimes. I recommend @Matthew Xavier 's answer.Aciculate
A bit odd, since by default ShowActivated is on.Crept
The first answer is good, thanks for that! But the second line of code, using the Topmost property is a bad practice since it can obscure other popup dialogs and have unexpected behavior.Lancelle
It doesn't work on Windows 7 if the window is already open, but below other windowsHarvey
Won't restore minimized windows. You'll need to store the last state of the window and restore that or use the Topmost hack.Interphase
Actually it can be done with this: if (myWindow.WindowState == WindowState.Minimized) myWindow.WindowState = WindowState.Normal; Oddly it will also preserve any Maximized windows and not revert them to a Normal state.Interphase
I got this to work by calling it in the Window Loaded event. It was not working for me in the constructor.Isolative
@MortenChristiansen My main window has a data grid that is loaded from constructor of the window. When the main window is opened from another window (that updates the data) the datagrid gets refreshed with updated data. Your solution did not refresh the datagrid with the updated data. This solution from @Jader Dias worked for me. However, your solution probably suits better in some other scenarios such as the one OP asked.Rabblerouser
Only works in VS debug mode!Nonintervention
L
193

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
Literacy answered 28/1, 2011 at 18:39 Comment(10)
Great hint! TopMost makes the magic happen on Windows 7 if the window is already open, but below the other windows.Radie
This did the trick for me too. Thanks to gsb for the additional comment about what looks like a strange use of TopMost!Quicktempered
In my case Window.Activate() and Window.Focus() were sufficient. Setting Window.TopMost is unnecessary.Hung
Your addition of 'Window.Focus();' made me realize that I needed it in my own code! Thanks!Mathew
Do not use Window.Focus(). This will grab the focus away from what the user is currently typing in a text box, which is insanely frustrating for end users. The code above works just fine without it.Vulpine
Speaking of the comment above, we have an old VB6 program which calls Window.Focus() when showing an alert. It pops up 5 alerts every 10 minutes, and every time, it grabs the focus away, and the user loses whatever they were typing, and they have to use the mouse to put the cursor back where it was. It drives hundreds of user crazy.Vulpine
Topmost = true; was what i was looking for. Thank youBoynton
in my use case, window.Focus() is useful, used because other windows in the same app may have opened that are supposed to be background windows, and this is only used at app startup. For an example of doing this after ShowDialog() see gist.github.com/ImaginaryDevelopment/…Curacy
That is a clever solution, I wonder if Microsoft 'fixed' it later, as it violates their intended 'protection' of bringing windows to the front by your toggle of the 'topmost' attribute.Adelbert
Set e.Handled=true; if executing from a mouse click event or else the mouse click will override this if your two windows are on the same screen.Joinery
C
39

In case you need the window to be in front the first time it loads then you should use the following:

private void Window_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
}

private void Window_Initialized(object sender, EventArgs e)
{
    this.Topmost = true;
}

Or by overriding the methods:

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

protected override void OnInitialized(EventArgs e)
{
    base.OnInitialized(e);
    Topmost = true;
}
Capeskin answered 14/10, 2009 at 9:29 Comment(1)
If you develop something similar to Launchy (launchy.net) in C#, you should notice this answer is almost useless.Aciculate
R
28

I know this question is rather old, but I've just come across this precise scenario and wanted to share the solution I've implemented.

As mentioned in comments on this page, several of the solutions proposed do not work on XP, which I need to support in my scenario. While I agree with the sentiment by @Matthew Xavier that generally this is a bad UX practice, there are times where it's entirely a plausable UX.

The solution to bringing a WPF window to the top was actually provided to me by the same code I'm using to provide the global hotkey. A blog article by Joseph Cooney contains a link to his code samples that contains the original code.

I've cleaned up and modified the code a little, and implemented it as an extension method to System.Windows.Window. I've tested this on XP 32 bit and Win7 64 bit, both of which work correctly.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace System.Windows
{
    public static class SystemWindows
    {
        #region Constants

        const UInt32 SWP_NOSIZE = 0x0001;
        const UInt32 SWP_NOMOVE = 0x0002;
        const UInt32 SWP_SHOWWINDOW = 0x0040;

        #endregion

        /// <summary>
        /// Activate a window from anywhere by attaching to the foreground window
        /// </summary>
        public static void GlobalActivate(this Window w)
        {
            //Get the process ID for this window's thread
            var interopHelper = new WindowInteropHelper(w);
            var thisWindowThreadId = GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);

            //Get the process ID for the foreground window's thread
            var currentForegroundWindow = GetForegroundWindow();
            var currentForegroundWindowThreadId = GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);

            //Attach this window's thread to the current window's thread
            AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);

            //Set the window position
            SetWindowPos(interopHelper.Handle, new IntPtr(0), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

            //Detach this window's thread from the current window's thread
            AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);

            //Show and activate the window
            if (w.WindowState == WindowState.Minimized) w.WindowState = WindowState.Normal;
            w.Show();
            w.Activate();
        }

        #region Imports

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

        [DllImport("user32.dll")]
        private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        #endregion
    }
}

I hope this code helps others who encounter this problem.

Rochdale answered 19/7, 2012 at 1:56 Comment(6)
Hey lookie there! I've been struggling with this for months! This works for both my situations. Awesome! (Windows 7 x64)Modestia
Actually, it only seems to work if I do this: App.mainWindow.Show(); SystemWindows.GlobalActivate(App.mainwindow); // When I remove the first .show() it does not bring to frontModestia
+1 for SetWindowPos(), I was looking for a way to only bring my Window to front without interrupting other apps or stealing focus. this.Activate() steals focus.Signpost
This did it for me, and it my case the whole point was to steal focus, as it happend when a user interacted with certain element. so Thanks alot this seems to work consistent! just calling this.Activate() only seems to work some times.Emblematize
Thank you. This worked when most other methods I've tried failed (I haven't tried every suggestion in this question).Hydrometallurgy
Several years ago I found the top-rated answer (Activate/TopMost) worked and up-voted it. But now today in Windows 10, I have repeatable examples were it does not work. This answer fortunately DOES work in those edge cases.Installation
G
25

To make this a quick copy-paste one -
Use this class' DoOnProcess method to move process' main window to foreground (but not to steal focus from other windows)

public class MoveToForeground
{
    [DllImportAttribute("User32.dll")]
    private static extern int FindWindow(String ClassName, String WindowName);

    const int SWP_NOMOVE        = 0x0002;
    const int SWP_NOSIZE        = 0x0001;            
    const int SWP_SHOWWINDOW    = 0x0040;
    const int SWP_NOACTIVATE    = 0x0010;
    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

    public static void DoOnProcess(string processName)
    {
        var allProcs = Process.GetProcessesByName(processName);
        if (allProcs.Length > 0)
        {
            Process proc = allProcs[0];
            int hWnd = FindWindow(null, proc.MainWindowTitle.ToString());
            // Change behavior by settings the wFlags params. See http://msdn.microsoft.com/en-us/library/ms633545(VS.85).aspx
            SetWindowPos(new IntPtr(hWnd), 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
        }
    }
}

HTH

Goggle answered 26/9, 2011 at 18:47 Comment(3)
+1 this is the only answer that was useful for me. I have an application with one master and several floating slave windows. Upon activating any of these, all other windows should be brought to front as well. But not activated/gain focus as most answers suggest: that is a disaster as it makes the window currently clicked on unclickable since suddenly another window gains focus.Arlberg
Any reason for not using process.MainWindowHandle?Overseer
In my case, I didn't want the main window, but agreed, there's other ways of getting an hWnd. FWIW an HwndSource object worked well.Towboat
V
14

Why some of the answers on this page are wrong!

  • Any answer that uses window.Focus() is wrong.

    • Why? If a notification message pops up, window.Focus() will grab the focus away from whatever the user is typing at the time. This is insanely frustrating for end users, especially if the popups occur quite frequently.
  • Any answer that uses window.Activate() is wrong.

    • Why? It will make any parent windows visible as well.
  • Any answer that omits window.ShowActivated = false is wrong.
    • Why? It will grab the focus away from another window when the message pops up which is very annoying!
  • Any answer that does not use Visibility.Visible to hide/show the window is wrong.
    • Why? If we are using Citrix, if the window is not collapsed when it is closed, it will leave a weird black rectangular hold on the screen. Thus, we cannot use window.Show() and window.Hide().

Essentially:

  • The window should not grab the focus away from any other window when it activates;
  • The window should not activate its parent when it is shown;
  • The window should be compatible with Citrix.

MVVM Solution

This code is 100% compatible with Citrix (no blank areas of the screen). It is tested with both normal WPF and DevExpress.

This answer is intended for any use case where we want a small notification window that is always in front of other windows (if the user selects this in the preferences).

If this answer seems more complex than the others, it's because it is robust, enterprise level code. Some of the other answers on this page are simple, but do not actually work.

XAML - Attached Property

Add this attached property to any UserControl within the window. The attached property will:

  • Wait until the Loaded event is fired (otherwise it cannot look up the visual tree to find the parent window).
  • Add an event handler that ensures that the window is visible or not.

At any point, you can set the window to be in front or not, by flipping the value of the attached property.

<UserControl x:Class="..."
         ...
         attachedProperties:EnsureWindowInForeground.EnsureWindowInForeground=
             "{Binding EnsureWindowInForeground, Mode=OneWay}">

C# - Helper Method

public static class HideAndShowWindowHelper
{
    /// <summary>
    ///     Intent: Ensure that small notification window is on top of other windows.
    /// </summary>
    /// <param name="window"></param>
    public static void ShiftWindowIntoForeground(Window window)
    {
        try
        {
            // Prevent the window from grabbing focus away from other windows the first time is created.
            window.ShowActivated = false;

            // Do not use .Show() and .Hide() - not compatible with Citrix!
            if (window.Visibility != Visibility.Visible)
            {
                window.Visibility = Visibility.Visible;
            }

            // We can't allow the window to be maximized, as there is no de-maximize button!
            if (window.WindowState == WindowState.Maximized)
            {
                window.WindowState = WindowState.Normal;
            }

            window.Topmost = true;
        }
        catch (Exception)
        {
            // Gulp. Avoids "Cannot set visibility while window is closing".
        }
    }

    /// <summary>
    ///     Intent: Ensure that small notification window can be hidden by other windows.
    /// </summary>
    /// <param name="window"></param>
    public static void ShiftWindowIntoBackground(Window window)
    {
        try
        {
            // Prevent the window from grabbing focus away from other windows the first time is created.
            window.ShowActivated = false;

            // Do not use .Show() and .Hide() - not compatible with Citrix!
            if (window.Visibility != Visibility.Collapsed)
            {
                window.Visibility = Visibility.Collapsed;
            }

            // We can't allow the window to be maximized, as there is no de-maximize button!
            if (window.WindowState == WindowState.Maximized)
            {
                window.WindowState = WindowState.Normal;
            }

            window.Topmost = false;
        }
        catch (Exception)
        {
            // Gulp. Avoids "Cannot set visibility while window is closing".
        }
    }
}

Usage

In order to use this, you need to create the window in your ViewModel:

private ToastView _toastViewWindow;
private void ShowWindow()
{
    if (_toastViewWindow == null)
    {
        _toastViewWindow = new ToastView();
        _dialogService.Show<ToastView>(this, this, _toastViewWindow, true);
    }
    ShiftWindowOntoScreenHelper.ShiftWindowOntoScreen(_toastViewWindow);
    HideAndShowWindowHelper.ShiftWindowIntoForeground(_toastViewWindow);
}

private void HideWindow()
{
    if (_toastViewWindow != null)
    {
        HideAndShowWindowHelper.ShiftWindowIntoBackground(_toastViewWindow);
    }
}

Additional links

For tips on how ensure that a notification window always shifts back onto the visible screen, see my answer: In WPF, how to shift a window onto the screen if it is off the screen?.

Vulpine answered 20/4, 2016 at 10:18 Comment(8)
"Enterprise level code" and a few lines later catch (Exception) { }. Yeah right... And it uses code that isn't even shown in the answer like _dialogService or ShiftWindowOntoScreenHelper. Plus asking to create the window in viewmodel side (which basically breaks the whole MVVM pattern)...Edifice
@Edifice This is enterprise level code. I typed it out from memory, and this exact technique is used in a large FTSE100 company. Real life is somewhat less pristine compared to the perfect design patterns that we are all aiming for.Vulpine
I don't like the fact that we keep an instance of the window in the view model myself, as Kryptos mentioned that breaks the whole point of mvvm, maybe it could have been done in codebehind instead?Oconnor
@Igor Meszaros Agreed. Now that I have more experience, if I had to do it again, it I would add a Behavior, and control it using a Func<> that is bound to the ViewModel.Vulpine
I would like to ask, does the active window mean it must be at the top?Nonintervention
Hi, @Contango, I just found this post and it really helped, but I still have some questions, could you please kinkdly help me out? My question is: 1) what is "EnsureWindowInForeground.EnsureWindowInForeground" in the code you posted above, Is it a ViewModel or something? Do I have to write it by myself? and 2), In your post, there is an "XAML - Attached Property" and a "C# - Helper Method", are they separate solutions, or do they work together to achieve our target?Litalitany
@Litalitany 1) It's an attached property, see code 2) They work together.Vulpine
@Vulpine But I don't see any type named "EnsureWindowInForeground" in you code.Litalitany
S
13

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.
Simpleton answered 6/1, 2009 at 4:43 Comment(5)
Good point. The purpose of the code was in conjunction with a global hotkey, though, and other applications do it somehow.Paintbrush
Have to use PInvoke in C# to emulate what is described in this article, codeproject.com/Tips/76427/…Aciculate
then why do expression blends error popup dialogs stay visible when I switch to visual studio sometimes? :-/Branca
Simon, I suspect that the error popups you see are "topmost" windows (a design decision of which I disapprove). There is a difference between the foreground window (which receives user input) and a "topmost" window in the Z-order. Any window can make itself "topmost", which places it atop all non-topmost windows, but doesn't give the window keyboard focus, etc. the way becoming the foreground window does.Simpleton
The trick fails for a few special windows. Visual Studio and command prompt windows must have something that prevents other window becoming the foreground window.Aciculate
C
8

I know that this is late answer, maybe helpful for researchers

 if (!WindowName.IsVisible)
 {
     WindowName.Show();
     WindowName.Activate();
 }
Caracal answered 11/12, 2014 at 10:17 Comment(0)
P
7

I have had a similar problem with a WPF application that gets invoked from an Access application via the Shell object.

My solution is below - works in XP and Win7 x64 with app compiled to x86 target.

I'd much rather do this than simulate an alt-tab.

void Window_Loaded(object sender, RoutedEventArgs e)
{
    // make sure the window is normal or maximised
    // this was the core of the problem for me;
    // even though the default was "Normal", starting it via shell minimised it
    this.WindowState = WindowState.Normal;

    // only required for some scenarios
    this.Activate();
}
Poteet answered 7/10, 2010 at 23:41 Comment(0)
H
5

Well, since this is such a hot topic... here is what works for me. I got errors if I didn't do it this way because Activate() will error out on you if you cannot see the window.

Xaml:

<Window .... 
        Topmost="True" 
        .... 
        ContentRendered="mainWindow_ContentRendered"> .... </Window>

Codebehind:

private void mainWindow_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
    this.Activate();
    _UsernameTextBox.Focus();
}

This was the only way for me to get the window to show on top. Then activate it so you can type in the box without having to set focus with the mouse. control.Focus() wont work unless the window is Active();

Haya answered 16/8, 2012 at 15:51 Comment(1)
Works for me with splash screen showing before. Thank you.Shortridge
P
3

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();
}
Paintbrush answered 3/11, 2008 at 1:40 Comment(3)
Just interested: Did you try Window.Activate (as suggested by Morten) and the other suggestions? They seem less hacky than this admitted kludge.Posterior
This has been quite awhile ago, but yes, at the time I did try thatPaintbrush
This does not work on my Windows XP. I recommend @Matthew Xavier 's answer.Aciculate
W
2

To show ANY currently opened window import those DLL:

public partial class Form1 : Form
{
    [DllImportAttribute("User32.dll")]
    private static extern int FindWindow(String ClassName, String WindowName);
    [DllImportAttribute("User32.dll")]
    private static extern int SetForegroundWindow(int hWnd);

and in program We search for app with specified title (write title without first letter (index > 0))

  foreach (Process proc in Process.GetProcesses())
                {
                    tx = proc.MainWindowTitle.ToString();
                    if (tx.IndexOf("Title of Your app WITHOUT FIRST LETTER") > 0)
                    {
                        tx = proc.MainWindowTitle;
                        hWnd = proc.Handle.ToInt32(); break;
                    }
                }
                hWnd = FindWindow(null, tx);
                if (hWnd > 0)
                {
                    SetForegroundWindow(hWnd);
                }
Wellmannered answered 11/11, 2010 at 17:32 Comment(1)
"Title of Your app WITHOUT FIRST LETTER" Oof, hacky hacky hacky. Why not use IndexOf properly, instead?Entozoon
S
2

These codes will work fine all times.

At first set the activated event handler in XAML:

Activated="Window_Activated"

Add below line to your Main Window constructor block:

public MainWindow()
{
    InitializeComponent();
    this.LocationChanged += (sender, e) => this.Window_Activated(sender, e);
}

And inside the activated event handler copy this codes:

private void Window_Activated(object sender, EventArgs e)
{
    if (Application.Current.Windows.Count > 1)
    {
        foreach (Window win in Application.Current.Windows)
            try
            {
                if (!win.Equals(this))
                {
                    if (!win.IsVisible)
                    {
                        win.ShowDialog();
                    }

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

                    win.Activate();
                    win.Topmost = true;
                    win.Topmost = false;
                    win.Focus();
                }
            }
            catch { }
    }
    else
        this.Focus();
}

These steps will works fine and will bring to front all other windows into their parents window.

Some answered 5/2, 2017 at 9:37 Comment(0)
Q
2

Just wanted to add another solution to this question. This implementation works for my scenario, where CaliBurn is responsible for displaying the main Window.

protected override void OnStartup(object sender, StartupEventArgs e)
{
    DisplayRootViewFor<IMainWindowViewModel>();

    Application.MainWindow.Topmost = true;
    Application.MainWindow.Activate();
    Application.MainWindow.Activated += OnMainWindowActivated;
}

private static void OnMainWindowActivated(object sender, EventArgs e)
{
    var window = sender as Window;
    if (window != null)
    {
        window.Activated -= OnMainWindowActivated;
        window.Topmost = false;
        window.Focus();
    }
}
Quadruped answered 12/4, 2017 at 21:19 Comment(0)
G
2

I wanted to create a launcher with the keyboard hook and had the same problem. After much trial and error, this solved the problem.

void Active()
{
    MainWindow0.Show();
    MainWindow0.Focus();
    MainWindow0.Activate();
    MainWindow0.WindowState = WindowState.Normal;
}

void Deactive()
{
    MainWindow0.Hide();
    MainWindow0.WindowState = WindowState.Minimized;
}
Gaw answered 25/2, 2023 at 8:53 Comment(0)
E
1

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.

Earhart answered 27/2, 2009 at 21:3 Comment(0)
B
1

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

    ....
}
Bostwick answered 16/12, 2021 at 16:11 Comment(0)
E
0

If you are trying to hide the window, for example you minimize the window, I have found that using

    this.Hide();

will hide it correctly, then simply using

    this.Show();

will then show the window as the top most item once again.

Ebarta answered 24/9, 2014 at 18:31 Comment(0)
S
0

Remember not to put the code that shows that window inside a PreviewMouseDoubleClick handler as the active window will switch back to the window who handled the event. Just put it in the MouseDoubleClick event handler or stop bubbling by setting e.Handled to True.

In my case i was handling the PreviewMouseDoubleClick on a Listview and was not setting the e.Handled = true then it raised the MouseDoubleClick event witch sat focus back to the original window.

Sherburne answered 24/4, 2017 at 19:45 Comment(0)
E
-2

I built an extension method to make for easy reuse.

using System.Windows.Forms;
    namespace YourNamespace{
        public static class WindowsFormExtensions {
            public static void PutOnTop(this Form form) {
                form.Show();
                form.Activate();
            }// END PutOnTop()       
        }// END class
    }// END namespace

Call in the Form Constructor

namespace YourNamespace{
       public partial class FormName : Form {
       public FormName(){
            this.PutOnTop();
            InitalizeComponents();
        }// END Constructor
    } // END Form            
}// END namespace
Embay answered 18/5, 2017 at 17:53 Comment(4)
Hi Mike. You are answering this question quite late. Can you explain in your answer why this approach is different (and perhaps better) from the very good answers that were already posted for this question?Eley
Only late as I just needed to do this, and I came across this and wanted to share how i solved the problem encase others wanted to use it.Embay
Sure, I was choosen to review your post and wanted to make you aware. It is always good to provide a new answer if you think it is a good contribution to the community.Eley
This question was specifically about WPF, but your solution is for WinForms.Milt

© 2022 - 2025 — McMap. All rights reserved.