How to make a WPF window be on top of all other windows of my app (not system wide)?
Asked Answered
B

20

74

I want my window to be on top of all other windows in my application only. If I set the TopMost property of a window, it becomes on top of all windows of all applications and I don't want that.

Barbarese answered 30/3, 2010 at 15:43 Comment(4)
By the way, I cannot set a Owner on that window because that window is created before any other window (it is the application splash screen). Ref: #2463649Barbarese
Though the question is rather old, I just have to make this comment... Your question plus the comment is rather strange, you want to have your window at top of your application but in your comment you are stating that there is no application running since its the first window (splash screen), so how can your window be on top of a non existing application?!? This just makes me wonder how in the world this question could get 16 upvotes.Alcoran
When the app starts, there is no other window but the main window appears shortly after and has to stay behind the splash screen until all is loaded.Barbarese
Than why not let the splashscreen start as first window and if its done doing it stuff open the mainwindow? Just change the StartupUri of the application to the splashscreen. (msdn.microsoft.com/en-us/library/…)Alcoran
B
55

You need to set the owner property of the window.

You can show a window via showdialog in order to block your main window, or you can show it normal and have it ontop of the owner without blocking the owner.

here is a codeexample of the codebehind part - I left out all obvious stuff:

namespace StackoverflowExample
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }
    void NewWindowAsDialog(object sender, RoutedEventArgs e)
    {
      Window myOwnedDialog = new Window();
      myOwnedDialog.Owner = this;
      myOwnedDialog.ShowDialog();
    }
    void NormalNewWindow(object sender, RoutedEventArgs e)
    {
      Window myOwnedWindow = new Window();
      myOwnedWindow.Owner = this;
      myOwnedWindow.Show();
    }
  }
}
Belligerence answered 18/6, 2012 at 18:40 Comment(2)
This is exactly what I was looking for - how to open a new window that retains focus/activity until closed. Thank you.Peele
Better to add myOwnedDialog.ShowInTaskbar = false; in to NewWindowAsDialogTowne
I
17

Instead you can use a Popup that will be TopMost always, decorate it similar to a Window and to attach it completely with your Application handle the LocationChanged event of your main Window and set IsOpen property of Popup to false.

Edit:

I hope you want something like this:

    Window1 window;

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        window = new Window1();
        window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
        window.Topmost = true;
        this.LocationChanged+=OnLocationchanged;
        window.Show();
    }
     
    private void OnLocationchanged(object sender, EventArgs e)
    {
          if(window!=null)
              window.Close();
    }

Hope it helps!!!

