Nik*_*san 5 .net c# panel onpaint autoscroll
我在表单上有一个简单的面板,我正在使用 AutoScrollMinSize 和 AutoScroll 在面板上获取一些滚动条,一切正常。
我还有一个滚动事件,我用它来使整个面板区域无效,因为事实上它似乎只使左/右、上/下滚动时所需的位无效。除此之外,我使用与面板大小相同的 BufferedGraphics,然后执行 .Render(e.Graphics),因为我希望它在整个面板上绘制,就好像滚动条不存在一样。
现在,我遇到的问题是,滚动和绘制内容时似乎存在视觉上的滞后,我认为这是因为在滚动事件之前有一个我不熟悉的额外绘制/设置阶段调用或在该事件与调用的 Paint 事件之间进行。
如果我在绘制方法中有一个无效面板,您不会看到问题,但这更多地与多次调用绘制事件隐藏问题有关。
所以我认为我理解它的方式是,当你滚动时,引擎盖下的某个东西会做一个大矩形 blit 移动已经存在的内容,然后调用需要填充区域的矩形 invalidate 。
如果是这种情况,是否有任何围绕此问题的方法,例如抑制此阶段或我缺少的一些其他设置以消除跟上滞后?
PS:我还重写了 OnPaintBackground 方法,它是一个空存根。
好的,回答我自己的问题,以防在极少数情况下您需要这个问题时对任何人有帮助。从有人提到 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2128 次 |
最近记录: |