Georgi Antonov Georgi Antonov - 1 month ago 5
C# Question

Scrolling two listboxes ( Windows Form ) at same time

Basically I have two list boxes syncListView1 and syncListView2 on the Form ( windows form application ) Im trying to make their scrollbar sync

I have googled some and i found this class but it does not seem to work :

class SyncListBox : System.Windows.Forms.ListBox
{
[Category("Action")]
private const int WM_HSCROLL = 0x114;
private const int WM_VSCROLL = 0x115;
public event ScrollEventHandler OnHorizontalScroll;
public event ScrollEventHandler OnVerticalScroll;

private const int SB_LINEUP = 0;
private const int SB_LINELEFT = 0;
private const int SB_LINEDOWN = 1;
private const int SB_LINERIGHT = 1;
private const int SB_PAGEUP = 2;
private const int SB_PAGELEFT = 2;
private const int SB_PAGEDOWN = 3;
private const int SB_PAGERIGHT = 3;
private const int SB_THUMBPOSITION = 4;
private const int SB_THUMBTRACK = 5;
private const int SB_PAGETOP = 6;
private const int SB_LEFT = 6;
private const int SB_PAGEBOTTOM = 7;
private const int SB_RIGHT = 7;
private const int SB_ENDSCROLL = 8;
private const int SIF_TRACKPOS = 0x10;
private const int SIF_RANGE = 0x1;
private const int SIF_POS = 0x4;
private const int SIF_PAGE = 0x2;
private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetScrollInfo(
IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo);

private struct ScrollInfoStruct
{
public int cbSize;
public int fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
}
protected override void WndProc(ref System.Windows.Forms.Message msg)
{
if (msg.Msg == WM_HSCROLL)
{
if (OnHorizontalScroll != null)
{
ScrollInfoStruct si = new ScrollInfoStruct();
si.fMask = SIF_ALL;
si.cbSize = Marshal.SizeOf(si);
GetScrollInfo(msg.HWnd, 0, ref si);
if (msg.WParam.ToInt32() == SB_ENDSCROLL)
{
ScrollEventArgs sargs = new ScrollEventArgs(
ScrollEventType.EndScroll,
si.nPos);
OnHorizontalScroll(this, sargs);
}
}
}
if (msg.Msg == WM_VSCROLL)
{
if (OnVerticalScroll != null)
{
ScrollInfoStruct si = new ScrollInfoStruct();
si.fMask = SIF_ALL;
si.cbSize = Marshal.SizeOf(si);
GetScrollInfo(msg.HWnd, 0, ref si);
if (msg.WParam.ToInt32() == SB_ENDSCROLL)
{
ScrollEventArgs sargs = new ScrollEventArgs(
ScrollEventType.EndScroll,
si.nPos);
OnVerticalScroll(this, sargs);
}
}
}
base.WndProc(ref msg);
}

private void InitializeComponent()
{
this.SuspendLayout();
//
// scrolled
//
this.Size = new System.Drawing.Size(120, 95);
this.ResumeLayout(false);
}
}


and in the code behind :

private void syncListView2_OnVerticalScroll(object sender, ScrollEventArgs e)
{
syncListView1.TopIndex = syncListView2.TopIndex;
}

private void syncListView1_OnVerticalScroll(object sender, ScrollEventArgs e)
{
syncListView2.TopIndex = syncListView1.TopIndex;
}

Answer

This is really bad practice to copy/paste code from article and don't even bother to read everything about the code and user reviews. You are not the first one who get stuck in this place....because one user already commented the problem

So what you probably missed is to subscribe to events. There is 2 options to do that:

  1. In designer window select first list box. Then in properties window select events tab(1.) and look for OnVerticalScroll event. When you find it click drop down button(2.). The list should contain at least 2 options syncListView1_OnVerticalScroll and syncListView1_OnVerticalScroll. So select syncListView1_OnVerticalScroll. Do the same thing with with second list box but select syncListView1_OnVerticalScrol2

enter image description here

  1. In form where you have list boxes open code view. There should be constructor where is InitializeComponent() method called. After that method add following code lines.

    syncListView1.OnVerticalScroll += this.syncListView1_OnVerticalScroll; syncListView2.OnVerticalScroll += this.syncListView2_OnVerticalScroll;