任何人都有关于如何阻止此绘图闪烁的任何建议?我已经尝试了每个双缓冲解决方案,停止使用.CreateGraphics,将所有功能全部移动到位,没有任何工作。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Math
{
public partial class Form1 : Form
{
static Random rand = new Random();
ProblemBox[] problems = new ProblemBox[20];
#region Types
public enum Type
{
Basic, Algebric, Triginomic
}
public class Problem
{
public Type type;
public String problem, answer;
public Boolean isTrue;
public Problem(Type type, String problem, String answer, Boolean isTrue)
{
this.type = type;
this.problem = problem;
this.answer = answer;
this.isTrue = isTrue;
}
}
class ProblemBox
{
public Rectangle rect;
public Problem problem;
public ProblemBox(Problem problem)
{
rect = new Rectangle(0, 309, 244, 30);
this.problem = problem;
}
public void move()
{
rect.Y -= 1;
}
public void draw(Graphics g)
{
g.FillRectangle(Brushes.DarkGray, rect);
g.DrawString(problem.problem + "=" + problem.answer, new Font("Times New Roman", 12.0f), Brushes.DarkBlue, new PointF(rect.X + 5, rect.Y + 5));
}
}
#endregion
public Problem CreateProblem() {
char op = '+';
int a = rand.Next(20), b = rand.Next(20), c;
switch (rand.Next(4)) {
case 2:
c = a - b;
op = '-';
break;
case 3:
c = a * b;
op = '*';
break;
case 4:
c = a / b;
op = '/';
break;
default:
c = a + b;
op = '+';
break;
}
bool isTrue = rand.Next(2) == 1;
if (!isTrue) {
c += 1 + (10 - rand.Next(20));
}
return new Problem(Type.Basic, String.Concat(a + ""+op +""+ b), String.Concat(c), isTrue);
}
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
problems[0] = new ProblemBox(CreateProblem());
}
private void panel1_Paint(object sender, PaintEventArgs e)//Tick
{
ProblemBox temp = null;
if (problems[0].rect.Y < 279)
{
temp = new ProblemBox(CreateProblem());
}
for (int i = 0; i < 20; i++)
{
if (temp != null)
{
ProblemBox temp2 = problems[i];
problems[i] = temp;
temp = temp2;
}
if (problems[i] != null)
{
problems[i].move();
problems[i].draw(e.Graphics);
}
}
Thread.Sleep(20);
DrawingPanel.Invalidate();
}
}
}
答案 0 :(得分:3)
拥有
并不是一个好主意 Thread.Sleep(20);
DrawingPanel.Invalidate();
在Paint
方法内。尽量避免它们,行为可能会大大改善。
答案 1 :(得分:0)
正如Tigran已经说过的那样,问题在于你没有完成重绘,这可以通过以下方式轻松解决:
(new Thread(() =>
{
Thread.Sleep(20);
this.BeginInvoke((MethodInvoker)delegate { DrawingPanel.Invalidate(); });
})).Start();
然而,由于重新绘制缓慢(或者更确切地说 - 不够快),也可能发生闪烁。在这种情况下解决方案非常简单 - 不要直接在屏幕上绘图(使用双缓冲)。
如果您需要标准组件的某些功能,那么必须创建您自己的组件并正确调用它。使用Panel
来解决与Panel
无意无关的事情 - 是不好的。
这是一个很好的首发:
[System.ComponentModel.DesignerCategory("Code")]
public class MyControl : PictureBox
{
public MyControl()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
// ...
}
}