我的目标是移动使用 Graphics 对象的方法绘制的可视元素在没有闪烁或伪影的情况下(在 .NET 3.5 中)在 Form 上移动。我可以通过使用自动双缓冲(将 Form 的 DoubleBuffered 属性设置为 true)或自己实现后缓冲来成功实现无闪烁移动。然而,我正在努力寻找一种方法来使用这两种方法,而不会显示清晰可见的伪影。
使用自动双缓冲时,页面撕裂效果很明显。在我的 60Hz LCD 的多达 3 次刷新过程中,似乎后台缓冲区正在缓慢地、逐步地从上到下复制到表单中。
当我自己实现双缓冲时(有关详细信息,请参阅代码块),它看起来好像后台缓冲区被复制到表单的速度足够快,不会发生页面撕裂。然而,有时会出现另一种类型的伪影。下面的代码允许您使用箭头键在窗体上左右移动白色背景上的蓝色矩形,应该将效果再现为一系列水平的白色带,这些带有时会出现在矩形的左右边缘就像它被移动一样。
public partial class Form1 : Form {
int x;
Bitmap buffer;
public Form1() {
InitializeComponent();
buffer = new Bitmap(Width, Height);
}
private void Form1_Paint(object sender, PaintEventArgs e) {
Graphics g = Graphics.FromImage(buffer);
g.Clear(Color.FromArgb(255, 255, 255));
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.FillRectangle(Brushes.Blue, x, 0, 100, 500);
e.Graphics.DrawImageUnscaled(buffer, 0, 0);
}
protected override void OnPaintBackground(PaintEventArgs pevent) {
//Don't allow the background to paint
}
private void Form1_KeyDown(object sender, KeyEventArgs e) {
const int scrollSpeed = 20;
if(e.KeyData == Keys.Left) {
x -= scrollSpeed;
Refresh();
}
else {
if(e.KeyData == Keys.Right) {
x += scrollSpeed;
Refresh();
}
}
}
}
if(其他人能够重现效果){
我做错了什么,可能
在绘画代码中触发了某种竞争条件,或者
这只是我必须
忍受的运行时行为?
}
else {
这可能是我的显卡的特性或
显示驱动程序有问题吗?
}