【问题标题】:Moving overlapping Pictureboxes at runtime causes lag in repaint在运行时移动重叠的图片框会导致重绘滞后
【发布时间】:2013-01-11 15:17:32
【问题描述】:

我有 2 个可移动的图片框,允许用户四处移动图像并按照自己的意愿对齐它们

当我将图片框 A 拖到图片框 B 上时,A 图像的尾随部分显示到 B 中。它很快就消失了。这与您在分辨率较差的旧 Windows 上看到的情况相同。

它的特殊之处在于它只显示在静态图片框内,而不是下面的空白区域。我一直在摆弄暂停布局和恢复布局,但运气不佳。有什么建议么?如果有帮助,我也愿意将控件类型从 Picturebox 更改为其他内容。

public void OnMouseMove(object sender, MouseEventArgs mouseEventArgs)
    {
        var control = sender as Control;

        control.SuspendLayout();

        Point pt = new Point(mouseEventArgs.X, mouseEventArgs.Y);

        control.Left += pt.X - _startDraggingPoint.X;
        control.Top += pt.Y - _startDraggingPoint.Y;


        control.ResumeLayout();
    }

【问题讨论】:

    标签: c# .net winforms picturebox


    【解决方案1】:

    这是 Winforms 中一个相当不可避免的问题,它是由您使用多个控件引起的,并且由于控件呈现到屏幕的方式而可见。逐个。双缓冲并不能解决问题,它只适用于每个单独控件的渲染,而 PictureBox 已经是双缓冲的。事实上,它使问题更糟,因为双缓冲不是免费的,而且会延迟绘制程序。

    它可见的最大原因是您的 PictureBox 控件在绘制图像时速度很慢。当您要求它缩放图像并期望它从大图像中渲染出漂亮的小图像时,就会发生这种情况。这种重新缩放需要时间,尤其是在图像很大的情况下,并且每次控件绘制自身时都会完成。您可以通过自己预缩放图像来修复它,这样控件就不必这样做了。

    真正的解决方法是根本不使用任何 PictureBox 控件,而只是让表单绘制图像。现在双缓冲解决了你的问题。你当然会失去很多便利,包括 PB 执行的内置缩放和免费获得的命中测试。实际上实施起来并不难。

    Windows 中有一个魔法咒语,可以潜在地解决问题,而无需您做任何工作来改进您的代码。您可以要求它对窗口及其所有子控件进行双重缓冲。一切都被渲染到屏幕外缓冲区,结果被传送到屏幕上。将此代码粘贴到您的表单中:

    protected override CreateParams CreateParams {
        get {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
            return cp;
        }
    }
    

    可能导致绘制伪影,如果它们太有害,那么您将不得不改进您的代码。

    【讨论】:

    • 感谢详细的解释!简单地将图像绘制成矩形并不难。我以其他形式这样做。问题是必须在表单上捕获单击和拖动事件,我特别希望它们在控件中。这是因为该功能是附加功能,我不想破坏当前架构。您是否有建议将点击拖动事件保留在图片控件而不是容器表单中?
    • 好吧,您已经知道图像的位置,或者您无法在表单的 Paint 事件处理程序中将它们绘制在正确的位置。因此,在 MouseDown 事件处理程序中找出哪个被点击也不难。
    • 我想你读错了。我可以检测到(实际上我在另一个程序中执行此操作)正在被单击,但是使用图形来绘制它们意味着它是正在执行检测的容器。我需要保持容器完好无损,因为它的主要目的不是这个功能。
    • 好吧,不管怎样,然后容器的 Paint 和 MouseDown 事件。
    【解决方案2】:

    将控件上的属性“DoubleBuffered”设置为 true。这可能有助于减少闪烁。

    见:http://msdn.microsoft.com/de-de/library/system.windows.forms.control.doublebuffered(v=vs.80).aspx

    【讨论】:

      【解决方案3】:

      最后,我采用了不同的解决方案。我们使用 DevExpress 的文档管理器来保存我们的图像控件。花了点功夫,但效果更好,结果也很顺利。

      【讨论】:

      • 怎么会有人否决我自己的解决方案?请解释一下?
      猜你喜欢
      • 2016-08-08
      • 1970-01-01
      • 2022-07-29
      • 2012-06-03
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多