Scrollbar still is painted after it should be removed

Posted by Walter Williams on Stack Overflow See other posts from Stack Overflow or by Walter Williams
Published on 2009-03-10T22:17:51Z Indexed on 2010/03/19 0:01 UTC
Read the original article Hit count: 282

Filed under:
|
|
|

I have the following custom control and can place on a form (with AutoScroll set to true and the control anchored left, top and right).

If the form is too short for the control, the form correctly resizes the control (to make room for the scroll) and displays the scroll bar.

When the control is closed using the close glyph, the control is resized and the scroll bar is removed, but occasionally the scroll bar appears to remain painted. If the form is minimized or moved off-screen, the leftover paint is removed.

I've tried Parent.Invalidate and have toyed with it in many ways but to no avail. Any suggestions?

(Using VS 2008 Standard)

alt text

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;



namespace GroupPanelTest
{
    public class GroupPanel : GroupBox
    {
    	#region Members
    	private const Int32 iHeaderHeight = 20;
    	private Int32 iFullHeight = 200;

    	private Boolean bClosed = false;
    	private Rectangle rectCloseGlyphBounds = Rectangle.Empty;
    	private Boolean bIsMoveOverCloseGlyph = false;
    	#endregion

    	#region Properties
    	[DefaultValue(false)]
    	public Boolean Closed
    	{
    		get
    		{
    			return (this.bClosed);
    		}
    		set
    		{
    			if (this.bClosed != value)
    			{
    				this.bClosed = value;
    				if (this.bClosed)
    				{
    					this.iFullHeight = base.Height;
    					base.Height = GroupPanel.iHeaderHeight;
    				}
    				else
    				{
    					base.Height = this.iFullHeight;
    				}

    				foreach (Control con in base.Controls)
    					con.Visible = !this.bClosed;

    				this.Invalidate();
    			}
    		}
    	}

    	public new Int32 Height
    	{
    		get
    		{
    			return (base.Height);
    		}
    		set
    		{
    			if (value != base.Height)
    			{
    				if (this.Closed)
    				{
    					this.iFullHeight = value;
    				}
    				else
    				{
    					Int32 iOldHeight = base.Height;
    					base.Height = value;
    				}
    			}
    		}
    	}

    	[DefaultValue(typeof(Size), "350,200")]
    	public new Size Size
    	{
    		get
    		{
    			return (base.Size);
    		}
    		set
    		{
    			if (base.Size != value)
    			{
    				base.Size = value;
    				if (!this.Closed)
    					this.iFullHeight = value.Height;
    			}
    		}
    	}

    	[DefaultValue(typeof(Padding), "0,7,0,0")]
    	public new Padding Padding
    	{
    		get
    		{
    			return (base.Padding);
    		}
    		set
    		{
    			base.Padding = value;
    		}
    	}
    	#endregion

    	#region Construction
    	public GroupPanel ()
    	{
    		SetStyle(ControlStyles.UserPaint, true);
    		SetStyle(ControlStyles.ResizeRedraw, true);
    		SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    		SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    		SetStyle(ControlStyles.Selectable, true);

    		this.Size = new Size(350, 200);
    		this.Padding = new Padding(0, 7, 0, 0); // the groupbox will add to that
    		this.rectCloseGlyphBounds = new Rectangle(base.ClientSize.Width - 24, 2, 16, 16);
    	}
    	#endregion

    	#region Overrides
    	protected override void OnSizeChanged (EventArgs e)
    	{
    		this.rectCloseGlyphBounds = new Rectangle(base.ClientSize.Width - 24, 2, 16, 16);
    		base.OnSizeChanged(e);
    	}

    	protected override void OnPaint (PaintEventArgs e)
    	{
    		base.OnPaint(e); // we want all the delegates to receive the events, but we do this first so we can paint over it

    		Graphics g = e.Graphics;

    		g.FillRectangle(SystemBrushes.Window, this.ClientRectangle);
    		Rectangle rectTitle = new Rectangle(0, 0, this.ClientRectangle.Width, GroupPanel.iHeaderHeight);
    		g.FillRectangle(SystemBrushes.Control, rectTitle);
    		g.DrawString(this.Text, this.Font, SystemBrushes.ControlText, new PointF(5.0f, 3.0f));

    		if (this.bIsMoveOverCloseGlyph)
    		{
    			g.FillRectangle(SystemBrushes.ButtonHighlight, this.rectCloseGlyphBounds);
    			Rectangle rectBorder = this.rectCloseGlyphBounds;
    			rectBorder.Inflate(-1, -1);
    			g.DrawRectangle(SystemPens.Highlight, rectBorder);
    		}

    		using (Pen pen = new Pen(SystemColors.ControlText, 1.6f))
    		{
    			if (this.Closed)
    			{
    				g.DrawLine(pen, this.rectCloseGlyphBounds.Left + 3, this.rectCloseGlyphBounds.Top + 3, this.rectCloseGlyphBounds.Left + 8, this.rectCloseGlyphBounds.Top + 8);
    				g.DrawLine(pen, this.rectCloseGlyphBounds.Left + 13, this.rectCloseGlyphBounds.Top + 3, this.rectCloseGlyphBounds.Left + 8, this.rectCloseGlyphBounds.Top + 8);

    				g.DrawLine(pen, this.rectCloseGlyphBounds.Left + 3, this.rectCloseGlyphBounds.Top + 7, this.rectCloseGlyphBounds.Left + 8, this.rectCloseGlyphBounds.Top + 12);
    				g.DrawLine(pen, this.rectCloseGlyphBounds.Left + 13, this.rectCloseGlyphBounds.Top + 7, this.rectCloseGlyphBounds.Left + 8, this.rectCloseGlyphBounds.Top + 12);
    			}
    			else
    			{
    				g.DrawLine(pen, this.rectCloseGlyphBounds.Left + 3, this.rectCloseGlyphBounds.Top + 8, this.rectCloseGlyphBounds.Left + 8, this.rectCloseGlyphBounds.Top + 3);
    				g.DrawLine(pen, this.rectCloseGlyphBounds.Left + 13, this.rectCloseGlyphBounds.Top + 8, this.rectCloseGlyphBounds.Left + 8, this.rectCloseGlyphBounds.Top + 3);

    				g.DrawLine(pen, this.rectCloseGlyphBounds.Left + 3, this.rectCloseGlyphBounds.Top + 12, this.rectCloseGlyphBounds.Left + 8, this.rectCloseGlyphBounds.Top + 7);
    				g.DrawLine(pen, this.rectCloseGlyphBounds.Left + 13, this.rectCloseGlyphBounds.Top + 12, this.rectCloseGlyphBounds.Left + 8, this.rectCloseGlyphBounds.Top + 7);
    			}
    		}
    	}

    	protected override void OnMouseDown (MouseEventArgs e)
    	{
    		if (e.Button == MouseButtons.Left && this.rectCloseGlyphBounds.Contains(e.Location))
    			this.Closed = !this.Closed; // close will call invalidate
    		base.OnMouseDown(e);
    	}

    	protected override void OnMouseMove (MouseEventArgs e)
    	{
    		this.bIsMoveOverCloseGlyph = this.rectCloseGlyphBounds.Contains(e.Location);
    		this.Invalidate(this.rectCloseGlyphBounds);
    		base.OnMouseMove(e);
    	}
    	#endregion
    }
}

© Stack Overflow or respective owner

Related posts about winforms

Related posts about c#