Вопрос

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);
}
Это было полезно?

Решение

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top