none
repainting child controls

    Question

  • I have created a container user control that repaints it's background so that it gives bevel look. I used that control in forms. i placed other controls such as panel in that user control. When i resize the form at runtime the user control resizes itself which fires paint event. In paint event i have filled the rectangle equivalent to the usercontrol boundary and repainted it with white color. Then I redo the whole operation of painting it so that it gives bevel look. But the problem is when i resize the form it is able to paint itself but not it's child controls. That's why junk graphics are seen on the screen. I can clearly tell that the panel control in the user control is not being painted. How do i make the child controls to invalidate when the parent user control is repainting itself.
    Sunday, December 27, 2009 3:49 PM

Answers

  • Hi Ishwor,

    I'm not sure what kind of junk graphics you see on screen, and what does it mean that the panel is not being repainted.

    Please try to add this line, if you haven't already
    SetStyle(ControlStyles.ResizeRedraw, true);

    to your control's constructor after the call to InitializeComponent().

    If it does not fix your problem please post the full code of your control so that I can reproduce the behavior you are describing.
    Or tell us at least what values do you use for all those fields in your OnPaint method.
    Are you inheriting from ContainerControl ?
    Also are you anchoring your control on the form or docking it; the same question goes for the panel inside your control.

    And, at the end, from what I can see in your code, you are doing some pointless paining.
    So instead of lines marked here with 1. 2. and 3. 

    			graphic.Clear(this.BackColor); // 1.
    			graphic.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 0, this.Width, this.Height)); // 2.
    			// ...
    
    			SolidBrush brBack = new SolidBrush(_backColor); // 3.
    			Rectangle rctBack = new Rectangle(0, 0, this.Width, this.Height); // 3.
    			graphic.FillRectangle(brBack, rctBack); // 3.
    

    just call 

    graphics.Clear(_backColor);

    since the last line in the code above will cancel the lines 1. and 2. (which do the same thing anyway).

    Also, add a try { } block to your method and move Dispose statements in the finally {} block so that they are called even if something goes wrong.
    And finally, I presumed that the code you posted is in the overriden OnPaint method, right ?

    Best regards, 
    Vladimir




    • Marked as answer by Ishwor Mali Sunday, January 3, 2010 6:24 AM
    Friday, January 1, 2010 5:59 PM

All replies

  • Hi,

    Show as the code you use to paint your control.
    Regards,
    Danijel

    Blog, Twitter
    Monday, December 28, 2009 12:23 PM
  • 	Graphics graphic = e.Graphics;
                graphic.Clear(this.BackColor);
                graphic.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0,0,this.Width,this.Height));
                //this.Refresh();       dangerous 
               
                this.SuspendLayout();
                //graphic.DrawRectangle(new Pen(Color.AliceBlue,2),new Rectangle(1,1,this.Width-5,this.Height-5));
                Pen lPenBorder = new Pen(Color.White);
                Pen rPenBorder = new Pen(Color.FromArgb(130, 130, 130));
                SolidBrush brInterior = new SolidBrush(_interiorColor);
                SolidBrush brBack = new SolidBrush(_backColor);
                Rectangle rctBack=new Rectangle(0,0,this.Width,this.Height);
                graphic.FillRectangle(brBack, rctBack);
                graphic.DrawLine(lPenBorder, 0, 0, this.Width - _borderWidth, 0);
                graphic.DrawLine(lPenBorder, 0, 0, 0, this.Height-_borderWidth);
                graphic.DrawLine(rPenBorder, this.Width-_borderWidth, 0,this.Width-_borderWidth,this.Height-_borderWidth);
                graphic.DrawLine(rPenBorder, 0,this.Height-_borderWidth,this.Width-_borderWidth,this.Height-_borderWidth);
                
                Rectangle rctInterior = new Rectangle(_interiorSpaceLeft, _interiorSpaceTop, this.Width - _interiorSpaceRight-_interiorSpaceLeft, this.Height - _interiorSpaceBottom-_interiorSpaceTop);
                
                //graphic.FillRectangle(brInterior, new Rectangle(rctInterior.X + 2, rctInterior.Y + 2, rctInterior.Width - 2, rctInterior.Height - 2));
                graphic.FillRectangle(brInterior,rctInterior);
                if(_interiorBorderWidth>0)
                    graphic.DrawRectangle(new Pen(_interiorBorderColor,_interiorBorderWidth), rctInterior);
    
                if (_caption != "")
                {
                    graphic.DrawString(_caption, this.Font, new SolidBrush(this.ForeColor), _captionPoint);
                    graphic.DrawLine(new Pen(Color.Black), new Point(1, this.Font.Height+5), new Point(this.Width - 3, this.Font.Height+5));
                }
                lPenBorder.Dispose();
                rPenBorder.Dispose();
                brInterior.Dispose();
                brBack.Dispose();
                
                this.ResumeLayout();


    Monday, December 28, 2009 1:28 PM
  • Hi Ishwor,

    Do not call SuspendLayout and ResumeLayout in your code. Paint has nothing to do with layout logic.

    To understand why these methods are used to, please read the following documentation:
    http://msdn.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx

    Don't forget to set control styles as well:
    SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    SetStyle(ControlStyles.DoubleBuffer, true);
    SetStyle(ControlStyles.UserPaint, true);
    Hope it helps

    Regards,
    Danijel

    Blog, Twitter
    Monday, December 28, 2009 4:09 PM
  • it is not helping. I tried your way.
    When I minimize the form and open it again it is repainted fine. I think i need to send some kind of messages to some child controls or parent control as form does when i minimize and maximize so that it is repainted correctly. Am I right?
    I think so. But how do i do that?
    Tuesday, December 29, 2009 1:11 PM
  • Hi Ishwor,

    I'm not sure what kind of junk graphics you see on screen, and what does it mean that the panel is not being repainted.

    Please try to add this line, if you haven't already
    SetStyle(ControlStyles.ResizeRedraw, true);

    to your control's constructor after the call to InitializeComponent().

    If it does not fix your problem please post the full code of your control so that I can reproduce the behavior you are describing.
    Or tell us at least what values do you use for all those fields in your OnPaint method.
    Are you inheriting from ContainerControl ?
    Also are you anchoring your control on the form or docking it; the same question goes for the panel inside your control.

    And, at the end, from what I can see in your code, you are doing some pointless paining.
    So instead of lines marked here with 1. 2. and 3. 

    			graphic.Clear(this.BackColor); // 1.
    			graphic.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 0, this.Width, this.Height)); // 2.
    			// ...
    
    			SolidBrush brBack = new SolidBrush(_backColor); // 3.
    			Rectangle rctBack = new Rectangle(0, 0, this.Width, this.Height); // 3.
    			graphic.FillRectangle(brBack, rctBack); // 3.
    

    just call 

    graphics.Clear(_backColor);

    since the last line in the code above will cancel the lines 1. and 2. (which do the same thing anyway).

    Also, add a try { } block to your method and move Dispose statements in the finally {} block so that they are called even if something goes wrong.
    And finally, I presumed that the code you posted is in the overriden OnPaint method, right ?

    Best regards, 
    Vladimir




    • Marked as answer by Ishwor Mali Sunday, January 3, 2010 6:24 AM
    Friday, January 1, 2010 5:59 PM
  • Finally it is resolved. I simply overrided the onPaint method. Called the base.onPaint() method first to let base control do it's work like cleaning up, then put my code to repaint the control. 

    Thanx to all of you for taking time to resolve my queries.

    And Vladimir I think that Paint event may work if I put this code SetStyle(ControlStyles.ResizeRedraw, true);
    right? I will give it a try.

    Sunday, January 3, 2010 6:23 AM