我在表单上有一个简单的面板,我正在使用AutoScrollMinSize和AutoScroll在我的面板上获取一些滚动条,一切正常。
我还有一个Scroll事件,我用它来使整个面板区域无效,因为事实上它似乎只会使向左/向右,向上/向下滚动时所需的位无效。除此之外,我使用的是BufferedGraphics,它与面板的大小相同,然后使用.Render(e.Graphics),因为我希望它能够在整个面板上绘制,就像滚动条不存在一样
现在,我遇到的问题是在滚动和绘制的内容时似乎存在视觉上的滞后延迟,我认为这是因为在某个地方有一个额外的绘制/设置阶段,我不熟悉调用Scroll事件或在其间调用Paint事件。
如果我在paint方法中有一个invalidate面板你没有看到问题,但这更多地与多次调用paint事件隐藏问题有关。
所以我认为我理解的方式是,当你滚动时,引擎盖下的东西会有一个大的矩形blit移动已经存在的内容,然后调用与需要填充的区域的矩形无效。
如果是这种情况,那么无论如何都会出现这种情况,因为在禁止此阶段或其他一些设置我缺少以摆脱跟上延迟?
PS:我还重写了OnPaintBackground方法,这是一个空的存根。
答案 0 :(得分:3)
好的,回答我自己的问题,以防万一在极少数情况下你需要这个帮助。从提及LockWindowUpdate的人开始引导我到WM_SETREDRAW和这篇文章SuspendDrawing,现在我可以平滑滚动,可以绘制完整的面板。只需让Scroll事件执行以下操作即可。 YMMV。
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
private const int WM_SETREDRAW = 0xB;
private void PanelView_Scroll(object sender, ScrollEventArgs e)
{
Control control = sender as Control;
if (control!=null)
{
if (e.Type == ScrollEventType.ThumbTrack)
{
// Enable drawing
SendMessage(control.Handle, WM_SETREDRAW, 1, 0);
// Refresh the control
control.Refresh();
// Disable drawing
SendMessage(control.Handle, WM_SETREDRAW, 0, 0);
}
else
{
// Enable drawing
SendMessage(control.Handle, WM_SETREDRAW, 1, 0);
control.Invalidate();
}
}
}