gpt4 book ai didi

c# - 重绘时如何修复面板闪烁?

转载 作者:太空狗 更新时间:2023-10-30 00:15:08 28 4
gpt4 key购买 nike

我有一个我已经子类化的面板并将 DoubleBuffered 设置为 true,我经常需要刷新绘图,但它闪烁并且不知道为什么。

private delegate void MyDelegate();

public void heartBeat()
{
while (true)
{
if (map.processNubots(rules))
{
if (this.InvokeRequired)
{
this.Invoke((MyDelegate)delegate
{
//drawPanel.SuspendLayout();
drawPanel.Refresh();
displayGrid();
//drawPanel.ResumeLayout();
});
}
Thread.Sleep(500);
}
else
{
break;
}
}
}

public void displayGrid()
{
int i = 0;
foreach (DictionaryEntry pair in map)
{
Monomer current = (Monomer)pair.Value;
drawMonomers(current.getLocation(), current.getState());
i++;
}
}

public void drawMonomers(Point location, string state)
{
...

SolidBrush sb = new SolidBrush(mycolor);
SolidBrush sbt = new SolidBrush(Color.Black);
Graphics g = drawPanel.CreateGraphics();
Font text = new Font("Arial", scale / 2);
Pen pen = new Pen(Color.Black, 1);
pen.Alignment = PenAlignment.Inset;
g.FillEllipse(sb, offSet + ((location.Y * scale) / 2) + (location.X * scale), offSet + (-location.Y * scale), scale, scale);
g.DrawEllipse(pen, offSet + ((location.Y * scale) / 2) + (location.X * scale), offSet + (-location.Y * scale), scale, scale);
g.DrawString(state, text, sbt, (offSet + ((location.Y * scale) / 2) + (location.X * scale)) + scale / 6, (offSet + (-location.Y * scale)) + scale / 6);

sb.Dispose();
sbt.Dispose();
pen.Dispose();
}

因此,在每次“计算”并向我想象的网格中添加一些内容后,我需要更新面板以在我的网格上显示这个新项目。我曾尝试在 displayGrid() 函数之前使面板无效,但它似乎会导致更多的闪烁。

heartbeat() 函数当前正在单独的线程上调用。

这是我的新 Panel 类。

public class Display : Panel
{
public Display()
{
this.DoubleBuffered = true;

}
}

最佳答案

    Graphics g = drawPanel.CreateGraphics();

使用 CreateGraphics() 打开双缓冲是最糟糕的组合。 CreateGraphics() 为您提供一个直接绘制到屏幕上的图形对象。双缓冲设置绘制到位图的 Graphics 对象,即双缓冲中使用的缓冲区。然后在绘制周期结束时将位图渲染到屏幕上。

所以在您的代码中发生的事情是您直接绘制屏幕,​​如果它足够慢,您几乎看不到但可以看到。然后就在那之后,你永远不会绘制的缓冲区被绘制。这会抹去你之前画的东西。最终效果是严重闪烁,您的绘画输出仅在几毫秒内可见。

使用 CreateGraphics() 是个错误。您总是希望通过从 Paint 事件获得的 e.Graphics 对象进行渲染,以便渲染到缓冲区。将该 Graphics 对象传递给您的 drawMonomers() 方法。因此:

public void drawMonomers(Graphics g, Point location, string state) {
// Etc...
}

private void Display1_Paint(object sender, PaintEventArgs e) {
//...
drawMonomers(e.Graphics, loc, state);
}

一般来说,CreateGraphics() 的用处非常有限。只有当您直接在屏幕上绘制并且您可以承受绘制的内容消失时才使用它。这通常只在具有不断运行的渲染循环的程序中有用,以每秒 20+ 帧的高速率产生新输出。就像一个电子游戏。

关于c# - 重绘时如何修复面板闪烁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16882921/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com