我有一个c#表单,我想用它来绘制一个在屏幕上连续移动的方框
为了实现这个移动框,我有以下函数。
public void draw_forever() {
int counter = 0;
while (1 < 2) {
counter += 1;
Debug.WriteLine("yo");
draw_rect(this, 0, 0, this.Width, this.Height, 1); // create a white box to clear the screen
draw_rect(this, counter, 150, 20, 20,0); // create a black box that moves accross the screen
if (counter > this.Width) { counter = 0; } // reset the box
}
}它会打印"yo",但不会更改表单
在这里,我初始化我的表单,调用我的函数,并在屏幕上绘制一个框。
public Form1()
{
InitializeComponent();
draw_rect(this, 50, 150, 20, 20, 0); // draw a first black box
this.Shown += (s, e) =>
{
Task.Run(() =>
{
draw_forever();
}
);};}我画的1个方框就是你所见过的。所以我们可以看到它永远不会用一个白色的盒子来清除屏幕

将以下代码复制并粘贴到一个空白的c#表单中,以便快速复制我所做的操作
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;
namespace draw_forev
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
draw_rect(this, 50, 150, 20, 20, 0); // 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, int colournum) // this function draws a block
{
Color thecolour;
if (colournum == 0) { thecolour = Color.Black; }
if (colournum == 1) { thecolour = Color.White; }
form.Paint += OnPaint;
void OnPaint(object sender, PaintEventArgs e)
{
if (colournum == 0)
{
using (var Pen1 = new Pen(Color.Black, 9))
{
e.Graphics.DrawRectangle(Pen1, x, y, width, height);
}
}
if (colournum == 1)
{
using (var Pen1 = new Pen(Color.White, 9))
{
Rectangle rect = new Rectangle(x, y, width, height);
e.Graphics.DrawRectangle(Pen1, rect);
}
}
}
}
public void draw_forever() {
int counter = 0;
while (1 < 2) {
counter += 1;
Debug.WriteLine("yo");
draw_rect(this, 0, 0, this.Width, this.Height, 1); // create a white box to clear the screen
draw_rect(this, counter, 150, 20, 20,0); // create a black box that moves accross the screen
if (counter > this.Width) { counter = 0; } // reset the box
}
}
}
}发布于 2020-06-17 17:52:29
我对你的代码做了一些修改:
首先,我将draw_forever方法设为异步,这样您就可以使用await Task.Delay(55)了。如果您不使用它,您将看不到任何东西,因为您的表单不断地自我更新。
然后,您必须更新draw_rect方法。您只绘制矩形的轮廓,这不会清除屏幕。另外,我建议你用一个实际的Color参数替换整型colournum。这使得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事件。
https://stackoverflow.com/questions/62425599
复制相似问题