C#锚定控件在调整大小时“抖动”

4
我有一个可以由用户调整大小的应用程序控件,它有一些按钮锚定在右上角,并且还有一个滚动条。
问题是当控件被调整大小时,右侧锚定的控件也会改变位置,只有几毫秒后控件才会到正确的位置。因此,子控件看起来像是在父控件调整大小时“抖动”。
我已经尝试了各种方法,例如在父控件上使用SuspendLayoutResumeLayout,将每个控件的双缓冲区和其他样式设置为true,设置WS_EX_COMPOSITED位,但似乎没有任何方法可以解决这个问题。
这个问题在其他应用程序中也存在,非常令人恼火。
所以,有没有办法在.NET上修复它?
也许可以将所有内容渲染到后台缓冲区,然后在所有内容完成后将其渲染到屏幕上?

控件嵌套有多深? - TaW
我会说深度大约为5级。有一个滚动条控件,然后是使用此滚动条的列表,然后是另一个控件,该控件具有左/右锚定的一些按钮,此控件位于基本上是窗口的控件内,该窗口控件再放入停靠控件中,其中这些“窗口”控件可以移动和调整大小。代码有点复杂,但我会尝试制作一个简化版本并附加到问题中。 - sleepydog
1
我会创建一个新的事件,在调整大小完成后触发,使用一些计时器魔法来停止和启动一个间隔约为50毫秒的计时器,在每个调整大小事件上,您可以创建这种假的ResizeEnd事件。在第一个调整大小事件中,我将使用dllimport调用(不记得是哪个)来停止绘制窗口或控件的内容。然后当调整大小完成时,再次使用相同的dllimport调用启用绘制。效果将是仅在调整大小完成后或每50毫秒重新绘制自身(如果您在调整大小时暂停)。 - Wolf5
@Wolf5 感谢您的建议,我在父控件上实现了这种方法,并在更改控件位置/大小之前调用SuspendDrawing,然后在布局设置完成后调用ResumeDrawing。它运行良好,“抖动”效果消失了,但现在唯一的问题是有时会在窗体背景上留下垃圾(控件在旧位置的部分)。 - sleepydog
谢谢。我对新创建的嵌套控件使用相同的策略,解决了类似的问题。现在不再出现卡顿。 - Wolf5
显示剩余4条评论
2个回答

2
我会创建一个新的事件,在调整大小完成后触发,并使用一些定时器魔术,在每个调整大小事件上启动和停止一个间隔大约为50毫秒的定时器,你可以创建这种虚假的ResizeEnd事件。
在第一个调整大小事件中,我将使用dllimport调用(不记得是哪个了)来停止绘制窗口或控件的内容。然后当调整大小完成时,再次使用相同的dllimport调用启用绘制。
效果将是它仅在调整大小完成后或每50ms重新绘制自身(如果您在调整大小时暂停)。
ResizeEnd: WinForms - 调整大小事件后的操作
SuspendDrawing: 如何暂停控件及其子项的绘制?

只是一点小提示,我在调用表单时使用了SuspendDrawing();在ResizeBegin事件上,ResumeDrawing(); SuspendDrawing();在Resize事件上,以及ResumeDrawing();在ResizeEnd上,效果非常好,所以计时器并不是必需的。 - sleepydog
计时器只有在创建 ResizeEnd 事件时才需要,除非您的控件已经具备该功能 :) - Wolf5

0

重写命名空间using System.Drawing;下面的虚方法

  protected override Point ScrollToControl(Control activeControl)
    {
        return AutoScrollPosition;
    }

应该解决这个问题!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接