Incubus answered 30/3, 2010 at 16:16 Comment(1)
This makes the window on top of all other applications as well. And what is the meaning of the LocationChanged handler (btw: handlers are not prefixed with 'On' by C# convention)?Begotten
M
14
CustomWindow cw = new CustomWindow();

cw.Owner = Application.Current.MainWindow;

cw.ShowInTaskbar = false;

cw.ShowDialog() ; 
Muth answered 27/3, 2012 at 7:18 Comment(5)
Can you provide some explanation along with your code - this helps everyone to understand your answerHypoglossal
If you configure window so, it will behave as desired. Window will be on top of all other windows in applicationMuth
Didn't work for me "null reference exception". My dialog is a WPF Window but the application and main window are WinForms.Bucksaw
This is going to make it modal. Want the secondary window to be in front of the main window, but be able to interact with the main window.Baseman
After setting Owner you can use Show only. Main window is clickable thenVictual
S
13

Simple to do it in XAML, and surprised that nobody posted this answer yet. In the following example, the Window is defined in a ResourceLibrary (notice the x:Key), but you can also use this XAML binding on a standalone Page-style WPF resource.

<Window x:Key="other_window" 
        Topmost="{Binding Source={x:Static Application.Current},Path=MainWindow.IsActive,Mode=OneWay}">
    <TextBlock Text="OTHER WINDOW" />
</Window>
Senegambia answered 4/7, 2016 at 21:21 Comment(1)
Simple and effective, thank you!Capuche
R
5

use the Activate() method. This attempts to bring the window to the foreground and activate it. e.g. Window wnd = new xyz(); wnd.Activate();

Roadside answered 6/12, 2010 at 16:40 Comment(0)
E
5

In the popup window, overloads the method Show() with a parameter:

Public Overloads Sub Show(Caller As Window)
    Me.Owner = Caller
    MyBase.Show()
End Sub

Then in the Main window, call your overloaded method Show():

Dim Popup As PopupWindow

Popup = New PopupWindow
Popup.Show(Me)
Extemporary answered 28/10, 2011 at 19:31 Comment(0)
P
4

I ran into a very similar situation as you. Most of the searches I came across stated all I needed to do was set the Owner of the windows I wish to be Topmost to the main window or whatever window that called Show.

Anyways, I'll go ahead and post a solution that worked well for me.

I created event handlers for Window.Activated and Window.Deactived in the window that was supposed to be Topmost with respect to my application.

private void Window_Activated(object sender, EventArgs e)
{
    Topmost = true;
}

private void Window_Deactived(object sender, EventArgs e)
{
    if(Owner == null || Owner.IsActive)
        return;
    bool hasActiveWindow = false;
    foreach(Window ownedWindow in Owner.OwnedWindows)
    {
        if(ownedWindow.IsActive)
            hasActiveWindow = true; 
    }

    if(!hasActiveWindow)
        Topmost = false;
}

It works great for me. Hopefully this is useful to someone else out there. :o)

Poundage answered 1/8, 2011 at 16:1 Comment(2)
When I click on another application, my window is no longer active, so Topmost never gets set to false.Cellarage
I was able to get this to work by check Topmost in the if statement, rather than IsActive: if (ownedWindow.Topmost)...Cellarage
Q
4

The best way is set this two events to all of windows of your app:

GotKeyboardFocus
LostKeyboardFocus

in this way:

WiondowOfMyApp_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = true;
}

WiondowOfMyApp_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = false;
}
  • and surely all of the windows that you wanted to be top, should be accessible from other windows of your app. in my case I have a base window and another some windows that should be top of my base window, so this was not bad to my base window has instance of each another windows.
Quinton answered 31/10, 2011 at 6:43 Comment(1)
This works flawlessly for making popup or utility windows that don't hover over other applications' windows when not active. Thanks!Bobodioulasso
Y
2

There are several threads, there's even a "topmost" tag. Search on that, or go directly to this post which looks good:

How to keep a window on top of all other windows in my application only?

Yap answered 30/3, 2010 at 15:52 Comment(2)
That question is for "Windows Forms" Windows. I have WPF Window.Barbarese
I can't set the Owner property because in my case, the window is created before any other windows. Therefore, I don't have any other window to set as the owner.Barbarese
B
2

I'm the OP. After some research and testing, the answer is:

No, there is no way to do exactly that.

Barbarese answered 8/4, 2010 at 16:15 Comment(3)
There are ways to do this. Some of the answers given are good candidates.Jeffersonjeffery
So, explain me how paint.net made the color, history and toolbox windows that is only on top of the application?Ankylostomiasis
@BurakYeniçeri 9 years later....I don't know. Back then I concluded that this was not possible after a lot of attempts. Much later Johannes came up with a solution that has a lot of upvotes, I suppose it's a good solution. I've cleared the "accept" on my own answer.Barbarese
E
1

Here's a way to do it: make your "topmost" window subscribe to your other windows GotFocus and LostFocus events and use the following as the event handlers:

class TopMostWindow
{
    void OtherWindow_LostFocus(object sender, EventArgs e)
    {
        this.Topmost = false;
    }

