c# - 在运行时移动重叠的图片框会导致重绘滞后

标签 c# .net winforms picturebox

我有 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();
    }

最佳答案

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

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

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

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

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

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

关于c# - 在运行时移动重叠的图片框会导致重绘滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14281085/

相关文章:

c# - 将文本框组合在一起,以便可以通过简单的循环更改它们的所有属性

c# - 从方法表达式获取具体类型

c# - 如何用最小起订量模拟 System.Xml.XmlWriter.WriteAttributeString()?

c# - 当我使用 .NET WebClient DownloadFileAsync 时,我随机返回零长度文件

.net - 滚动ListView时出现错误 "Cannot access a disposed object"

.net - 如何创建支持多个项目(如列表框)的 Winform 用户控件

c# - 如何在 .NET Core 2 中使用 ACL?

c# - 您将如何实现 IEnumerator 接口(interface)?

c# - 无法填充 DataGridView

c# - foreach 缺少控件,除非嵌套和重复