gpt4 book ai didi

c# - 手动处理 WinForms 控件的滚动

转载 作者:行者123 更新时间:2023-11-30 14:59:39 25 4
gpt4 key购买 nike

我有一个可能非常大的控件 (System.Windows.Forms.ScrollableControl)。它具有自定义 OnPaint 逻辑。出于这个原因,我正在使用描述的解决方法 here .

public class CustomControl : ScrollableControl
{
public CustomControl()
{
this.AutoScrollMinSize = new Size(100000, 500);
this.DoubleBuffered = true;
}

protected override void OnScroll(ScrollEventArgs se)
{
base.OnScroll(se);
this.Invalidate();
}

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var graphics = e.Graphics;
graphics.Clear(this.BackColor);
...
}
}

绘画代码主要绘制滚动时移动的“正常”事物。绘制的每个形状的原点都由 this.AutoScrollPosition 偏移。

graphics.DrawRectangle(pen, 100 + this.AutoScrollPosition.X, ...);

但是,该控件还包含“静态”元素,这些元素始终绘制在相对于父控件的相同位置。为此,我只是不使用 AutoScrollPosition 并直接绘制形状:

graphics.DrawRectangle(pen, 100, ...);

当用户滚动时,Windows 会沿与滚动相反的方向平移整个可见区域。通常这是有道理的,因为这样滚动看起来平滑且响应迅速(并且只有新部分需要重新绘制),但是静态部分也会受到此转换的影响(因此 this.Invalidate()OnScroll 中)。在下一次 OnPaint 调用成功重绘表面之前,静态部分会稍微关闭。这会在滚动时产生非常明显的“抖动”效果。

有没有一种方法可以创建一个可滚动的自定义控件,而静态部分没有这个问题?

最佳答案

您可以通过完全控制滚动来做到这一点。目前,您只是连接到事件来执行您的逻辑。我以前遇到过滚动问题,我设法使一切顺利运行的唯一方法是通过覆盖 WndProc 实际处理 Windows 消息。例如,我有这段代码可以在多个 ListBox 之间同步滚动:

protected override void WndProc(ref Message m) {
base.WndProc(ref m);
// 0x115 and 0x20a both tell the control to scroll. If either one comes
// through, you can handle the scrolling before any repaints take place
if (m.Msg == 0x115 || m.Msg == 0x20a)
{
//Do you scroll processing
}
}

使用 WndProc 将在重绘任何内容之前为您提供滚动消息,因此您可以适本地处理静态对象。我会用它来暂停滚动,直到发生 OnPaint。它看起来不会那么流畅,但您不会遇到静态物体移动的问题。

关于c# - 手动处理 WinForms 控件的滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16501557/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com