    void OtherWindow_GotFocus(object sender, EventArgs e)
    {
        this.Topmost = true;
    }
}
Endamoeba answered 4/7, 2010 at 19:9 Comment(0)
H
0

You can add this to your windows tags

WindowStartupLocation="CenterScreen"

Then you can also display it if you want your users to acknowledge it in order to proceed

YourWindow.ShowDialog();

First try it without TopMost parameters and see the results.

Hildredhildreth answered 30/3, 2010 at 20:0 Comment(6)
I don't want a modal window. Just a top level window.Barbarese
so why not just use the WindowStartupLocation="CenterScreen"Hildredhildreth
Because if the user click another windows that is behind, it will not stay on top. I want it to be always on top but I don't want it to block the other windows (that is what modal do).Barbarese
By the way, WindowStartupLocation only affects the initial values for the Top and Left properties of the window when it is opened; it does not affect the Z order.Barbarese
you're right about the WindowStartupLocation. Though, I don't understand the usability of having a window on top of every other windows and still not blocking them. Would you please elaborate more about it? Do you want to have this window on top, but still be able to change something in other windows?Hildredhildreth
In general, tool windows work like that. For instance, you can undock the "Tools" toolbar in Visual Studio and float it on top of your code window. You can still type in the code windows even if that window is on top. If you bring Notepad on top of Visual Studio, Notepad will hide the Tools window. Therefore that windows is on top of all windows in Visual Studio but not on top of all the windows of the system.Barbarese
K
0

Try this:

Popup.PlacementTarget = sender as UIElement;
Keffiyeh answered 30/10, 2013 at 5:43 Comment(0)
K
0

I too faced the same problem and followed Google to this question. Recently I found the following worked for me.

CustomWindow cw = new CustomWindow();
cw.Owner = this;
cw.ShowDialog();
Kanarese answered 27/6, 2015 at 7:48 Comment(1)
what if cw already existed, and you wanted this to be under it?Treble
P
0

How about htis:

Private Sub ArrangeWindows(Order As Window())
    For I As Integer = 1 To Order.Length -1
        Order(I).Owner = Order(I - 1)
    Next
End Sub
Pashto answered 15/10, 2016 at 11:38 Comment(0)
R
0

I just ran into this same issue. I have a desktop app that has multiple WPF windows, and I needed my custom splash screen to be on top of the other windows in my app only. No other windows are open when my splash screen comes up, but I do open the MainWindow from my splash screen after some authentication. So I just did something similar to what @GlenSlayden did but in code behind since, like I said, the MainWindow isn't up for me to bind to:

private void SplashScreen_ContentRendered(object sender, EventArgs e)
{
    // User authentication...
    // ...

    MainWindow mainWindow = new MainWindow();
    SetBinding(SplashScreen.TopmostProperty, new Binding("IsVisible"))
    {
        Source = mainWindow,
        Mode = BindingMode.OneWay,
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    };
    mainWindow.Show();
}

Now while my program is loading all the other windows from the MainWindow, the splash screen is on top, but while the program is authenticating the user, it's not topmost, so you can click away on some other program and it will hide behind it. It's the closest thing I could find to a solution for this problem. It's not perfect because it still goes over top of all other applications while my program is loading after authentication, but that's not for very long in my case.

Roam answered 20/11, 2017 at 17:25 Comment(0)
S
0

I just ran into the same problem and found trouble setting the owner using MVVM without causing the app to crash in production. I have a Window Manager View Model that includes a command to open a window using the uri of the window - and I wasn't able to set the owner to App.MainWindow without the app crashing.

So - Instead of setting the owner, I bound the TopMost property of the window to a property in my Window Manager View model which indicates whether the application is currently active. If the application is active, the window is on top as I would like. If it is not active, other windows can cover it.

