Olivier Chung
Olivier Chung

Reputation: 49

How to refresh graphics in C#

I have a timer in a panel and when the timer ticks, it changes the coordinates of a rectangle.

I have tried two approaches: 1. Inside onPaint method, 2. Timer calls a function to create graphics and draw the moving rectangle

The first one does not work, but when I switch the windows, it moved once.

The second one works with problem. It is moving but leaving the previous position filled with color, which means the graphics are not refreshed.

I simply use g.FillRectangles() to do that.

Can anyone help me?

P.S. the panel is using a transparent background.

Added: This is a System.Windows.Form.Timer

timer = new Timer();
timer.Enabled = false;
timer.Interval = 100;  /* 100 millisec */
timer.Tick += new EventHandler(TimerCallback);

private void TimerCallback(object sender, EventArgs e)
{
    x+=10;
    y+=10;

    //drawsomething();
    return;
}

1.

protected override void OnPaint(PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
    g.FillRectangle(Brushes.Red, x, y, 100, 100);
    base.OnPaint(e);
}

2.

private void drawsomething()
{
    if (graphics == null)
        graphics = CreateGraphics();

    graphics.FillRectangle(Brushes.Red, x, y, 100, 100);
}

Upvotes: 0

Views: 21173

Answers (3)

Alex Erygin
Alex Erygin

Reputation: 3230

You can use Invalidate method. This method Invalidates a specific region of the control and causes a paint message to be sent to the control.

Details are here: http://msdn.microsoft.com/ru-ru/library/system.windows.forms.panel.invalidate%28v=vs.110%29.aspx

Upvotes: 1

Shell
Shell

Reputation: 6849

Place this.Invalidate() in the TimerCallback event.

private void TimerCallback(object sender, EventArgs e)
{
    x+=10;
    y+=10;

    this.Invalidate();
    return;
}

remove drawsomething function. it is not required here.

Full Code:

public partial class Form1 : Form
{
    Timer timer = new Timer();

    int x;
    int y;
    public Form1()
    {
        InitializeComponent();
        timer.Enabled = true;
        timer.Interval = 100;  /* 100 millisec */
        timer.Tick += new EventHandler(TimerCallback);
    }
    private void TimerCallback(object sender, EventArgs e)
    {
        x += 10;
        y += 10;
        this.Invalidate();
        return;
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
        g.FillRectangle(Brushes.Red, x, y, 100, 100);
        base.OnPaint(e);
    }
}

Upvotes: 3

Ehsan
Ehsan

Reputation: 32651

You need to call the Refresh method of control class after redrawing. It

Forces the control to invalidate its client area and immediately redraw itself and any child controls.

Upvotes: 1

Related Questions