Re: timer not being called when OnPaint calls Invalidate
- From: "Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx>
- Date: Mon, 27 Nov 2006 18:06:18 -0800
"grayaii" <grayaii@xxxxxxxxx> wrote in message
news:1164678497.496520.123790@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[...]
I have my onpaint function call Invalidate at the very end like so:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
// Draw everything...
this.Invalidate()
}
Let me make sure I understand what you are saying:
In your overridden "OnPaint" handler, which is called in response to a paint
event, which occurs any time an area of the control (form) is invalidated,
you invalidate the entire control (form)?
Seems to me you've got a pretty classic infinite loop there.
The problem is that I want to setup a System.Windows.Forms.Timer when I
click the a certain key for instance. When I hit the key, I create a
timer successfully, but the timer's event never gets called after I
start the timer.. It seems the "this.Invalidate" within OnPaint does
not give the form the opportunity to call the tick-event of the timer.
Sure, I can believe that. If you fill your message queue with paint events,
I can see how you might never get to a point where you can pull out the
timer event.
I believe the problem (and ultimately the solution) lies in the fact
that the form is a single-threaded application. In my own ignorance, I
thought that when you create a timer it creates a new thread,
independent of the message loop of the application, but apparently not.
Not using the Forms.Timer method of creating a timer, no. All that does is
use the usual Windows WM_TIMER mechanism, which relies on being able to get
a WM_TIMER message from the window's message queue.
If you want a timer that operates independently of the message queue, you
should probably use something like Threading.Timer instead. That will use a
different thread to handle the timer. Of course, if your timer code has to
interact with the window, you will wind up having to use Invoke or
BeginInvoke, which introduces a dependency on the message queue again.
Otherwise, it should be fine though.
IMHO, however, you should rethink the wisdom of calling Invalidate from
within your OnPaint handler. This is very bad form. Generally speaking,
you should only ever call Invalidate when there has actually been some
change in the data being drawn. It makes no sense to call Invalidate when
what you've just done is to have redrawn the control. Nothing about drawing
the control should be changing the way it should draw next time, and so
there should be no reason to call Invalidate from within the OnPaint
handler.
[...]
I'm soooo close to the solution that I can almost taste it, but I'm
stuck. The words, "Multithreaded app" screams at me.
You may or may not need to introduce a new thread into your program. That
depends on exactly what you're trying to do. However, personally I would
first attempt to solve your problem simply by removing the Invalidate from
the OnPaint handler. If your timer does something that requires the control
(form) to be redrawn, then call Invalidate there (assuming you have to...in
most simple cases, a form contains only controls that already know to
invalidate themselves if their data changes...simply setting the control's
data is enough).
Pete
.
- Follow-Ups:
- Re: timer not being called when OnPaint calls Invalidate
- From: grayaii
- Re: timer not being called when OnPaint calls Invalidate
- References:
- timer not being called when OnPaint calls Invalidate
- From: grayaii
- timer not being called when OnPaint calls Invalidate
- Prev by Date: Re: timer not being called when OnPaint calls Invalidate
- Next by Date: Re: Hiding a virtual method
- Previous by thread: Re: timer not being called when OnPaint calls Invalidate
- Next by thread: Re: timer not being called when OnPaint calls Invalidate
- Index(es):
Relevant Pages
|