[英]Horrible Flickering drawing in C#
有人對如何阻止此圖形閃爍有任何建議嗎? 我嘗試了每種雙重緩沖解決方案,停止使用.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();
}
}
}
擁有一個好主意
Thread.Sleep(20);
DrawingPanel.Invalidate();
內部Paint
方法。 嘗試避免它們,行為可能會大大改善。
正如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);
// ...
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.