Scroll事件和Paint事件之间存在滞后,可能介于两者之间

时间:2012-11-16 11:11:25

标签: c# .net panel autoscroll onpaint

我在表单上有一个简单的面板,我正在使用AutoScrollMinSize和AutoScroll在我的面板上获取一些滚动条,一切正常。

我还有一个Scroll事件,我用它来使整个面板区域无效,因为事实上它似乎只会使向左/向右,向上/向下滚动时所需的位无效。除此之外,我使用的是BufferedGraphics,它与面板的大小相同,然后使用.Render(e.Graphics),因为我希望它能够在整个面板上绘制,就像滚动条不存在一样

现在,我遇到的问题是在滚动和绘制的内容时似乎存在视觉上的滞后延迟,我认为这是因为在某个地方有一个额外的绘制/设置阶段,我不熟悉调用Scroll事件或在其间调用Paint事件。

如果我在paint方法中有一个invalidate面板你没有看到问题,但这更多地与多次调用paint事件隐藏问题有关。

所以我认为我理解的方式是,当你滚动时,引擎盖下的东西会有一个大的矩形blit移动已经存在的内容,然后调用与需要填充的区域的矩形无效。

如果是这种情况,那么无论如何都会出现这种情况,因为在禁止此阶段或其他一些设置我缺少以摆脱跟上延迟?

PS:我还重写了OnPaintBackground方法,这是一个空的存根。

1 个答案:

答案 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();
            }
        }
    }