Question

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);
}
Était-ce utile?

La solution

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);
    }
}

Autres conseils

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.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top