Click here to Skip to main content
15,881,803 members
Articles / Desktop Programming / Windows Forms

Custom Drawn Scrollbar

Rate me:
Please Sign up or sign in to vote.
4.93/5 (24 votes)
28 Aug 2009CPOL3 min read 129.5K   17.9K   71   20
An article about creating a custom scrollbar control
Image 1

Introduction 

I was working (in my free time) on a calendar control which looks similar to the one in Outlook 2007 and I encountered, among other problems, that the standard scrollbar doesn't fit nicely with the look of my calendar control. So I searched the Web and CodeProject for custom drawn scrollbars.

Among others, I found the article from Greg Ellis. Although it pointed me in the right direction, I missed some things the system scrollbar is capable of. As a last resort, I searched in the help of Visual Studio and found a simple example of a custom drawn scrollbar which I took as a starting point.

Some Remarks

This control is mostly useful for developers who build their own custom drawn controls and need a scrollbar.

The scrollbar has one major shortcoming - the width is fixed. I didn't need this feature and the drawing would be more complex, so I left it out.
Because I used collection initializers, the project builds only with a C# 3.0 compiler and upwards, but that can easily be fixed.
To enable the scrollbar to scroll when pressing and holding the mouse button, I used a timer - didn't find another way.
The drawing is realized with GDI+ (in a separate renderer class) with two exceptions: the little arrow in the arrow buttons and the grip in the thumb are images - there, shame on me, I was a bit lazy.

Layout of the Control

As it is said, a picture says more than thousand words, here is a diagram with the essential classes: 

Image 2

Please note that the property Opacity sets the opacity of the context menu, not of the control itself.
I left out the control designer class because it's not really necessary, only when using Visual Studio. 

Let's Start 

When drawing a control from scratch, it's necessary to override the OnPaint method and also, in my humble opinion, to set some control styles in the constructor:

C#
public ScrollBarEx()
{
   // sets the control styles of the control
   SetStyle(
     ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw
     | ControlStyles.Selectable | ControlStyles.AllPaintingInWmPaint
     | ControlStyles.UserPaint, true);

     ....
}

After that, some thoughts have to go to the logic of the control, among them methods to calculate the thumb size and position.
As an example, here is the method that calculates the thumb size: 

C#
private int GetThumbSize()
{
    // get the size of the track the thumb can occupy
    int trackSize =
       this.orientation == ScrollBarOrientation.Vertical ?
       this.Height - (2 * this.arrowHeight) : this.Width - (2 * this.arrowWidth);

    if (this.maximum == 0 || this.largeChange == 0)
    {
       return trackSize;
    }

    float newThumbSize = ((float)this.largeChange * (float)trackSize) /
      (float)this.maximum;

    return Convert.ToInt32(Math.Min((float)trackSize, Math.Max(newThumbSize, 10f)));
}

The second step was to think about mouse handling, so one needs to override the OnMouseDown, OnMouseUp and OnMouseMove methods to interact with the mouse.

There are three main areas where mouse handling is done:

  • arrow buttons
  • thumb
  • track above and under the thumb

As an addition, I've also overridden OnMouseEnter and OnMouseLeave to get a visual indication whether the mouse is over the scrollbar or not.

The third step was the interaction with the keyboard and can be done in several ways - one way is to override the ProcessDialogKey method which captures also the arrow keys that will be needed to navigate the scrollbar.

The last step was to implement the drawing functionality which I put in a renderer class to separate logic and drawing of the control.

To prevent the painting but still be able to update the scrollbar, two methods were added to the control: 

  • BeginUpdate
  • EndUpdate

These methods send a message via the SendMessage API switching the painting on or off.

Some Last Words

This is my first article here on CodeProject (or elsewhere), so please bear with me. I know this isn't a very good article, but I hope with time and experience future articles will be better. Feel free to point out what I should have done better.

History

  • 28th August, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Franc Morales4-Sep-21 17:50
Franc Morales4-Sep-21 17:50 
QuestionHow to a adjust thumb size, when this scroll is attached to panel Pin
Member 1341336327-May-19 13:48
Member 1341336327-May-19 13:48 
Bugsource and demo code is down Pin
Sebastian.Lange.Net8-Jan-15 19:43
Sebastian.Lange.Net8-Jan-15 19:43 
QuestionWhy did you not use inheritation? Pin
jmerum22-Oct-14 22:26
jmerum22-Oct-14 22:26 
GeneralMy vote of 5 Pin
Wonderwhy113-Oct-12 2:19
Wonderwhy113-Oct-12 2:19 
AnswerRe: My vote of 5 Pin
Thomas Duwe14-Oct-12 21:36
Thomas Duwe14-Oct-12 21:36 
GeneralMy vote of 5 Pin
Tinhiuvanoinho23-Jul-11 6:16
Tinhiuvanoinho23-Jul-11 6:16 
GeneralRe: My vote of 5 Pin
Thomas Duwe25-Aug-11 23:04
Thomas Duwe25-Aug-11 23:04 
GeneralAttaching the scrollbar to panel Pin
roopan18-Dec-09 4:05
roopan18-Dec-09 4:05 
GeneralRe: Attaching the scrollbar to panel Pin
Thomas Duwe19-Dec-09 15:51
Thomas Duwe19-Dec-09 15:51 
GeneralRe: Attaching the scrollbar to panel Pin
roopan19-Dec-09 18:30
roopan19-Dec-09 18:30 
GeneralRe: Attaching the scrollbar to panel Pin
Thomas Duwe29-Dec-09 5:14
Thomas Duwe29-Dec-09 5:14 
GeneralGreat job 5! Pin
v# guy31-Aug-09 16:11
v# guy31-Aug-09 16:11 
GeneralRe: Great job 5! Pin
Thomas Duwe1-Sep-09 22:14
Thomas Duwe1-Sep-09 22:14 
GeneralThanks Pin
Paul Selormey28-Aug-09 16:16
Paul Selormey28-Aug-09 16:16 
Yes, thanks a lot for providing something I was just looking for.
It is a clever decision doing a custom control, instead of customizing the current Windows scrollbars.

I will suggest you make the ScrollBarExRenderer class non-static, and provide methods for others to override and easily scheme the scrollbar, something similar to the ToolStripRenderer.

Best regards,
Paul.


Jesus Christ is LOVE! Please tell somebody.

GeneralRe: Thanks Pin
Thomas Duwe28-Aug-09 17:28
Thomas Duwe28-Aug-09 17:28 
GeneralCool - Voted 5 Pin
Anthony Daly28-Aug-09 8:18
Anthony Daly28-Aug-09 8:18 
GeneralRe: Cool - Voted 5 Pin
Thomas Duwe28-Aug-09 13:51
Thomas Duwe28-Aug-09 13:51 
GeneralRe: Cool - Voted 5 Pin
Anthony Daly29-Aug-09 0:13
Anthony Daly29-Aug-09 0:13 
GeneralRe: Cool - Voted 5 Pin
qingpoqiu1-May-13 16:59
qingpoqiu1-May-13 16:59 

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.