Paint event

F

Frank Rizzo

I am creating a User Control that does a lot of it own painting from the
UserControl_Paint event mostly using the e.Graphics object that's
passed into Paint event. It works pretty good.

Occasionally, the paint event doesn't fire. This occurs mostly in apps
with many 3rd party controls when the user presses Alt key the first
time. The problem doesn't occur after the 1st key press. I can't seem
to nail down where the problem is coming from.

Any and all ideas are welcome, as I am at the end of the rope.

Thanks.
 
M

Michael C

Frank Rizzo said:
I am creating a User Control that does a lot of it own painting from the
UserControl_Paint event mostly using the e.Graphics object that's passed
into Paint event. It works pretty good.

Occasionally, the paint event doesn't fire. This occurs mostly in apps
with many 3rd party controls when the user presses Alt key the first time.
The problem doesn't occur after the 1st key press. I can't seem to nail
down where the problem is coming from.

Any and all ideas are welcome, as I am at the end of the rope.

Try the onpaint override instead.

Michael
 
M

Michael C

Frank Rizzo said:
Tried it. Same thing happened.

Do you do a this.Validate() anywhere in the paint? Can you post a simplified
sample that demonstrates the problem?
 
F

Frank Rizzo

Michael C wrote:

"Frank Rizzo" <[email protected]> wrote in message news:[email protected]...



Try the onpaint override instead.



Tried it. Same thing happened.



Do you do a this.Validate() anywhere in the paint? Can you post a simplified sample that demonstrates the problem?

Here is the sample.  All this is inside of a user control.  The control is inside another control which is inside a form.
The user presses Alt and then for about a second whatever I painted disappears and then reappears again (because the OnPaint event fired).


        private static Font _TextFont = new Font("Tahoma", 11f, FontStyle.Bold);
        private static Brush _TextBrush = new SolidBrush(SystemColors.Window);
        private static PointF _TextPoint = new PointF(6f, 2f);

        protected override void OnPaint(PaintEventArgs e)
        {
            PaintControlGradient(e);
        }

        private void PaintControlGradient(PaintEventArgs e)
        {
            Color GradientBegin = Color.White;
            Color GradientEnd = Color.Black;

            Rectangle rect = new Rectangle(new Point(0, 0), this.Size);
            LinearGradientBrush gradientBrush = new LinearGradientBrush(rect, GradientBegin, GradientEnd, 90f);

            e.Graphics.FillRectangle(gradientBrush, rect);
            e.Graphics.DrawString("Yeah", _TextFont, _TextBrush, _TextPoint);
        }
 
W

WRH

Maybe put an Invalidate in the control's OnLoad method?

Michael C wrote:
Try the onpaint override instead.
Tried it. Same thing happened.

Do you do a this.Validate() anywhere in the paint? Can you post a simplified
sample that demonstrates the problem?
Here is the sample. All this is inside of a user control. The control is inside another control which is inside a form.
The user presses Alt and then for about a second whatever I painted disappears and then reappears again (because the OnPaint event fired).


private static Font _TextFont = new Font("Tahoma", 11f, FontStyle.Bold);
private static Brush _TextBrush = new SolidBrush(SystemColors.Window);
private static PointF _TextPoint = new PointF(6f, 2f);

protected override void OnPaint(PaintEventArgs e)
{
PaintControlGradient(e);
}

private void PaintControlGradient(PaintEventArgs e)
{
Color GradientBegin = Color.White;
Color GradientEnd = Color.Black;

Rectangle rect = new Rectangle(new Point(0, 0), this.Size);
LinearGradientBrush gradientBrush = new LinearGradientBrush(rect, GradientBegin, GradientEnd, 90f);

e.Graphics.FillRectangle(gradientBrush, rect);
e.Graphics.DrawString("Yeah", _TextFont, _TextBrush, _TextPoint);
}
 
M

Michael C

