Click here to Skip to main content
13,000,324 members (75,819 online)
Click here to Skip to main content
Add your own
alternative version


36 bookmarked
Posted 27 Jun 2004

Getting Scroll Events for a Listbox

, 27 Jun 2004
Rate this:
Please Sign up or sign in to vote.
The standard framework won't tell when the scrollbar moved or what position it is at. This code gives you that control.

Sample Image - ScrollingListbox.png


This example shows how to access scrollbar events in a custom control that is derived from the System.Windows.Forms.ListBox control, in C# .NET. Questions answered are:

  • How do I get the Scroll event?
  • How do I get the Scrollbar position?

Getting Started

Create a new project (File, New, Project...) of type 'Windows Application'. Visual Studio will show the project in your Solution Explorer and 'Form1.cs' in design mode. Right-click the project node and select 'Add, Add User Control...'. Name it 'ScrollingListBox.cs'. It is now visible in the Solution Explorer and it looks like a gray square in the designer.

Press F7 to go to the code and replace the base 'UserControl' by 'ListBox'. Save, compile, go to designer. As you can see, the icon in the Solution Explorer changes and the designer doesn't show a listbox. This is your code at this point:

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace WebsiteSamples
    /// <summary>
    /// Summary description for ScrollingListBox.
    /// </summary>
    public class ScrollingListBox : System.Windows.Forms.ListBox
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        public ScrollingListBox()
            // This call is required by the Windows.Forms Form Designer.

            // TODO: Add any initialization after the InitForm call


        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
            if( disposing )
                if(components != null)
            base.Dispose( disposing );

        #region Component Designer generated code
        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
            components = new System.ComponentModel.Container();

Win32 Stuff

We are going to override the WndProc and handle the scrollbar events. Here're the constants with the same name as in the C:\Program Files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\Include\WinUser.h include file.

private const int WM_HSCROLL = 0x114;
private const int WM_VSCROLL = 0x115;

private const int SB_LINELEFT = 0;
private const int SB_LINERIGHT = 1;
private const int SB_PAGELEFT = 2;
private const int SB_PAGERIGHT = 3;
private const int SB_THUMBPOSITION = 4;
private const int SB_THUMBTRACK = 5;
private const int SB_LEFT = 6;
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;

