views:

464

answers:

2

My application pops a form as a child of the main form. On the form is
User Control with a Panel where Graphics are rendered. When executed from Visual Studio in debug mode the drawing is often rendered as expected, imagine a simply XY graph. If the panel's graphic aren't drawn then adding two or three break points to the drawing routines usually fix the problem.

When executed inside Visual Studio in release mode, or from the.exe in any mode, the graphics are never rendered, although the user control's Paint method is called. Resizing the form cause the repaint to be called again, of course, and the image is now rendered correctly.

Can anyone give me some insight as to why there's a difference in the behavior between Debug and Release modes, from execution within VS and out side VS, any why are the break points sometimes fixing things? And how can I get the graphics to be consistently visible.

Thanks,

Rick

+1  A: 

Without more information I can't say for sure why you are seeing the difference in behavior (I would suggest you are seeing the same problem since you admit that the debug version doesn't always work either), but you may find that breakpoints will often "fix" paint problems because switching back to Visual Studio ends up invalidating the entire painting surface, as opposed to just a small part. So you bring up the application and its not painting correctly, you hit a breakpoint in visual studio, switch over look at some variables, go back to the application and its painted correctly because OnPaint was called with the proper clipping rectangle to repaint the entire surface (and OnPaintBackground is also usually called, see below).

If this is the case, you should be able to replicate it in the release version by minimizing and restoring your application. If that "fixes" the display of your control, then it is likely caused by a problem with your paint method assuming that it is painting the entire control when it may not be.

You might also look into PaintBackground to make sure that you are erasing your control's surface properly. It is possibly that you are leaving your old display and then repainting on top of it instead of starting from a "fresh" canvas.

Based on your description of what is going on, and the ways that you make it redraw, those are my best suggestions. I would need some more specific details (Paint code, specific description of what happens - is the control not drawn or does it display only parts, etc.) to provide any more accurate help.

Brian B.
+1  A: 

I just gave this a whirl and it did what I expected in release mode. . . it fills the panel with the color Blue and a big yellow ellipse. Please post the minimum amount of example code that is required to reproduce the problem. . . perhaps building off of MyPanel below.

The role of the timer is to ensure we're not redrawing too often. It's a self-terminating timer which forces a repaint of the whole control. This is needed because the custom drawn content sizes with the control.

   public class MyPanel : Panel
    {
        Timer _resizeRedrawDelayTimer = new Timer();
        public MyPanel()
        {
            _resizeRedrawDelayTimer.Interval=50;
            _resizeRedrawDelayTimer.Tick += new EventHandler(_resizeRedrawDelayTimer_Tick);
        }

        void _resizeRedrawDelayTimer_Tick(object sender, EventArgs e)
        {
            Invalidate();
            _resizeRedrawDelayTimer.Stop();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            // don't redraw if still resizing.
            if (!_resizeRedrawDelayTimer.Enabled)
            {
                e.Graphics.FillRectangle(Brushes.Blue, this.ClientRectangle);
                e.Graphics.FillEllipse(Brushes.Yellow, this.ClientRectangle);
            }
            base.OnPaint(e);
        }

        protected override void OnResize(EventArgs eventargs)
        {
            if (_resizeRedrawDelayTimer.Enabled)
                _resizeRedrawDelayTimer.Stop();
            // restart the timer.
            _resizeRedrawDelayTimer.Start();
            base.OnResize(eventargs);
        }
    }
Jason D