You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForm双ListBox同步滚动需求:无Scroll Event实现上下滚动联动

实现ListBox滚动时自动同步TopIndex(模拟Excel冻结窗格)

标准ListBox没有公开的滚动事件,要实现滚动时同步两个控件的TopIndex,需通过捕获Windows底层消息来实现,具体方案如下:

1. 自定义带滚动事件的ListBox控件

继承标准ListBox,重写WndProc方法监听滚动相关的Windows消息,触发自定义的Scroll事件:

using System;
using System.Windows.Forms;

public class ScrollableListBox : ListBox
{
    // 自定义滚动事件
    public event EventHandler Scroll;

    protected virtual void OnScroll(EventArgs e)
    {
        Scroll?.Invoke(this, e);
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        // 监听垂直滚动条消息(WM_VSCROLL)和鼠标滚轮消息(WM_MOUSEWHEEL)
        const int WM_VSCROLL = 0x0115;
        const int WM_MOUSEWHEEL = 0x020A;
        
        if (m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL)
        {
            OnScroll(EventArgs.Empty);
        }
    }
}

2. 绑定滚动事件实现同步

将窗体上的两个ListBox替换为上述ScrollableListBox(可通过工具箱添加自定义控件,或代码实例化),然后给两个控件绑定同一个滚动事件处理方法:

private void ScrollableListBox_Scroll(object sender, EventArgs e)
{
    var currentList = sender as ScrollableListBox;
    
    // 双向同步TopIndex
    if (currentList == listBoxLeft)
    {
        listBoxRight.TopIndex = listBoxLeft.TopIndex;
    }
    else if (currentList == listBoxRight)
    {
        listBoxLeft.TopIndex = listBoxRight.TopIndex;
    }
}

额外说明

  • 拖动滚动条、点击滚动条箭头、鼠标滚轮滚动等操作,都会触发实时同步;
  • 需确保两个ListBox的项数一致,避免TopIndex越界;
  • 若仅需单向同步(比如仅右侧滚动时左侧跟随),可删除对应方向的赋值逻辑。

内容的提问来源于stack exchange,提问作者Célio Ávila

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 20:24:24