Search code examples
c#winformsrepaintinvalidation

User control repainting only when window moved


I have a custom user control which displays waveform of an audio file. I've put two instances of controls on a form. The second instance works as expected while the first instance causes the problem mentioned.

What I am doing is drawing a vertical (red) line, indicating current position. The problem is best seen in a youtube video.

This is the code of my custom controller (OnPaint() - notice that I invalidate only the region affected by the red vertical line):

protected override void OnPaint(PaintEventArgs e)
{
    [...]
    Invalidate(new Rectangle(x_pos-5, 0, x_pos, this.Height));
    using (Pen linePen = new Pen(Color.Red, 1.5f))
    {
        e.Graphics.DrawLine(linePen, x_pos, 0, x_pos, this.Height);
        Invalidate(new Rectangle(x_pos-2,0,x_pos+2,this.Height));
    }

    base.OnPaint(e);
}

Q: Since the OnPaint method is equivalent for both controls why do I need to move the window to repaint the first control (waveform)?


Solution

  • The problem with OnPaint is that it's only called when it's necessary, for example when the window is moved, resized, after it's brought back from minimized state, or when another window is moved on top of it.

    In order to periodically repaint the window (or parts of it), you'll need to add a Timer to the form and implement its Tick event.

    private void timer1_Tick(object sender, EventArgs e)
    {
        this.Invalidate();
    }
    

    By default, Timer.Interval is set to 100 (100 ms). If you only want to update your rectangle every second, you can increase that value to 1000 if you want.