0

I can't get a form to remain on top, in .net

I have checked How to make form always on top in Application and the answer there mentions form1.TopLevel = true; and I've checked How to make a window always stay on top in .Net? and it says Form.ActiveForm.TopMost so i've tried Form.ActiveForm.TopMost = true; and this.TopMost = true;

private void Form1_Load(object sender, EventArgs e)
{
  this.TopLevel = true; //default anyway

  Form.ActiveForm.TopMost = true;
  this.TopMost = true;  
}

But as you can see, a notepad window or any window can cover it.

enter image description here

Added

I have tried every suggestion made so far.

In response to Han's advice, "Of all the possible places to set TopMost property, the Load event is the worst. It should be set in the constructor, so the window gets created top-most right away. Or it should be set after it is visible, so after the Load event. Use the constructor. ". I tried putting those lines in the constructor.

    public Form1()
    {
        InitializeComponent();
        this.TopLevel = true; //default anyway

        //Form.ActiveForm.TopMost = true; (commented to prevent a System.InvalidOperationException, presumably the form isn't yet active at this stage)
        this.TopMost = true;
    }

And the the other two suggestions, from others-

I tried setting the Form's TopMost field in the designer to True.

And running the EXE directly rather than just clicking play in visual studio.

Same issue.

And if you find that hard to believe, i've taken a 1min video here showing just that. https://screencast-o-matic.com/watch/cbXXrw2oTN

A potentially useful comment was mentioned..

Steve comments - "OK something definitively odd is happening here. I have tried to create a simple topmost form using linqpad and at the first run I get your same behavior. At the second run though everything works as expected."

barlop
  • 12,887
  • 8
  • 80
  • 109
  • Did you try it outside Visual Studio? (IE running the exe) – Steve Nov 11 '17 at 15:45
  • are you intending to open form as modal? – Chandan Rai Nov 11 '17 at 15:45
  • Of all the possible places to set TopMost property, the Load event is the worst. It should be set in the constructor, so the window gets created top-most right away. Or it should be set after it is visible, so after the Load event. Use the constructor. – Hans Passant Nov 11 '17 at 15:58
  • @HansPassant done though it still doesn't stay on top. – barlop Nov 12 '17 at 03:42
  • @Steve yes I tried running the exe directly, same issue – barlop Nov 12 '17 at 03:42
  • @crowchirp no i'm not intending anything to be a modal dialog, it's just the default form that loads up with a winforms application. – barlop Nov 12 '17 at 03:43
  • I am unable to reproduce your issue. Just created an empty form with only TopMost=True in the constructor of the form. It behaves as expected (stay on top of every other window unless anoterh TopMost window appears) So I think that your problem lies somewhere else in your code. I suggest to look at what events are triggered after that line of code and look carefully at what code is run there. – Steve Nov 12 '17 at 09:33
  • @Steve it's literally a new project with no other code added other than the code I mentioned. Any time i've ever used a utility to make windows stay on top they have always worked or a feature of a program to make it stay on top, it has worked. like MIRC has a stay on top option, or Deskpins lets you make windows stay on top, they always work.. Neither of those run in the background either. So there's no program that is stopping things from staying on top. I wonder what winapi function MIRC or deskpins uses? – barlop Nov 12 '17 at 14:06
  • OK something definitively odd is happening here. I have tried to create a simple topmost form using linqpad and at the first run I get your same behavior. At the second run though everything works as expected. – Steve Nov 12 '17 at 15:17
  • You can't. TopMost is only for your own form's collections. See [How do I create a topmost window that is never covered by other topmost windows?](https://blogs.msdn.microsoft.com/oldnewthing/20110310-00/?p=11253) – LarsTech Nov 13 '17 at 20:27
  • @LarsTech Your link has nothing to do with my question. I'm not asking how to get a window on top of a window that is already set to be on top. I'm asking about a simple function that many programs such as mirc or of course deskpins(which sets any window on top) or pasteitin do already. – barlop Nov 13 '17 at 22:34
  • How so? Looks like you are complaining that NotePad is staying above your window? – LarsTech Nov 13 '17 at 22:35
  • @LarsTech I don't know how I can be much clearer here. (and putting aside that your characterising of what I wrote as 'complaining' is absurd). Your link is talking about getting a window to stay on top of a window that is already set to stay on top. I am talking about getting a window to stay on top of a window that is not set to stay on top. – barlop Nov 14 '17 at 03:59
  • TopMost = true from the designer puts the form above an open NotePad application. @Steve already mentioned that to you. Why it doesn't work for you is a mystery to us. – LarsTech Nov 14 '17 at 14:58
  • @LarsTech almost everything you have written here has been either wrong or irrelevant or adds nothing to the discussion-for example,. You wrote "You can't. TopMost is only for your own form's collections" You were wrong and your latest comment contradicts what you wrote there as your latest comment says 'TopMost = true from the designer puts the form above an open NotePad application". Your link was irrelevant for the reason i've stated twice now. And you now stating that the solution to why it isn't working in my project is a mystery to you and others, adds nothing to the discussion. – barlop Nov 15 '17 at 02:43
  • @LarsTech also, steve did say " I have tried to create a simple topmost form using linqpad and at the first run I get your same behavior. " So it's not just me. Everything you are saying is wrong, or mischaracterising things, or irrelevant or adds nothing, or some combination. these comments will probably get deleted after the stupid conversation you provoke. And the valuable contributions of other people could be lost. – barlop Nov 15 '17 at 02:48
  • I will try https://support.microsoft.com/en-us/help/2587473/topmost-windows-are-not-always-in-the-topmost-position-in-windows-7-or though i'd be interested to know what method deskpins or mirc uses such that it's immune from this issue – barlop Nov 15 '17 at 22:50

1 Answers1

0

A workaround, is this, following on from Han's point to put not put it in Load. Load is indeed too early. I've been finding that (at least on the system with the issue), The Constructor is also too early. I find that putting it in the Shown event, works.

One possible solution to this, is to run this patch, https://support.microsoft.com/en-us/help/2587473/topmost-windows-are-not-always-in-the-topmost-position-in-windows-7-or But be warned, if you want to uninstall it, I have some doubts whether it uninstalls correctly. And it's also not clear to me whether the patch is working or working sporadically. It likely works but it's hard for me to tell.

One commenter thought it's just my system, though that's not the case, as Steve ran into the same issue the first time he ran it. I find it may be most prone to happen after windows restarts, So, the program is running very fresh. But I find that putting that code in the Shown event, is fine and the form stays on top.

I tried instead of TopMost=true, using SetWindowPos, to set the window on top, I tried it fairly early like in the constructor, and late, like in the Shown event or on a button click, and I found it was fine in the Shown event or on a button click. So the issue was related to the TopMost=true line, or SetWindowPos line, firing too early, prior to the window it is setting appearing.

When calling SetWindowPos later one can use either this.Handle or GetForegroundWindow(), the former is easier as it's native. When calling it earlier one must use this.Handle. And using this.TopMost=true avoids all winAPI calls completely.

So in short, you could try the patch, though note that it might not uninstall right.. Or you can try the workaround of putting this.TopMost=true in the Shown event of the form.

barlop
  • 12,887
  • 8
  • 80
  • 109