Frank Rizzo said:
Here is the sample. All this is inside of a user control. The control is
inside another control which is inside a form.
The user presses Alt and then for about a second whatever I painted
disappears and then reappears again (because the
OnPaint event fired).

I can't reproduce the problem. I tried a UC in a UC in a form and even added
a menu because I presumed you had a menu. It all worked perfect on my
machine.

BTW, did you know this can be replaced

private static Brush _TextBrush = new SolidBrush(SystemColors.Window);

with

private static Brush _TextBrush = SystemBrushes.Window;
or Brushes.White if you just want white.

It has the added advantage that it doesn't need to be disposed.

Michael
 
F

Frank Rizzo

Michael said:
I can't reproduce the problem. I tried a UC in a UC in a form and even added
a menu because I presumed you had a menu. It all worked perfect on my
machine.

I can't repro the problem in my test app either. But it sure happens in
the main app. Maybe I'll make a small video and post it here, so you
can see what's going on.
BTW, did you know this can be replaced

private static Brush _TextBrush = new SolidBrush(SystemColors.Window);

with

private static Brush _TextBrush = SystemBrushes.Window;

Oh, thanks. I actually looked for that and couldn't find it. I'll have
to talk to my intellisense. I do see it now.
 
F

Frank Rizzo

In case anyone is interested, I solved the issue by turning
DoubleBuffered property to True on the control. Somehow magically, the
problem went away.

Yeah.
 
M

Michael C

Frank Rizzo said:
In case anyone is interested, I solved the issue by turning DoubleBuffered
property to True on the control. Somehow magically, the problem went
away.

That's not really a solution. This will use large amounts of memory as the
control will create a bitmap the size of the control. It will also slow your
paint speed down potentially to half I believe, which is a problem as
painting in dot net is slow enough as it is :)

Michael
 
F

Frank Rizzo

Michael said:
That's not really a solution. This will use large amounts of memory as the
control will create a bitmap the size of the control. It will also slow your
paint speed down potentially to half I believe, which is a problem as
painting in dot net is slow enough as it is :)

Actually, it sped the living hell out of it (or at least perceived
speed). And got rid of my problem. I'll still make a video out of the
old method.
 
M

Michael C

Frank Rizzo said:
Actually, it sped the living hell out of it (or at least perceived speed).

It does make it look a lot quicker but I don't think it will actually be
quicker. It has to paint to the buffer and then paint the buffer to the
control. I'm trying to get something similar working at the moment and I
tried with and without double buffer and found it to be slower.
And got rid of my problem.

Is it possible that some code was executing during the time when it was
unpainted that was causing the paint event to not be called?

Michael
 
F

Frank Rizzo

Michael said:
It does make it look a lot quicker but I don't think it will actually be
quicker. It has to paint to the buffer and then paint the buffer to the
control. I'm trying to get something similar working at the moment and I
tried with and without double buffer and found it to be slower.

Is it possible that some code was executing during the time when it was
unpainted that was causing the paint event to not be called?

Doubtful, the user control has its own window handle, so it would
process its own events. Besides the problem is reproducible 100% by
just pressing Alt. Perhaps other controls on the forms respond to it as
well causing the slowdown.
 
M

Michael C

Frank Rizzo said:
Doubtful, the user control has its own window handle, so it would process
its own events.

The application has only one message loop and won't process any of the
messages in the loop while the app is using 100% cpu in the main thread. A
WM_PAINT message could be sitting in the loop and will be ignored until the
app becomes idle. You can test this by doing a sleep(30000) and dragging a
windows over your app, nothing will get repainted. WinXP does do some tricks
to make it loop like the app is painting itself but it's actually XP doing
the painting.
Besides the problem is reproducible 100% by just pressing Alt. Perhaps
other controls on the forms respond to it as well causing the slowdown.

Although I agree it is likely the 100% cpu isn't the cause, it could be the
WM_PAINT message being dropped in certain circumstances.

Michael
 

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