Question

I've written the following (very simple) control for use in an application (comments removed for brevity):

public partial class HorizontalRule : Control
{
    public HorizontalRule()
    {
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        var g = e.Graphics;

        var rect = new Rectangle(
            this.ClientRectangle.Left,
            this.ClientRectangle.Height / 2 + 1, 
            this.ClientRectangle.Width,
            1);

        ControlPaint.DrawBorder3D(g, rect, Border3DStyle.Etched);

        return;
    }
}

Disclaimer: I'm a newbie at painting my own controls.

I chose to draw the line this way based on the recommendation in the Vista UX guidelines that suggests an etched rectangle of height 1 for separators.

When static, this looks fine, but I've noticed that I get redrawing artifacts if I place this control in a window and resize it (via anchor, e.g.). I'm redrawing my border over my entire client rectangle's width, but it's like it isn't actually being painted. Enabling DoubleBuffered in HorizontalRule's constructor, or in the form that it's embedded in, doesn't seem to make a difference either.

What am I doing wrong?

Update:

Per the suggestion, I tried calling base.OnPaint last instead of first. I don't know what that would have changed, and it doesn't seem to have changed anything either.

Not drawing the background accomplished nothing useful. I still get the artifacting, but then I also don't get the background color so instead I saw image of whatever was underneath the horizontal line.

Was it helpful?

Solution 2

I can hack a solution that doesn't result in artifacting by overriding OnResize() to invalidate the entire control:

protected override void OnResize(EventArgs e)
{
    base.OnResize(e);

    this.Invalidate();
}

I'm not sure that this is the "right" solution, however.

OTHER TIPS

Dont call base.OnPaint, or call it last (I cant recall now).

Also, try overriding the background paint method, so it does not call the base.

I would draw this on a bitmap then draw the bitmap instead of worrying about painting it each time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top