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)

我的设计细节

我有两个类 NodeLink 他们都有 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(自定义任务栏预览)

Tableau 自定义图形联动筛选

Power BI 自定义显示或隐藏线条

在自定义 collectionview 单元格中填充图像而不会闪烁

闪烁自定义语法突出显示不起作用[关闭]

Android自定义的View闪烁问题