【发布时间】:2020-06-17 09:17:57
【问题描述】:
我有一个 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”,但不会对表单进行任何更改
在这里我初始化我的表单,调用我的函数并在屏幕上绘制 1 个框。
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
}
}
}
}
【问题讨论】:
-
这还能编译吗?你必须全部重写。为简单起见:订阅 Paint 事件一次,添加一个 Timer(间隔最大 55 毫秒),在其 Tick 事件中,将值添加到 Rectangle 的位置(你永远不会这样做)然后调用
this.Invalidate()。顺便说一句,您不需要每次都用相同的颜色填充表单的 ClientArea,只需在设计器中设置 BackColor。删除Task.Run(),改为启动定时器。 -
您需要在
draw_forever();中调用this.refresh();才能重新绘制表格。由于您正在创建一个新线程,因此您将获得一个例外。所以你需要一种方法来调用它,因为你不会在 creating thread 上调用它 -
我停在
draw_forever()。其余的完全错误,不可读,并且您发布它的方式无法编译(看起来您每次调用该方法时都在订阅 Paint 事件,OnPaint 看起来它在另一个没有 Lambda 的方法中,它不能是本地函数等等)。试试我描述的。 -
@Paul Sütterlin 是吗?那么,
void OnPaint只是被视为本地函数,但不能。编译器不会测试您编写的内容的逻辑。这种方法从根本上就是错误的。 -
@Paul Sütterlin 它可能看起来正在工作。但事实并非如此。 OP 很快就会发现(当应用程序开始崩溃时没有明显原因)。