Here is what I added to my View Model:

 public class WindowManagerVM : GalaSoft.MvvmLight.ViewModelBase
    {
        public WindowManagerVM()
        {
            App.Current.Activated += (s, e) => IsAppActive = true;
            App.Current.Deactivated += (s, e) => IsAppActive = false;
        }

        private bool _isAppActive = true;
        public bool IsAppActive
        {
            get => _isAppActive;
            set
            {
                if (_isAppActive != value)
                {
                    _isAppActive = value;
                    RaisePropertyChanged(() => IsAppActive);
                }
            }
        }
    }

Here is the XAML that implements it (I use MVVM light with a ViewModelLocator as a static resource in my app called Locator):

<Window Topmost="{Binding WindowManager.IsAppActive, Source={StaticResource Locator}}"/>
Substrate answered 11/2, 2019 at 16:21 Comment(0)
V
0

This is what helped me:

Window selector = new Window ();
selector.Show();
selector.Activate();
selector.Topmost = true;
Vestibule answered 12/11, 2019 at 17:29 Comment(0)
S
0

This is my second answer to the question; I have found another very effective technique for managing multiple Window instances belonging to a single Application

As many have noted, the Window.Owner property is key. Whenever your app is active--meaning one of its windows IsActive--you want the Owner property of all your windows to be null. This allows equal switching between the various windows in your app.

But when your app is not active, you want the Window.Owner property for each of your non-MainWindow windows to be set to your MainWindow. This way, you can use any of your app's windows to re-activate, and all your app's windows will be restored in front of all other apps.

Each time the app is re-activated, switch the Window.Owner values back to null. the Application.OnActivated and Application.OnDeactivated methods are perfect for this.

You'll have to separately keep a list of all your windows, since using this workaround means you won't have the convenience of the Window.OwnedWindows property on your MainWindow, for when it comes time to perform these adjustments.

public partial class MyApp : Application
{
    // not shown: keep this list of all your non-main windows updated...
    public List<Window> rgw = new List<Window>();

    protected override void OnActivated(EventArgs e)
    {
        // when app is ACTIVE, set all `Owner` values to null...
        rgw.ForEach(w => w.Owner = null);

        base.OnActivated(e);
    }

    protected override void OnDeactivated(EventArgs e)
    {
        // set `Owner` on all non-main Windows only when not-active
        rgw.ForEach(w => w.Owner = Current.MainWindow);  

        base.OnDeactivated(e);
    }

    // etc..
}
Senegambia answered 31/3, 2022 at 17:12 Comment(0)
G
-1

Just learning C# and ran across similar situation. but found a solution that I think may help. You may have figured this a long time ago. this will be from starting a new project but you can use it in any.

1) Start new project.

2) go to Project, then New Windows form, then select Windows Form and name Splash.

3) set size, background, text, etc as desired.

4) Under Properties of the Splash.cs form set Start Position: CenterScreen and TopMost: true

5) form1 add "using System.Threading;"

6) form1 under class add "Splash splashscreen = new Splash();"

7) form1 add "splashscreen.Show();" and "Application.DoEvents();"

8) form1 Under Events>>Focus>>Activated add "Thread.Sleep(4000); splashscreen.Close();"

9) Splash.cs add under "Public Splash" add "this.BackColor = Color.Aqua;" /can use any color

10) This is the code for Form1.cs

public partial class Form1 : Form
{
    Splash splashscreen = new Splash();
    public Form1()
    {
        InitializeComponent();
        splashscreen.Show();
        Application.DoEvents();

    }

    private void Form1_Activated(object sender, EventArgs e)
    {
        Thread.Sleep(4000);
        splashscreen.Close();
    }
}

11) this is the code on Splash.cs

public partial class Splash : Form
{
    public Splash()
    {
        InitializeComponent();
        this.BackColor = Color.Aqua;
    }
}

12) I found that if you do NOT do something in the splash then the screen will not stay on the top for the time the first form needs to activate. The Thread count will disappear the splash after x seconds, so your program is normal.

Gauche answered 20/5, 2018 at 22:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.