首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >手动处理WinForms控件的滚动

手动处理WinForms控件的滚动
EN

Stack Overflow用户
提问于 2013-05-12 04:45:10
回答 2查看 9.6K关注 0票数 3

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

代码语言:javascript
运行
复制
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偏移。

代码语言:javascript
运行
复制
graphics.DrawRectangle(pen, 100 + this.AutoScrollPosition.X, ...);

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

代码语言:javascript
运行
复制
graphics.DrawRectangle(pen, 100, ...);

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

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

EN

Stack Overflow用户

发布于 2013-05-12 05:34:58

你可以通过完全控制滚动来做到这一点。目前,您只需连接到事件来执行您的逻辑。我以前遇到过滚动的问题,唯一能让一切顺利运行的方法就是通过重写WndProc来处理Windows消息。例如,我使用以下代码在多个ListBoxes之间同步滚动:

代码语言:javascript
运行
复制
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。它看起来不会那么平滑,但你不会遇到静态对象移动的问题。

票数 3
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16501557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档