Click here to Skip to main content
15,881,938 members
Articles / Programming Languages / C#
Article

Understand .NET Scrollbars

Rate me:
Please Sign up or sign in to vote.
4.57/5 (29 votes)
28 Dec 20043 min read 153.7K   3.3K   70   10
Thumb Size, Paging, and Sub-Paging issues.

Image 1

Introduction

Scrollbars seem easy at the surface, but I recently discovered that the .NET implementation needed a minor adjustment for my needs. I decided to write a little test application to study scrollbars and how the different properties affect the visual and functional aspects of a scrollbar.

How Does A ScrollBar Work?

There are three things about a scrollbar that you usually set:

  • The thumb, so that it reflects the visible portion of the document proportional to the entire document, which is represented by the entire track height (or width, for horizontal scrollbars).
  • How to set the scrollbar so that it correctly pages through a document when the user clicks on the track.
  • How to set the scrollbar so that you can correctly display sub-page changes when the user moves the thumb or uses the arrow buttons at the edges of the scrollbar.

This is easy enough to do in .NET with the following properties:

  • LargeChange sets the viewable "page" dimension.
  • Maximum sets the total document dimension.

Setting these two properties adjusts the scrollbar so that the thumb correctly reflects the viewable "page" proportional to the entire document breadth or width. The following equation illustrates the relationship between LargeChange and Maximum to the thumb length and scrollbar length (I'm using length here to reflect one dimension, width or height):

LargeChange     Thumb Length
-----------  =  ------------  
  Maximum       Track Length

Furthermore, when the user clicks on the track, the scrollbar's Value changes by the LargeChange value.

Sub-Page Scrolling

The assumption in the .NET implementation is that you will always want to scroll by a "page" (the LargeChange). I have a situation where I don't want to do this. I have an image viewer that has rows of images, and what I'd like is the LargeChange to scroll by rows, not the entire visible "page", which consists of multiple rows. At the same time, I'd like the SmallChange to scroll pixel rows so that the viewer scrolls smoothly. This second requirement means that I can't do this:

C#
LargeChange=1;       // 1 row
Maximum=numRows;     // total # of rows

because now I can't specify a sub-row SmallChange (this property is of type int). Instead, I should do something like this:

C#
SmallChange=1;                // 1 pixel of change
LargeChange=rowHeight;        // height of 1 row
Maximum=numRows * rowHeight   // total height of all rows

But now my thumb is no longer proportional to the visible "page"! The thumb now reflects the ratio of one row with regards to the whole document rather than the entire page to the whole document. While this works from a functional perspective, the visual aspect is wrong.

The Solution

The solution is to decouple the LargeChange (which has to be used to get the thumb set to the appropriate size) from the actual change in Value when the user clicks on the track. This is accomplished by overriding the WndProc method and trapping the page up/down messages in a specialized VScrollBar (or HScrollBar):

C#
protected override void WndProc(ref Message m)
{
  if (m.Msg == 8469)
  {
    switch((uint)m.WParam)
    {
      case 2: // page up
        if (this.Value - this.ValLargeChange > 0)
        {
          this.Value-=this.ValLargeChange;
        }
        else
        {
          this.Value=0;
        }
        break;

      case 3: // page down
        if (this.Value+this.LargeChange+this.ValLargeChange < this.Maximum)
        {
          this.Value+=this.ValLargeChange;
        }
        else
        {
          this.Value=this.Maximum - this.LargeChange;
        }
        break;

      default:
        base.WndProc (ref m);
        break;
    }
  }
  else
  {
    base.WndProc (ref m);
  }
}

This takes control of the default scrollbar behavior and changes the Value based on my desired large change (in the ValLargeChange property).

Conclusion

You can play with the demo to see the difference in operation. Note that this code isn't brilliant, the property names are clumsy, and the message values are hard coded. Obviously, it's not production code. It is, as the project name indicates, merely a study of the problem.

License

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


Written By
Architect Interacx
United States United States
Blog: https://marcclifton.wordpress.com/
Home Page: http://www.marcclifton.com
Research: http://www.higherorderprogramming.com/
GitHub: https://github.com/cliftonm

All my life I have been passionate about architecture / software design, as this is the cornerstone to a maintainable and extensible application. As such, I have enjoyed exploring some crazy ideas and discovering that they are not so crazy after all. I also love writing about my ideas and seeing the community response. As a consultant, I've enjoyed working in a wide range of industries such as aerospace, boatyard management, remote sensing, emergency services / data management, and casino operations. I've done a variety of pro-bono work non-profit organizations related to nature conservancy, drug recovery and women's health.

Comments and Discussions

 
QuestionThanks Pin
twocozz22-Oct-21 10:38
twocozz22-Oct-21 10:38 
PraiseGood work! Pin
Kitiara30616-Mar-20 16:45
Kitiara30616-Mar-20 16:45 
SuggestionSuggestion of my implementation Pin
wholsh5-Sep-11 5:52
wholsh5-Sep-11 5:52 
GeneralUseful article Pin
oakash8-Jan-10 18:29
oakash8-Jan-10 18:29 
QuestionMessage IDs Pin
metator30-May-06 14:23
metator30-May-06 14:23 
AnswerRe: Message IDs Pin
Marc Clifton30-May-06 15:27
mvaMarc Clifton30-May-06 15:27 
QuestionHow to use Scrollbars Pin
sapphireadmin28-Oct-05 5:59
sapphireadmin28-Oct-05 5:59 
GeneralNice, but... Pin
Member 2611885-Feb-05 10:11
Member 2611885-Feb-05 10:11 
GeneralSuggestions/Comments... Pin
Andrew Smith30-Dec-04 6:32
Andrew Smith30-Dec-04 6:32 
GeneralNice one!!! Pin
Rajesh Pillai28-Dec-04 23:05
Rajesh Pillai28-Dec-04 23:05 

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.