C# 滚动自定义图形以减少闪烁的更好方法
Posted
技术标签:
【中文标题】C# 滚动自定义图形以减少闪烁的更好方法【英文标题】:C# Better way to scroll custom graphic to reduce flickering 【发布时间】:2012-07-06 20:52:21 【问题描述】:我正忙于开发一个 C# win 表单应用程序,它以分层结构绘制数据库结构的图形表示。
一切正常,只是滚动有问题。它有一个严重的闪烁问题。
我研究了以下内容:
C# graphics flickering
当您想刷新表面时,请致电 Invalidate()
(帮助很大,但仍有一点延迟)
还将DoubleBuffered
属性设置为True(这个问题我得到一个ArgumentException
抛出消息“参数无效。”但我可以在我的主窗体上将DoubleBuffered
设置为true)
我的设计细节
我有两个类 Node
和 Link
他们都有 GraphicsPath
成员,他们都有一个 public void Draw(Graphics g)
方法来绘制自己。
我还有一个用户控制调用StructureMap
覆盖了protected override void OnPaint(PaintEventArgs e)
方法,循环遍历每个Node
调用它的绘图函数。循环很简单,因为父节点通过Link
对象链接到子节点。我所要做的就是调用父节点的draw方法,它的所有子节点也都被重绘了。
我也在以同样的方式进行 Hit 测试。
有没有更好的方法?为什么我不能在我的用户控件上将 DoubleBuffered
设置为 true?
PS:这是我的第一篇文章,请告诉我我是怎么做的?
【问题讨论】:
【参考方案1】:DoubleBuffered ArgumentException 可能是由于您在某处处置了图形对象。
也可以参考这篇文章; What could cause Double Buffering to kill my app?
【讨论】:
你是对的,这解决了 DoubleBuffered 问题。我认为您需要 Dispose 图形对象以防止内存泄漏。但是在使用 DoubleBuffered 时,滚动仍然会有延迟。 @ZioN:那是因为你的绘画程序很慢,这是完全不同的事情。请随时为此提出另一个问题。【参考方案2】:您的闪烁声音似乎是由您绘制图像所需的处理量引起的。
缓解这种情况的一种方法是将模型绘制到屏幕外位图,然后您的绘画/滚动等只是将该位图绘制到屏幕上。
只有在你的模型改变时才更新位图。
【讨论】:
我认为位图可以帮助很多。我也想知道你能用位图做命中测试吗?由于我还想为我的对象设置动画,希望能够选择和取消选择它们? 一种方法是将图像附加到 PictureBox 控件,将图片框放置在启用 AutoScroll 的 Panel 内。使用各种鼠标事件来获取鼠标交互的位置。 我以后会看看这个,因为现在我只是使用我当前的设计,因为使用位图和 PictureBox 将是重新设计。我想我会在第 2 版中考虑这一点;)【参考方案3】:使用位图作为背景图像将减少闪烁。可能是这样的:
private Bitmap _backBuffer;
private void Form1_Paint(object sender, PaintEventArgs e)
if (_backBuffer == null)
_backBuffer = new Bitmap(Form1.Width, Form1.Height, PixelFormat.Format32bppRgb);
Graphics g = Graphics.FromImage(_backBuffer);
g.SmoothingMode = SmoothingMode.HighQuality;
drawSomething(g);
//Copy the back buffer to the screen
e.Graphics.DrawImageUnscaled(_backBuffer, 0, 0);
Form1.BackgroundImage = _backBuffer;
【讨论】:
以上是关于C# 滚动自定义图形以减少闪烁的更好方法的主要内容,如果未能解决你的问题,请参考以下文章
闪烁窗口不适用于 TabbedThumbnail(自定义任务栏预览)