Introduction

In one of my recent projects, I needed to scroll large number of items. To be precise, I wanted to scroll contents of entire physical drive. It is easy to guess that out-of-the-box WinForms ScrollBar with Maximum, Minimum, and Value properties defined as Integer (Int32) is not very useful for this purpose.

In the reality, limitation is even stronger. In design mode: setting Maximum to anything more than 1,000,000,000 and Minimum to anything less than -1,000,000,000 results in design time exception ("Property value is not valid" message). On the other hand, you can set Minimum and Maximum from the code to any valid integer (Int32) value. No exception is thrown. But when expression Maximum - Minimum evaluates to more than int.MaxValue -1, you can observe strange behavior. Value of Maximum suddenly changes to something different than you wanted it to be. Better don't even try to play with Microsoft's ScrollBar and big numbers. For this, you have ScrollBarEnhanced described in this article.

As I said above:

If you remember Vertical ScrollBar in Visual Studio with multicolored graphical decorations, this is what I wanted to achieve.

Background

In the first attempt to solve my problem, I built a custom control inherited from VScrollBar (I didn't care about the horizontal scrollbar at this time, all I needed was vertical scrollbar). I was able to overwrite Maximum, Minimum, and Value properties to accept long values. But first, it was quite ugly code (translating long values from the wrapper to int values for underlying VScrollBar and vice versa and I still could not show a graphical decoration for bookmarks, and dynamic tooltips were not easy to implement as well.

After I decided to code ScrollBarEnhanced from scratch, I quickly upgraded my requirements to use decimal instead of long for Maximum, Minimum, SmallChage, LargeChange and Value properties.

Decimal has 28-29 significant digit precision and an approximate values range of -1.0 x 10-28 to 7.9 x 10+28. This is much better than long with values in range -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 ("only" 19 significant digits). There is the reason for greater accuracy of decimal. decimal is 128-bit data type while long is 64-bit "only". And the final argument for using decimal was fact that WPF version of ScrollBar does use decimal so why not have similar behavior in WinForms version of it.

To code my own ScrollBarEnhanced implementation, I need to program the following:

Overview

For start, I created in Visual Studio ScrollBarEnhanced custom control inherited from UserControl.

public class ScrollbarEnhanced : UserControl 

This control encapsulates functionality of both Vertical and Horizontal ScrollBar and adds several enhancements to satisfy my needs.

All drawing happens in OnPaint. Below I'm showing simplified version that paints basic ScrollBar. The "real" code has a little bit more lines in order to address different way of painting hot or pressed elements of ScrollBar. I removed them here to show how simple is the basic drawing of ScrollBarEnhanced: just few calls to ScrollBarRenderer draw methods - that's all.

protected override void OnPaint(PaintEventArgs e) 
{ 
   int ArrowHeight = SystemInformation.VerticalScrollBarArrowHeight;
 
   //Draw top arrow
   ScrollBarRenderer.DrawArrowButton(e.Graphics,rec, ScrollBarArrowButtonState.UpNormal);
           
   //Draw top track
   int ThumbPos = Value2ThumbTopPosition(Value);
   rec = new Rectangle(0, ArrowHeight + 1, ClientSize.Width, ThumbPos - ArrowHeight);
   ScrollBarRenderer.DrawUpperVerticalTrack(e.Graphics, rec, ScrollBarState.Normal);
 
   //draw thumb
   int nThumbHeight =ThumbHeight;
   rec = new Rectangle(0, ThumbPos, ClientSize.Width, nThumbHeight);
   ScrollBarRenderer.DrawVerticalThumb(e.Graphics, rec, ScrollBarState.Normal);
 
   //draw thumb grip
   ScrollBarRenderer.DrawVerticalThumbGrip(e.Graphics, rec, ScrollBarState.Normal);
 
   //Draw bottom track
   rec = new Rectangle(0, ThumbPos + nThumbHeight, 
             ClientSize.Width, TrackHeight - (ThumbPos + nThumbHeight));
   ScrollBarRenderer.DrawLowerVerticalTrack(e.Graphics, rec, ScrollBarState.Normal);
 
   //Draw bottom arrow 
   rec = new Rectangle(0, ClientSize.Height - ArrowHeight, ClientSize.Width, ArrowHeight);  
   ScrollBarRenderer.DrawArrowButton(e.Graphics, rec, ScrollBarArrowButtonState.DownNormal);
 
   //Draw  bookmarks (on top of everything)
   if (Bookmarks != null)
   {
      foreach (ScrollBarBookmark bk in Bookmarks)
      {
         DrawBookmark(e.Graphics, bk);
      }
  }
}

DrawBookmark method called from OnPaint is used to display bookmark markers on the ScrollBarEnhanced control. They are three flavors of bookmarks: ImageScrollBarBookmark, BasicShapeScrollBarBookamrk and ValueRangeScrollBarBookmark. All three are derived from Abstract class ScrollBarBoookmark.

private void DrawBookmark(Graphics Graphics, ScrollBarBookmark Bookmark)
{
    BasicShapeScrollBarBookmark shapeBookmark = null;
    ImageScrollBarBookmark imageBookmark=null;
    if (Bookmark is BasicShapeScrollBarBookmark)
        shapeBookmark = (BasicShapeScrollBarBookmark)Bookmark;
    else
        imageBookmark = (ImageScrollBarBookmark)Bookmark;

    //Make sure that brush needed for drawing is ready to use
    if (shapeBookmark != null)
    {
        if (shapeBookmark.Brush == null)  //this bookmark is used to the first time
        {
            if (!m_BrushesCache.ContainsKey
            (shapeBookmark.Color))  //this color is used for the first time
                m_BrushesCache.Add(shapeBookmark.Color, new SolidBrush(shapeBookmark.Color));

            shapeBookmark.Brush = m_BrushesCache[shapeBookmark.Color];
        }
        //Make sure that pen needed for drawing is ready to use
        if (shapeBookmark.Pen == null)  //this bookmark is used to the first time
        {
            if (!m_PensCache.ContainsKey
            (shapeBookmark.Color))  //this color is used for the first time
            {
                m_PensCache.Add(shapeBookmark.Color, new Pen(shapeBookmark.Color));
            }
            shapeBookmark.Pen = m_PensCache[shapeBookmark.Color];
        }

        if (shapeBookmark.Stretch)
        {
            Bookmark.X = 0;
            shapeBookmark.Width = this.ClientSize.Width;
        }
        else
        {
            CalculateBookmarkXPosition(Bookmark);
        }
    }
    else  //Calculate X for ImageBookmark
    {
        CalculateBookmarkXPosition(Bookmark);
    }

    //Calculate top Y position of bookmark 
    Bookmark.Y = (int)(TrackHeight * Bookmark.Value / Maximum + 
      SystemInformation.VerticalScrollBarArrowHeight - Bookmark.Height / 2);

    if (imageBookmark != null)
    {
        Graphics.DrawImage(imageBookmark.Image, new Point(Bookmark.X, Bookmark.Y)); 
    }
    else  if (shapeBookmark.FillBookmarkShape)
    {
        if (shapeBookmark.Shape == ScrollbarBookmarkShape.Oval)
            Graphics.FillEllipse(shapeBookmark.Brush, new Rectangle(Bookmark.X, 
               Bookmark.Y, shapeBookmark.Width, shapeBookmark.Height));
        else
            Graphics.FillRectangle(shapeBookmark.Brush, new Rectangle(Bookmark.X, 
               Bookmark.Y, shapeBookmark.Width, shapeBookmark.Height));
    }
    else  
    {
        if (shapeBookmark.Shape == ScrollbarBookmarkShape.Oval)
            Graphics.DrawEllipse(shapeBookmark.Pen, new Rectangle(Bookmark.X, 
              Bookmark.X, shapeBookmark.Width, shapeBookmark.Height));
        else
            Graphics.DrawRectangle(shapeBookmark.Pen, new Rectangle(Bookmark.X, 
              Bookmark.X, shapeBookmark.Width, shapeBookmark.Height));
    }
}
private void CalculateBookmarkXPosition(ScrollBarBookmark Bookmark)
{
    switch (Bookmark.Alignment)
    {
        case ScrollBarBookmarkAlignment.Left:
            Bookmark.X = 0;
            break;
        case ScrollBarBookmarkAlignment.Right:
            Bookmark.X = this.ClientSize.Width - Bookmark.Width;
            break;
        case ScrollBarBookmarkAlignment.Center:
            Bookmark.X = (this.ClientSize.Width - Bookmark.Width) / 2;
            break;
    }
}

ScrollBarBookmark class mentioned above requires a little bit more attention. You will be using it only if you want to display bookmarks on your scrollbar. ScrollBarBookmark is an abstract class that contains basic bookmark properties defined as follows:

public abstract class ScrollBarBookmark
{
    [DefaultValue(0)]
    public decimal Value { set; get; }

    [DefaultValue(ScrollBarBookmarkAlignment.Left)]
    public ScrollBarBookmarkAlignment Alignment { set; get; }

    //e.g. Bookmark object from host can contain any sort of info
    //can be handy when bookmark is clicked; moved over etc.
    [DefaultValue(null)]
    public object Tag { set; get; }

    public virtual int Height { set; get; }
    public abstract int Width { set; get; }

    //Every time bookmark is repainted the following two values are 
    //Populated with X, Y of bookmark center
    protected internal int X { set; get; }
    protected internal int Y { set; get; }
}  

"Real" bookmarks are stored in instance of one of three classes inherited from ScrollBarBookmark:

ImageScrollBarBookmark is defined below:

public class ImageScrollBarBookmark : ScrollBarBookmark
{
    public ImageScrollBarBookmark()
    {
        this.Image = null;
        this.Value = 0;
        this.Alignment = ScrollBarBookmarkAlignment.Left;
        this.Tag = null;
    }
    public ImageScrollBarBookmark(decimal Value, Image Image, 
            ScrollBarBookmarkAlignment Alignment, object Tag)
    {
        this.Image = Image;
        this.Value = Value;
        this.Alignment = Alignment;
        this.Tag = Tag;
    }
    public Image Image { set; get; }
    public override int Width 
    {
        get { return Image.Width; }
        set {  ;}
    }
    public override  int Height
    {
         get { return Image.Height; }
        set {;}
    }
} 

And here goes BasicShapeScrollBarBookmark:

public BasicShapeScrollBarBookmark()
{
    Value = 0;
    Alignment = ScrollBarBookmarkAlignment.Left;
    Height = 5;
    Width = 5;
    Shape = ScrollbarBookmarkShape.Rectangle;
    Color = Color.Orange;
    FillBookmarkShape = true;
    Stretch = false;
    Tag = null;
}

public BasicShapeScrollBarBookmark(decimal ScrollValue, 
       ScrollBarBookmarkAlignment Alignment, int Height, 
       int Width, bool Stretch, object Tag)
{
    this.Value = ScrollValue;
    this.Alignment = Alignment;
    this.Height = Height;
    this.Width = Width;
    this.Stretch = Stretch;  //Stretch to smallest scrollbar dimension
    this.Tag = Tag;
    this.Shape = ScrollbarBookmarkShape.Rectangle;
    this.Color = Color.Empty;
    this.FillBookmarkShape = true;
}

public BasicShapeScrollBarBookmark(decimal ScrollValue, 
       ScrollBarBookmarkAlignment Position, int Height, int Width, 
       ScrollbarBookmarkShape Shape, Color Color, bool FillBookmarkShape, 
       bool StretchToScrollBarWidth, object Tag)
{
    this.Value = ScrollValue;
    this.Alignment = Position;
    this.Height = Height;
    this.Width = Width;
    this.Shape = Shape;
    this.Color = Color;
    this.FillBookmarkShape = FillBookmarkShape;
    this.Stretch = StretchToScrollBarWidth;
    this.Tag = Tag;
}

int m_Width = 0;
[DefaultValue(4)]
public override int Width
{ 
     set { m_Width = value; } 
     get { return m_Width; } 
}

int m_Height = 0;
[DefaultValue(4)]
public override int Height 
{ 
    set { m_Height = value; }
    get { return m_Height; } 
}

[DefaultValue(false)]
public bool Stretch { set; get; }

[DefaultValue(ScrollbarBookmarkShape.Rectangle)]
public ScrollbarBookmarkShape Shape { set; get; }

[DefaultValue(true)]
public bool FillBookmarkShape { set; get; }

private Color m_Color = Color.Empty;
[DefaultValue(typeof(Color), "Orange")]
public Color Color 
{
    set
    {
        if (m_Color != value)
        {
            m_Color = value;
            Pen = null;
            Brush = null;
        }
    }
    get { return m_Color; }
}
 
[NonSerialized]
private Pen m_Pen;
protected internal Pen Pen 
{
    set { m_Pen = value; }
    get { return m_Pen; }
}

[NonSerialized]
private Brush m_Brush;
protected internal Brush Brush
{
    set { m_Brush = value; }
    get { return m_Brush;  }
}

ValueRangeScrollBarBookmark adds one extra property to BasicShapeScrollBarbookmark: EndValue.

public class ValueRangeScrollBarBookmark : BasicShapeScrollBarBookmark
{

    public ValueRangeScrollBarBookmark()
    {
        Name = "";
        Value = 0;
        EndValue = 0;
        Alignment = ScrollBarBookmarkAlignment.Left;
        Height = 5;
        Width = 5;
        Shape = ScrollbarBookmarkShape.Rectangle;
        Color = Color.Orange;
        FillBookmarkShape = true;
        Stretch = false;
        Tag = null;
    }



    public ValueRangeScrollBarBookmark(string Name, decimal StartValue, 
        decimal EndValue, ScrollBarBookmarkAlignment Alignment, int Depth, 
        Color Color, bool FillBookmarkShape, bool StretchToScrollBarWidth, object Tag):
        base(Name, StartValue, Alignment, 0, Depth, ScrollbarBookmarkShape.Rectangle, 
        Color, FillBookmarkShape, StretchToScrollBarWidth, Tag)
    {
        this.EndValue = EndValue;
    }

    public decimal EndValue { set; get; }

    int m_Width = 0;
    [DefaultValue(4)]
    [Description("ValueRangeScrollBarBookmark Height (for vertical) 
      or Width (for horizontal) are calculated every time scrollbar is repainted. 
      Value will change every time Minimum, Maximum or scrollbar size change.")]
     public override int Width
    {
        set { m_Width = value; }
        get { return m_Width; }
    }

    int m_Height = 0;
    [DefaultValue(4)]
    [Description("ValueRangeScrollBarBookmark Height (for vertical) 
      or Width (for horizontal) are calculated every time scrollbar is repainted.
      Value will change every time Minimum, Maximum or scrollbar size chage.")]
    public override int Height
    {
        set { m_Height = value; }
        get { return m_Height; }
    }
}

When ValueRangeScrollBookmark is drawn in OnPaint method, its length (height for Vertical or width for horizontal scrollbar) is calculated as follows:

int bookmarkLength =(Bookmark.EndValue - Bookmark.Value) / (Maximum - Minimum)) * TrackLength);

And finally goes the definition of enums used in above code:

public enum ScrollbarBookmarkShape
{
    Rectangle,
    Oval,
}
public enum ScrollBarBookmarkAlignment
{
    Left,
    Right,
    Center
}

Typically, you would assign bookmarks from the code. For example, user of your program clicks something on the page with attached scrollbar and wants to mark this position for quick reference.

Here is the short description of BasicShapeScrollBarBookmark properties

Property

Description

Alignment

Bookmark position enumerator. Can be Left, Center, or Right

Color

Bookmark color; color used to draw bookmark border and the bookmark body.

FillBookmarkShape

If set to true, bookmark body is filled with the same color as the bookmark border, otherwise only border line of bookmark is displayed. Since bookmark markers are usually small, most likely you would like to keep this property set to true to make marker more visible.

Height

Height of the bookmark graphical element; default value is 5 pixels.

Shape

Bookmark shape enumerator: can be Rectangle or Oval

Stretch

If this property is set to true, Width and Position properties are disregarded and bookmark is shown as a rectangle or oval (depending on Shape property value) with Width equal to the width of the scrollbar control instance.

Tag

Anything can go here. It can be useful if you want to assign more information to the bookmark object than list of predefined properties can offer. ScrollBarEnhanced doesn't make any use if it, but since some enhanced events return original bookmark object to the host (for example: the list of bookmarks mouse is moving over), host can find Tag values handy in some situations.

Value

Value property of ScrollBarEnhanced corresponding to the center of bookmark graphical representation.

Width

Width of the bookmark graphical element; default value is 5 pixels.

ImageScrollBarBookmark has a little bit different set of properties:

Property

Description

Alignment

Bookmark position enumerator. Can be Left, Center, or Right

Height

Height of the bookmark graphical element (height of the Image). This is read-only property.

Image

Graphical element to be displayed as a bookmark.

Tag

Anything can go here. It can be useful if you want to assign more information to the bookmark object than list of predefined properties can offer. ScrollBarEnhanced doesn't make any use if it, but since some enhanced events return original bookmark object to the host (for example list of bookmarks mouse is moving over), host can find Tag values handy in some situations.

Value

Value property of ScrollBarEnhanced corresponding to the center of bookmark graphical representation.

Width

Width of the bookmark graphical element (width of the Image). This is read-only property.

ValueRangeScrollBarBookmark has identical properties as BasicShapeScrollBarBookmark plus one extra:

Property

Description

EndValue

Together with Value it defines range of values and effectively the size of shape used to draw the bookmark.

Besides OnPaint few more methods play key role in the code. Below they are briefly mentioned. If you want more details please view ScrollBarEnhanced source code attached to this article.

Method

Description

OnMouseClick

Fires MouseClick event with extended list values passed as an argument.

OnMouseDown

Saves current mouse position. Fires proper OnScroll events. If mouse down was on up or down arrow, decrements or increments Value by SmallChange amount. If mouse was down on upper or lower track area, decrements or increments Value by LargeChage.

OnMouseLeave

Cleanups after other mouse actions.

OnMouseMove

If mouse is down and over the thumb, performs thumb dragging. Otherwise fires MouseMove event with extended list values passed as an argument.

OnMouseUp

Fires Scroll event with extended list values passed as an argument.

Using the Code

You can use ScrollBarEnhanced control exactly same way you are using regular WinForms VScrollBar or HScrollBar. ScrollBarEnhanced has an Orientation property that makes scrollbar to behave like vertical or horizontal scrollbar appropriately. You just have to drop it on desired Form, set up needed properties, hook up events you want to intercept and you are ready to go.

Enhanced Properties You Can Use Are:

Property

Description

Bookmarks

Collection of ScrolBarBookmark objects. Each element defines where and how to display bookmark graphical marker. You can define value, location, size, color and shape.

BookmarksOnTop

This property defines if bookmark are drawn as the topmost items (when set to true). This means that scrollbar thumb might be partially cover with bookmark. If this property is set to false, topmost item is scrollbar thumb.

ContextMenuStrip

This property is inherited from, the base control but unlike context menu of standard VScrollBar and HSrollBar is fully customizable. You can intercept Opening events and modify context menu before display or simply replace context menu with your own.

EndValue

Together with Value property it defines range for which scrollbar is defined. EndValue is defined of ValueRangeScrollBarBookmark only.

InitialDelay

Standard VScrollBar has one cool feature I wanted to reproduce. When you keep the left mouse button in down position it repeats click action without you actually clicking. This behavior starts after holding mouse down for interval defined in milliseconds in InitialDelay property. Value of InitialDelay is usually bigger than RepeatInterval. Default value is 400 milliseconds.

Orientation

Enumerator defining if ScrollBarEnhanced behaves like vertical or horizontal scrollbar.

QuickToolbarNavigtion

if set to true, allows quick navigation to bookmarked values by clicking bookmark graphical representation.

RepeatInterval

After auto-repeat behavior is triggered by holding mouse down for InitialDelay milliseconds, all subsequent auto-generated clicks occur in intervals defined in RepeatInerval. Default value is 62 milliseconds.

ShowTooltipOnMouseMove

If this property set to true, every time when user is moving mouse over scrollbar track, tooltip will be displayed. By default tooltip text shows value mouse is passing over. Tooltip text can be overwritten by host code by handling TooltipNeeded event by changing ToolTip property of event arguments object passed to the event handler.

Value, Minimum, Maximum, SmallChage, LargeChage

Properties have the same meaning as in standard VScrollBar or HScrollBar control but now all have type of decimal.

Enhanced Events:

There three new events defined in ScrollBarEnhanced that are not present is standard VScrollBar and HScrollBar:

Event

Description

OrienationChanged

Fires every time Orientation property of ScrollBarEnhanced changes.

OrientationChanging

Fires every time value of Orientation property is about to change. This is cancellable event.

ToolTipNeeded

I wanted to be able to capture all situations when scrollbar needs to display tooltip, and be able to either use default tooltip value or change it on the fly.

Here is a short description of all events defined in ScrollBarEnhanced:

Event

Description

MouseClick

This event occurs every time mouse is clicked in the scrollbar trackbar area. This event is identical to MouseClick of VScrollBar or HScrollBar.

MouseMove

This event occurs every time mouse moves over ScrollBarEnhanced control . See EnhancedMouseEventArgs for detailed information about argument passed to the event handler.

OrientationChanging

This event occurs every tine orientation of ScrollBarEnhanced is about to change. User has the opportunity to cancel change of Orientation property value.

OrientaionChanged

This notification happens every time after orientation property changes.

Scroll

Mimics Scroll event of standard VScrollBar and HScrollBar. See EnhancedScrollEventArgs for detailed information about argument passed to the event handler.

TooltipNeeded

This event is fired every time mouse moves over trackbar area or over bookmark marker (in order for this event to be fired, ShowToooltipOnMouseMove property has to be set to true). By handling this event, you can modify default tooltip value. See ToolTipNeededEventArgs for detailed information about argument passed to the event handler.

ValueChanged

Occurs every time scrollbar value changes. This event is identical to standard VScrollBar or HScrollBar ValueChanged event.

Enhanced Event Arguments

EnhancedMouseEventArgs - This object is used to pass information to MouseMove and MouseClick event handlers. Please take a look at Bookmarks property of this event. It is collection. Reason for this is the fact that one single vertical pixel of ScrollBarEnhanced can be mapped to multiple bookmarks. First, nothing stops you from defining multiple Boookmarks for the same ScrollBarEnhanced value. Second, even if you would be protected from assigning multiple bookmarks for the same value, you still might end up with multiple bookmarks displayed over same ScrollBar pixel. Bookmarks on the list are displayed in the same order as they occur on the list of Bookmarks property. Last element is drawn last so on the display it appears to be on the top. Let's consider the following (a little bit extreme) example. You want to scroll through the entire content of physical drive of 1Tb (Terabyte) size (~1012 bytes). Let's assume that you are going to show 100 bytes in one line of display. This means that you need to set ScrollbarEnhanced Maximum to 1012/100=1010) - that is how many lines you want to scroll through. Finally, assume that your ScrollBarEnhanced control is displayed with 1000 vertical pixels on the track bar. That means that you have to map <0, 1010> of ScrollBarEnhanced address space to <0, 1000> pixels of display. Therefore, 1 pixel will be mapped to 1010/1000= 107 (10 Millions) values. So even if you set one bookmark at 0 value and another one at 5,000,000, both bookmarks will be displayed at the same point on the screen.

EnhancedScrollEventArgs - This definition is almost identical to ScrollEventArs used in VScrollBar. Only difference is that OldValue and NewValue are decimal not int.

public class EnhancedMouseEventArgs:MouseEventArgs
{
    public EnhancedMouseEventArgs(decimal Value, MouseEventArgs MouseArgs,
           List<ScrollBarBookmark> Bookmarks,
           EnhancedScrollBarMouseLocation ScrollBarSection )
           :base(MouseArgs.Button, MouseArgs.Clicks, MouseArgs.X, MouseArgs.Y,
           MouseArgs.Delta)
    {
        this.Value = Value;
        this.Bookmarks = Bookmarks;
        this.ScrollBarSection = ScrollBarSection;
    }
    public decimal Value {private set; get;}
    public List<ScrollBarBookmark> Bookmarks {private set; get;}
    public EnhancedScrollBarMouseLocation ScrollBarSection { private set; get; }
}

ToolTipNeededEventArgs - used for ToolTipNeeded event. It passes extended information about point of the ScrollBarEnhanced that needs tooltip. ToolTipNeededEventArgs defines the following properties:

public class TooltipNeededEventArgs : EventArgs
{
    public TooltipNeededEventArgs(decimal Value, string ToolTip,
    List<ScrollBarBookmark> Bookmarks)
    {
        this.Value=Value;
        this.ToolTip=ToolTip;
        this.Bookmarks = Bookmarks;
    }
    public decimal Value { private set; get; }
    public string ToolTip {set; get;}
    public List<ScrollBarBookmark> Bookmarks { set; get; }
}
public decimal OldValue {private set; get;}
public decimal NewValue {private set; get;}
    public ScrollOrientation ScrollOrientation {private set; get;}
    public ScrollEventType Type {private set; get;}
	
	
}

Notes

//Following are valid assignments for Minimum and Maximum
Minimum = 0;
Maximum  = decimal.MaxValue;
//Following is valid too
Minimum = deximal.MinValue/2+1;
Maximum = decimal.MaxValue/2;
//The following will throw OverflowException (because decimal.MaxValue+1>decimal.MaxValue)
Minimum = -1;
Maximum= decimal.MaxValue; 

Demo Program

The downloadable demo program illustrates how to use ScrollBarEnhanced control in your code. It doesn't require much explanation. From the program GUI, you can modify all properties of instance of ScrollBarEnhanced control (scrollbar is displayed on the central part of the form). All added and modified properties are grouped in Enhanced category. I did it only to make the demo program easier to navigate since all enhanced properties will be displayed next to each other on the property grid. You can of course change property definition and change category attribute to more logical value. In fact, they all should belong to Behavior category. GUI also captures and displays all enhanced events fired by the instance of ScrollBarEnhanced instance.

Downloadable zip file contains also help file (chm). Please note, that since you are downloading this file from the Internet, in order to use it you have to unblock it first. You can do it from Windows explorer: right_click on the help file, select 'Properties', click 'Unblock' button.


Home  bullet Products  bullet Downloads  bullet About Us  bullet Contact Us

Credit Card Logo