When we recognize the scroll message in the WndProc, we need to call GetScrollInfo in user32.dll to find out the position. (The Microsoft documentation says that this position is sent in the wparam of the scroll message when the type is SB_THUMBPOSITION or SB_THUMBTRACK, but that's simply not true.) So, first GetScrollInfo is imported from the DLL.

[DllImport("user32.dll", SetLastError=true) ]
private static extern int GetScrollInfo(
    IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo );

The ScrollInfoStruct is called SCROLLINFO in Win32 and it's the typical query construct you see in Microsoft APIs: an info structure is loaded with its own size and a question-code (and optionally arguments for the question). This be the case, the question is 'what's your position?', or 'SIF_ALL'.

private struct ScrollInfoStruct
    public int cbSize;
    public int fMask;
    public int nMin;
    public int nMax;
    public int nPage;
    public int nPos;
    public int nTrackPos;

Finally, detect the message and fire the event

OK, now let's fire the standard ScrollEvent when we receive a scroll message. For this, we need the event, which I called it 'Scrolled', since this is the naming that Microsoft uses for events (like 'Clicked'):

public event ScrollEventHandler Scrolled = null;

In the WndProc, get the scroll message and fire the Scrolled event. In this example, I only respond to the WM_HSCROLL message, since that's the one needed for an owner drawn listbox control. The code for WM_VSCROLL would be exactly the same, however. In this example, I'm only interested in the end-scroll message, which is fired after every scrolling action.

protected override void WndProc(ref System.Windows.Forms.Message msg)
    if( msg.Msg == WM_HSCROLL )
        if( Scrolled != 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(
                Scrolled(this, sargs);
    base.WndProc(ref msg);

To be able to use the Marshal class, you have to reference the Interop namespace:

using System.Runtime.InteropServices;

That should do it. You can extend it by capturing the vertical scrollbar or by capturing more scroll events. If you want to know the scrollbar position at any other time, use the GetScrollInfo function.

Also, I haven't tried it, but it probably works for any control with a scrollbar in it.

In case you're wondering, I needed this code to have other controls 'scroll along' with a ListBox.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Web Developer
Netherlands Netherlands
No Biography provided

You may also be interested in...

Comments and Discussions

Questionwill it work properly in Windows Vista ? Pin
Member 452709619-Aug-09 21:48
memberMember 452709619-Aug-09 21:48 
GeneralScroll position in wParam of SB_THUMBPOSITION and SB_THUMBTRACK Pin
ZachJohnson1-May-09 15:00
memberZachJohnson1-May-09 15:00 
GeneralI made some changes to support vscroll and mouse wheel Pin
Harry Chou26-Sep-07 7:11
memberHarry Chou26-Sep-07 7:11 
QuestionnPos = 0, all the time. Pin
chbfiv21-Aug-07 17:10
memberchbfiv21-Aug-07 17:10 
AnswerRe: nPos = 0, all the time. Pin
Bob A A26-Oct-08 10:55
memberBob A A26-Oct-08 10:55 
GeneralScrollingListBox VB Code Pin
YogJ6923-Aug-06 11:17
memberYogJ6923-Aug-06 11:17 
GeneralRe: ScrollingListBox VB Code Pin
Bob A A26-Oct-08 10:58
memberBob A A26-Oct-08 10:58 
GeneralAdding the control to the form Pin
thomasholme14-Jan-06 1:19
memberthomasholme14-Jan-06 1:19 
Generalhorizontal scallbar in listbox Pin
Anonymous21-Jun-05 20:32
sussAnonymous21-Jun-05 20:32 
QuestionCan i get scroll events for an external application? Pin
llisha20-Apr-05 20:11
memberllisha20-Apr-05 20:11 
QuestionShould this work for all controls? Pin
mcollins200314-Mar-05 9:10
membermcollins200314-Mar-05 9:10 
AnswerRe: Should this work for all controls? Pin
yuanshu_yun11-Jul-06 2:36
memberyuanshu_yun11-Jul-06 2:36 
QuestionHow do i set position of scroll? Pin
dankoGreiner25-Feb-05 2:50
memberdankoGreiner25-Feb-05 2:50 
AnswerRe: How do i set position of scroll? Pin
clivenyong5-Feb-06 7:55
memberclivenyong5-Feb-06 7:55 
GeneralRe: How do i set position of scroll? Pin
PRMan!!!22-Aug-06 13:19
memberPRMan!!!22-Aug-06 13:19 
Generalsome code for the world Pin
Anonymous31-Jan-05 4:42
sussAnonymous31-Jan-05 4:42 
GeneralRe: some code for the world (ScrollUtility.cs) Pin
Anonymous31-Jan-05 4:44
sussAnonymous31-Jan-05 4:44 
GeneralRe: some code for the world (Derived Listbox) Pin
Anonymous31-Jan-05 4:49
sussAnonymous31-Jan-05 4:49 
GeneralRe: some code for the world (Derived Listbox) Pin
dhawal kapdia21-Feb-06 19:17
memberdhawal kapdia21-Feb-06 19:17 
GeneralRe: some code for the world (about ScrollUtility.cs) Pin
Anonymous31-Jan-05 5:05
sussAnonymous31-Jan-05 5:05 
GeneralRe: some code for the world (about ScrollUtility.cs) Pin
brianlang753-Jun-05 9:15
memberbrianlang753-Jun-05 9:15 
GeneralRe: some code for the world (about ScrollUtility.cs) Pin
kasix16-Nov-05 13:47
memberkasix16-Nov-05 13:47 
GeneralRe: some code for the world (about ScrollUtility.cs) Pin
PRMan!!!22-Aug-06 13:19
memberPRMan!!!22-Aug-06 13:19 
QuestionRe: some code for the world (about ScrollUtility.cs) Pin
divinaet20-Aug-07 21:33
memberdivinaet20-Aug-07 21:33 
Generaloriginally Position vs. target Position Pin
thopra19-Jan-05 5:47
memberthopra19-Jan-05 5:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170624.1 | Last Updated 28 Jun 2004
Article Copyright 2004 by bugshake
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid