How can I update a WinForm without stealing focus?

G

Guest

How can I update a WinForm without stealing focus?

I have a main form which has a Timer to perform updates (query data and
display it on the form). (Yes, it uses Invoke.) I also have menu items that
can display dialogs to set various things.

The problem is that when I have a dialog open and the timer updates the main
form, the main form steals the focus from the dialog.

As a work-around I have the app stop the updates while a dialog is open, but
I'd prefer to be able to have the updates occur without the focus being
stolen from the dialog.
 
K

Kevin Spencer

Are you using ShowDialog to display the dialog? This creates a modal dialog.

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Chicken Salad Alchemist

I recycle.
I send everything back to the planet it came from.
 
K

Kevin Spencer

Can you give some more details about the "dialog" you're showing and how?
The more information you provide, the more likely you are to get a solution
in less than 6 months!

-
HTH,

Kevin Spencer
Microsoft MVP
Professional Chicken Salad Alchemist

I recycle.
I send everything back to the planet it came from.
 
G

Guest

Can you give some more details about the "dialog" you're showing and how?

I don't see as that matters. When the user clicks on the menu item, its
event handler instantiates the appropriate form and calls the ShowDialog()
method.

(Currently it first set a boolean to tell the timer's elapsed handler not to
do its thing.)

When the ShowDialog() method returns, the menu click event handler takes
whatever action is needed.

(And tells the timer's elapsed handler to behave as normal.)

The concern is that I want the timer's elapsed handler to continue behaving
normally even while the "dialog" is shown, but not allow the main form to
"steal" the focus away from the "dialog".

It's a System.Timers.Timer

It's got to be caused by the updates that get done, I'll try to narrow it
down.
 
G

Guest

OK, I've got it behaving as expected now. It was, of course, my fault.
But it raises another question.

The problem was that I was setting the main form's TopMost property. The
goal was to have the form "pop up" to the top when new data was displayed
(but not otherwise).

The rhetorical question now is: why does the form steal the focus and/or
"pop up" when I set its TopMost property to false? I expect that to happen
when I set it to true, but why does false seem to have the same effect?
 
K

Kevin Spencer

You should have no trouble with the timer if your dialog form is working as
it should. The timer runs in its own thread, and should do whatever it's
doing without any trouble from the dialog form. By "working as it should," I
mean that the form should be invoked using ShowDialog, and return by setting
its DialogResult property.

That said, I'm not sure how using a System.Timers.Timer instance might
affect the operation. The recommended timer to use in a Windows Form is a
System.Windows.Forms.Timer class, which is a Component designed to work in a
single-threaded environment. I couldn't say for sure because I haven't used
a server Timer in a Windows Form. Would it be possible to use that type
instead? It might be worth a try.

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Chicken Salad Alchemist

I recycle.
I send everything back to the planet it came from.
 
K

Kevin Spencer

That could certainly be the problem Setting the TopMost property to true
will certainly place the Form on the top of the z-order of all windows on
the desktop, even if it is not the active or foreground form. If you want to
set it to TopMost, you could do it after the modal dialog returns. As to why
it steals the focus when you set it to false, I can't say. But perhaps you
should call the Activate method instead of setting the TopMost property. The
Activate method will bring the Form to the front of the z-order if it is the
Active Window, but only flash the window caption in the Task Bar if it is
not the Active Form. This can be overruled, but you might want to be sure
you want to do it. I believe you would have to use a WinAPI function to do
this, either SetForegroundWindow or SetActiveWindow (I believe it would be
SetForegroundWindow). See:

http://msdn.microsoft.com/library/d...rence/windowfunctions/setforegroundwindow.asp

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Chicken Salad Alchemist

I recycle.
I send everything back to the planet it came from.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top