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
相关产品推荐
相关产品推荐

