Я внес некоторые изменения в ваш код:
Сначала я сделал метод draw_forever
asyn c, поэтому вы можете использовать await Task.Delay(55)
. Если вы не используете это, вы ничего не увидите, потому что ваша форма постоянно обновляется.
Затем вам нужно обновить метод draw_rect. Вы рисуете только контур прямоугольника, который не очищает экран. Также я бы порекомендовал вам заменить целочисленное значение colournum фактическим параметром Color. Это упрощает метод draw_rect
и делает код более читабельным.
Третье изменение - вам нужно обновить форму. Введите this.Refresh()
, чтобы убедиться, что все изменения будут отображены.
Вот новый код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;
using System.Threading;
namespace draw_forev
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
draw_rect(this, 50, 150, 20, 20, Color.Black, false); // draw a first black box
this.Shown += (s, e) =>
{
Task.Run(() =>
{
draw_forever();
}
);
};
}
public static void draw_rect(Form form, int x, int y, int width, int height, Color colour, bool fill) // this function draws a block
{
form.Paint += OnPaint;
void OnPaint(object sender, PaintEventArgs e)
{
if (fill)
{
e.Graphics.FillRectangle(new SolidBrush(colour), x, y, width, height);
}
else
{
e.Graphics.DrawRectangle(new Pen(colour, 9), x, y, width, height);
}
}
}
public async void draw_forever()
{
int counter = 0;
while (1 < 2)
{
counter += 1;
Debug.WriteLine("yo " + counter);
draw_rect(this, 0, 0, this.Width, this.Height, Color.White, true); // create a white box to clear the screen
draw_rect(this, counter, 150, 20, 20, Color.Black, false); // create a black box that moves accross the screen
this.Invoke(new MethodInvoker(this.Refresh));
if (counter > this.Width)
{ counter = 0; } // reset the box
await Task.Delay(55);
}
}
}
}
Несмотря на то, что этот код работает, он совсем не эффективен. Вы должны подписаться на событие OnPaint только один раз.