I admit that I’ve struggled with scrollbars since the Crossbasic days: Specifically, how to get the scrollbar handle to be proportional to the content height. Facing the problem again, I didn’t find the ideal solution in the forums, so I put together a simple demo project:
Var contentHeight As Double = Canvas1.Height
Var visibleFractionOfContentHeight As Double = contentHeight / Me.Height
// Make the scrollbar handle proportional
Scrollbar1.MaximumValue = Ceil((visibleFractionOfContentHeight - 1) * 20) // 20 is magic number that will put the scrollbar at 50%
// Scroll the content
Canvas1.Top = (Me.Height - contentHeight) * Scrollbar1.Value / Scrollbar1.MaximumValue
“20” is a magic number. Would be smoother if .MaximumValue were floating point rather than an Integer, but it works. And I’m open to better solutions.
Here’s a project that has a DesktopScrollbar subclass called ProportionalDesktopScrollbar.
It has one new function, GetContentOffset, that takes the content size and visible size, computes the proportional handle size, and returns the content offset:
Public Function GetContentOffset(contentSize as Double, visibleSize as Double) As Double
Var visibleFractionOfContentHeight As Double = contentSize / visibleSize
// Make the handle proportional
Var maxValue As Double = Ceil((visibleFractionOfContentHeight - 1) * 20) // 20 is magic number that will put a scrollbar at 50%
Me.MaximumValue = maxValue
If maxValue = 0 Then Return 0
// Return the scroll offset
Return (visibleSize - contentSize) * (Me.Value / Me.MaximumValue)
End Function
Call this when resizing the window or when the scrollbar’s value is changed. In the demo project:
Bug fix: 20 is not a magic number—it’s the PageStep value. Using a high PageStep value will increase the granularity of the scrollbar.
Public Function GetContentOffset(contentSize as Double, visibleSize as Double) As Double
Var visibleFractionOfContentHeight As Double = contentSize / visibleSize
// Make the handle proportional
Var maxValue As Double = Ceil((visibleFractionOfContentHeight - 1) * Me.PageStep) // Higher PageStep values offer more granularity in the scrollbar's position
Me.MaximumValue = maxValue
If maxValue = 0 Then Return 0
// Return the scroll offset
Return (visibleSize - contentSize) * (Me.Value / Me.MaximumValue)
End Function