TopMost isnt working for me
-
I have a program that I have written that uses its main form to show buttons which show the status of devices. These button have their own class (inherting the button class) and are run as their own threads and can update themselves as required. What I want to do, is to make the form become the TopMost window when one of the buttons indicates an error condition. I can make the button threads modify a master variable of the form, and that works. But when I then also try to make the form TopMost (TopMost=True) (actioned by a button thread) is does not get remembered. E.G if a button thread calls the main forms subroutine :- Public Sub attention() SyncLock myObjLock If need_attention = False Then need_attention = True TopMost = True End If End SyncLock End Sub need_attention gets updated to False but TopMost never happens. If I call this from the main form routines it seems to work, just not when a thread calls the routine. I'm not sure if I'm missing something simple, hopefully I am. Please help Thanks Nigel
-
I have a program that I have written that uses its main form to show buttons which show the status of devices. These button have their own class (inherting the button class) and are run as their own threads and can update themselves as required. What I want to do, is to make the form become the TopMost window when one of the buttons indicates an error condition. I can make the button threads modify a master variable of the form, and that works. But when I then also try to make the form TopMost (TopMost=True) (actioned by a button thread) is does not get remembered. E.G if a button thread calls the main forms subroutine :- Public Sub attention() SyncLock myObjLock If need_attention = False Then need_attention = True TopMost = True End If End SyncLock End Sub need_attention gets updated to False but TopMost never happens. If I call this from the main form routines it seems to work, just not when a thread calls the routine. I'm not sure if I'm missing something simple, hopefully I am. Please help Thanks Nigel
Have you set a breakpoint to make sure the TopMost call occurs ?
Christian Graus - Microsoft MVP - C++ "I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
-
I have a program that I have written that uses its main form to show buttons which show the status of devices. These button have their own class (inherting the button class) and are run as their own threads and can update themselves as required. What I want to do, is to make the form become the TopMost window when one of the buttons indicates an error condition. I can make the button threads modify a master variable of the form, and that works. But when I then also try to make the form TopMost (TopMost=True) (actioned by a button thread) is does not get remembered. E.G if a button thread calls the main forms subroutine :- Public Sub attention() SyncLock myObjLock If need_attention = False Then need_attention = True TopMost = True End If End SyncLock End Sub need_attention gets updated to False but TopMost never happens. If I call this from the main form routines it seems to work, just not when a thread calls the routine. I'm not sure if I'm missing something simple, hopefully I am. Please help Thanks Nigel
try to use mdiparent
-
I have a program that I have written that uses its main form to show buttons which show the status of devices. These button have their own class (inherting the button class) and are run as their own threads and can update themselves as required. What I want to do, is to make the form become the TopMost window when one of the buttons indicates an error condition. I can make the button threads modify a master variable of the form, and that works. But when I then also try to make the form TopMost (TopMost=True) (actioned by a button thread) is does not get remembered. E.G if a button thread calls the main forms subroutine :- Public Sub attention() SyncLock myObjLock If need_attention = False Then need_attention = True TopMost = True End If End SyncLock End Sub need_attention gets updated to False but TopMost never happens. If I call this from the main form routines it seems to work, just not when a thread calls the routine. I'm not sure if I'm missing something simple, hopefully I am. Please help Thanks Nigel
uk_nbb wrote:
and are run as their own threads
I am not sure what you are saying here, are you having some other thread create and handle a Button ? All Controls require they be touched only by the thread that created them, which in practice means everything gets created and touched by the main thread (aka GUI thread only), since thats where your first Form gets created, and normally everything in one way or another connects to it. There are a few properties/methods that dont have to obey this rule; mainly InvokeRequired and Invoke() and its exactly these that you must use to let another thread do something to a Control it did not create. If you dont follow the rules here, on old .NET (prior to 2.0) it may or may not work, typically it will suddenly ignore you or freeze, show a white menu bar, things like that. Since 2.0 it will throw an InvalidOperationException except when you have set CheckForIllegalCrossThreadCalls=false, which is considered bad practice and brings you back to the 1.x behavior. Hope this helps. :)
Luc Pattyn [My Articles] [Forum Guidelines]
-
Have you set a breakpoint to make sure the TopMost call occurs ?
Christian Graus - Microsoft MVP - C++ "I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
The TopMost call gets called and is set to true. But when I set a breakpoint further on when something else happens and I look at the TopMost value, it is False and so the setting is never held. I never set it back to False so it can't be holding its value (well its not being set properly I guess). Its confusing !!! Nigel
-
uk_nbb wrote:
and are run as their own threads
I am not sure what you are saying here, are you having some other thread create and handle a Button ? All Controls require they be touched only by the thread that created them, which in practice means everything gets created and touched by the main thread (aka GUI thread only), since thats where your first Form gets created, and normally everything in one way or another connects to it. There are a few properties/methods that dont have to obey this rule; mainly InvokeRequired and Invoke() and its exactly these that you must use to let another thread do something to a Control it did not create. If you dont follow the rules here, on old .NET (prior to 2.0) it may or may not work, typically it will suddenly ignore you or freeze, show a white menu bar, things like that. Since 2.0 it will throw an InvalidOperationException except when you have set CheckForIllegalCrossThreadCalls=false, which is considered bad practice and brings you back to the 1.x behavior. Hope this helps. :)
Luc Pattyn [My Articles] [Forum Guidelines]
-
The TopMost call gets called and is set to true. But when I set a breakpoint further on when something else happens and I look at the TopMost value, it is False and so the setting is never held. I never set it back to False so it can't be holding its value (well its not being set properly I guess). Its confusing !!! Nigel
Well, it works and it sticks. The only three things that can change that are: 1: You change it back to False. 2: You create a new instance of your form somewhere along the way and assign it to the same variable, thus giving the appearance that it didn't stick. 3: Some other form set TopMost to True somewhere else in your app.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007