Click here to Skip to main content
Click here to Skip to main content

Owner-drawn trackbar(slider)

By , 30 Jan 2007
 

Sample Image - ColorSlider.gif

Introduction

This article presents owner-drawn trackbar control. Component is written entirely from scratch. All painting events are done by code. It’s got cool, modern look. The best thing is, however, the capability of changing slider’s thumb shape. It is done simply by providing appropriate graphics path.

Background (optional)

I always wanted to have cool slider for my audio player application. The best I could find here was Guinness4Strength's article. Unfortunately, I didn’t find it pretty enough, so I decided to write my own trackbar. Hopefully you like it.

Properties

Appearance:

  • ThumbSize - Gets or sets the size of the thumb
  • ThumbCustomShape - Gets or sets the thumb custom shape. Use ThumbRect property to determine bounding rectangle.
  • ThumbRoundRectSize - Gets or sets the size of the thumb round rectangle edges.
  • BorderRoundRectSize - Gets or sets the size of the border round rect.

Values:

  • Orientation - Gets or sets the orientation of Slider.
  • Value - Gets or sets the value of Slider.
  • Minimum - Gets or sets the minimum value.
  • Maximum - Gets or sets the maximum value.
  • SmallChange - Gets or sets trackbar's small change. It affects how to behave when directional keys are pressed
  • LargeChange - Gets or sets trackbar's large change. It affects how to behave when PageUp/PageDown keys are pressed

Behavior:

  • DrawFocusRectangle - Gets or sets a value indicating whether to draw focus rectangle.
  • DrawSemitransparentThumb - Gets or sets a value indicating whether to draw semitransparent thumb.
  • MouseEffects - Gets or sets whether mouse entry and exit actions have impact on how control look.
  • MouseWheelBarPartitions - Gets or sets the mouse wheel bar partitions.

Colors:

  • ThumbOuterColor - Gets or sets the thumb outer color.
  • ThumbInnerColor - Gets or sets the inner color of the thumb.
  • ThumbPenColor - Gets or sets the color of the thumb pen.
  • BarOuterColor - Gets or sets the outer color of the bar.
  • BarInnerColor - Gets or sets the inner color of the bar.
  • BarPenColor - Gets or sets the color of the bar pen.
  • ElapsedOuterColor - Gets or sets the outer color of the elapsed.
  • ElapsedInnerColor - Gets or sets the inner color of the elapsed.

Points of Interest

This control will provide design-time support. Next version should contain custom properties editors.

History

  • 30.01.2007 - first version.
  • License

    This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

    About the Author

    Michal Brylka
    Architect Nokia Siemens Networks
    Poland Poland
    Member
    Michał is C# and whole .NET enthusiast. He graduated from computer science MSc studies at Wroclaw University of Technology, Poland.
     
    He is interested in photography and diving. He is member of PADI, currently with divemaster certificate.

    His favorite movies are Matrix, Amélie(Le Fabuleux Destin d'Amélie Poulain), Stargate SG-1 TV Serie and comedies of Mel Brooks.
     
    Michał lives in Wroclaw, Poland. To contact Michał, email him at michal.brylka[mail-'"at'"-sign]op.pl.

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    You must Sign In to use this message board.
    Search this forum  
        Spacing  Noise  Layout  Per page   
    SuggestionGreat control - some suggestionsmemberdr_thomas1 May '13 - 4:01 
    Liked your slider and am using it. Have some suggestions.
    Instead on OnKeyUp, use OnKeyDown. That way, if the user holds down the arrow keys or page up/down, the slider will continue to move. Also, ScrollEventArgs has a property called OldValue, which currently isn't being populated. It would be nice to add that. Thanks again!
    Don Thomas

    QuestionthumbCustomShapememberUltiblade11 Mar '13 - 3:54 
    I was looking for a good slider replacement and found yours. It works really great, thanks ! I do have a little question: playing around with the custom thumb shape, i noticed that it is always drawn from a fixed point. For example: you cannot create a thumb that has the height of the trackbar without it shifting to the top of the controls bounds. I found that the problem has something to do with the line :
    m.Translate(thumbRect.Left - thumbPath.GetBounds().Left, thumbRect.Top - thumbPath.GetBounds().Top);
    If i offset the thumRect.top a bit, the offset from the top changes. Do you have any ideas on how the code should be altered to avoid drawing from zero ??
    Best regards, ub
    QuestionVertical orientation - reversedmemberthewampek5 Feb '13 - 5:09 
    Anyone managed to reverse the slider on vertical orientation? Max value should be up and min value at bottom. Just 180 degree around.
     
    Thank you.
    SuggestionAdding ColorSlider to the VB ToolBoxmemberRavinduL27 Dec '12 - 20:37 
    Hello,
    Yes, the ColorSlider is a very nice variation of the TrackBar. You can add that as an element to the Visual Basic toolbox. Heres how;
     
    1. Download the 'demo project (binary only)' which is 24 kb is size.
    ► You download that as a WinRAR zip archive so, you need to have an archiving program to extract it to your computer.
    ► There will be 2 files in the archive.
    ► One is an application (.exe (executable)) and the other is a .dll file.
    ► Note that when you delete the .dll file, the application does not work.
     
    2. Add it to your VB toolbox.
    ► To do this, open Visual Basic, create a new project and dock the whole program to a side.
    ► Next go to the place you extracted the 'demo project (binary only)' 24 kb archive.
    ► Make sure the VB toolbox is Visible.
    ► Drag & Drop the .dll file to your VB toolbox. Then, a new element names 'ColorSlider' will appear.
    ► You can now customize, and use this on your projects.
    Name - Ravindu Liyanapathirana
     
    Website - http://tech20000.net.ms
    YouTube channel - http://www.youtube.com/user/Technological20000
     
    Channel E-mail - admin@tech20000.net.ms
    Personal E-mail - rliyanapathirana6@gmail.com

    Questionimage as pen?memberAndres Santillan20 Sep '12 - 18:01 
    first and foremost great control worked right off the bat..I just have a quick question is there a way to use an image as the thumb pen you know the one that is clicked and moved back and forth? If it's not too much to ask if you could show me if it's possible I would greatly appreciate it! Great job though let me just say that again Smile | :)
    GeneralMy vote of 5memberMember 90334004 Jun '12 - 6:04 
    Great control. A bit more commenting would be helpful for those new to C# but overall very high quality
    QuestionNice work thanks. My vote is 5memberIssaharNoam11 Jan '12 - 22:18 
    Hi,
    My vote is 5.
    I have application that I supply to client.
    What are the reuse conditions of this code?
    I am not a lawyer so I do not understand the license document Smile | :)
    Sorry
     
    Noam
    QuestionPanel scrolls on mouse wheel before trackbarmemberhowardfarrar27 Sep '10 - 6:21 
    Hi
     
    Great control, but I have a slight problem when I put several into a Panel container which has a scrollbar. It looks like the panel takes priority of the mouse wheel so that the panel scrolls instead of the trackbar. Once the panel slider has reached the end of its travel, it then moves the trackbar.
     
    Is there a way of reversing the wheel scrolling priority so that the trackbar moves before the Panel does?
    AnswerRe: Panel scrolls on mouse wheel before trackbarmemberhowardfarrar28 Sep '10 - 1:13 
    I've managed to solve it
     
    adding ((HandledMouseEventArgs)e).Handled = true; at the end of OnMouseWheel() stopped the message getting back to the panel
     
    Smile | :)
    GeneralMy vote of 5memberXmen W.K.16 Jul '10 - 15:48 
    Very nice, still some morons voted it 2 or 3.
     
    5 from me. Thanks for share.
    Generalgood controlmembersecurigy19 Jun '10 - 0:29 
    great performace. seems like what I needed, except I have no idea how to change the trackbar thumb to the image that I have stored in the .png file/project resources... for me it is a must, since it should indicate volume...any ideas? the code in the example seem drawing it by itself based on some math functions...
    GeneralVery cool, small addition I did for myselfmemberIssaharNoam22 Mar '09 - 0:38 
    Thanks for this good implementation.
    I did small change in order to allow fully hide the border. In following case in mouse over event, I found that transparent border appeared because was lightened.
     
    Here is my fix for myself
    public static Color[] LightenColors(params Color[] colorsToLighten)
            {
                Color[] colorsToReturn = new Color[colorsToLighten.Length];
                for (int i = 0; i < colorsToLighten.Length; i++)
                {
                    if(colorsToLighten[i]==Color.FromKnownColor(KnownColor.Transparent))
                        colorsToReturn[i] = colorsToLighten[i];
                    else
                        colorsToReturn[i] = ControlPaint.Light(colorsToLighten[i]);
                }
                return colorsToReturn;
            }

    GeneralRe: Very cool, small addition I did for myselfmemberXmen W.K.16 Jul '10 - 15:50 
     if(colorsToLighten[i] == Colors.Transparent))
     
    or
     
     if(colorsToLighten[i].A == 0))
     
    you don't need to make it complicated


    TVMU^P[[IGIOQHG^JSH`A#@`RFJ\c^JPL>;"[,*/|+&WLEZGc`AFXc!L
    %^]*IRXD#@GKCQ`R\^SF_WcHbORY87֦ʻ6ϣN8ȤBcRAV\Z^&SU~%CSWQ@#2
    W_AD`EPABIKRDFVS)EVLQK)JKQUFK[M`UKs*$GwU#QDXBER@CBN%
    R0~53%eYrd8mt^7Z6]iTF+(EWfJ9zaK-i’TV.C\y<pŠjxsg-b$f4ia>
    -----------------------------------------------
    128 bit encrypted signature, crack if you can

    Questionorientation slider value reversedmemberTVW036 Mar '09 - 12:11 
    when setting the orientation of the control to vertical, the max value is at the bottom instead of at the top. it's just 180() to what you would expect a normal slider control to be set to in a vertical environment. I am not a great C# coder so can you point me in the right direction to where i can fix this?
    thanks! and Awesome control by the way.
    AnswerRe: orientation slider value reversed [modified]membertgpfarm11027 Mar '09 - 14:30 
    yeah I need this also.
    Though a hack you can do is (100 - colorSlider.Value)
     
    modified on Saturday, March 7, 2009 9:09 PM

    AnswerRe: orientation slider value reversedmemberMichal Brylka8 Mar '09 - 8:57 
    At this point changing that would not be trivial. So it is best to hack it so that instead of using Value property you use (Maximum-Value)
     
    Michał Bryłka
     
    Theory is when you know something, but it doesn't work.
    Practice is when something works, but you don't know why.
    Programmers combine theory and practice: Nothing works and they don't know why.

    GeneralBrilliant implementation! Following slight change I did for myselfmemberIssaharNoam23 Feb '09 - 0:42 
    I added the HideOuterRegion property to extend the inner area for the whole control.
    In DrawColorSlider method, I check if this property is true and if yes, I don't inflate the barRect in every orientation.
     

     

    Thanks for great article!
    Issahar
    GeneralRe: Brilliant implementation! Following slight change I did for myselfmemberMichal Brylka8 Mar '09 - 8:42 
    you're welcome Smile | :)
     
    Michał Bryłka
     
    Theory is when you know something, but it doesn't work.
    Practice is when something works, but you don't know why.
    Programmers combine theory and practice: Nothing works and they don't know why.

    GeneralFantastic!member-Sean-20 Feb '09 - 11:38 
    Really great job! Love it, this is one control that really lacks in win forms!
     
    Cheers! Big Grin | :-D Thumbs Up | :thumbsup:
    GeneralRe: Fantastic!memberMichal Brylka8 Mar '09 - 6:36 
    Thanx Smile | :)
     
    Michał Bryłka
     
    Theory is when you know something, but it doesn't work.
    Practice is when something works, but you don't know why.
    Programmers combine theory and practice: Nothing works and they don't know why.

    QuestionConversion to VB?membershalan9918 Oct '07 - 22:59 
    Hi Michal, this is absolutely brilliant and exactly what I was looking for!! Well done! My application is in VB. Could I just place the dll in my solution and reference it or would I need a VB version of the component class?
     
    I tried converting but there are numerous errors! Sniff | :^)
    GeneralRe: Conversion to VB?memberMichal Brylka22 Feb '08 - 2:50 
    hi,
     
    you only need to extract control source to separate C# library and then add reference to it in your VB project
     
    Regards
     
    Michal Brylka
     
    Theory is when you know something, but it doesn't work.
    Practice is when something works, but you don't know why.
    Programmers combine theory and practice: Nothing works and they don't know why.

    GeneralSlight improvementsmemberJeromeHordies16 Sep '07 - 5:07 
    Good job !
    In order to use it in my application i made 2 small modifs:
    - I fired the Scroll event after the OnMouse_Wheel
    - I added the support for Image Thumb
     
    Here is the changed code of ColorSlider.cs:
     
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
     
    namespace MB.Controls
    {
          /// <summary>
          /// Encapsulates control that visualy displays certain integer value and allows user to change it within desired range. It imitates <see cref="System.Windows.Forms.TrackBar"/> as far as mouse usage is concerned.
          /// </summary>
          [ToolboxBitmap(typeof(TrackBar))]
          [DefaultEvent("Scroll"), DefaultProperty("BarInnerColor")]
          public partial class ColorSlider : Control
          {
                #region Events
     
                /// <summary>
                /// Fires when Slider position has changed
                /// </summary>
                [Description("Event fires when the Value property changes")]
                [Category("Action")]
                public event EventHandler ValueChanged;
     
                /// <summary>
                /// Fires when user scrolls the Slider
                /// </summary>
                [Description("Event fires when the Slider position is changed")]
                [Category("Behavior")]
                public event ScrollEventHandler Scroll;
     
                #endregion
     
                #region Properties
     
                private Rectangle thumbRect; //bounding rectangle of thumb area
                /// <summary>
                /// Gets the thumb rect. Usefull to determine bounding rectangle when creating custom thumb shape.
                /// </summary>
                /// <value>The thumb rect.</value>
                [Browsable(false)]
                public Rectangle ThumbRect
                {
                      get { return thumbRect; }
                }
     
                private Rectangle barRect; //bounding rectangle of bar area
                private Rectangle barHalfRect;
                private Rectangle thumbHalfRect;
                private Rectangle elapsedRect; //bounding rectangle of elapsed area
     
                private int thumbSize = 15;
                /// <summary>
                /// Gets or sets the size of the thumb.
                /// </summary>
                /// <value>The size of the thumb.</value>
                /// <exception cref="T:System.ArgumentOutOfRangeException">exception thrown when value is lower than zero or grather than half of appropiate dimension</exception>
                [Description("Set Slider thumb size")]
                [Category("ColorSlider")]
                [DefaultValue(15)]
                public int ThumbSize
                {
                      get { return thumbSize; }
                      set
                      {
                            if (value > 0 &
                                  value < (barOrientation == Orientation.Horizontal ? ClientRectangle.Width : ClientRectangle.Height))
                                  thumbSize = value;
                            else
                                  throw new ArgumentOutOfRangeException(
                                        "TrackSize has to be greather than zero and lower than half of Slider width");
                            Invalidate();
                      }
                }
     
                private GraphicsPath thumbCustomShape = null;
                /// <summary>
                /// Gets or sets the thumb custom shape. Use ThumbRect property to determine bounding rectangle.
                /// </summary>
                /// <value>The thumb custom shape. null means default shape</value>
                [Description("Set Slider's thumb's custom shape")]
                [Category("ColorSlider")]
                [Browsable(false)]
                [DefaultValue(typeof(GraphicsPath), "null")]
                public GraphicsPath ThumbCustomShape
                {
                      get { return thumbCustomShape; }
                      set
                      {
                            thumbCustomShape = value;
                            thumbSize = (int) (barOrientation == Orientation.Horizontal ? value.GetBounds().Width : value.GetBounds().Height) + 1;
                            Invalidate();
                      }
                }
     
                private Size thumbRoundRectSize = new Size(8, 8);
                /// <summary>
                /// Gets or sets the size of the thumb round rectangle edges.
                /// </summary>
                /// <value>The size of the thumb round rectangle edges.</value>
                [Description("Set Slider's thumb round rect size")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Size), "8; 8")]
                public Size ThumbRoundRectSize
                {
                      get { return thumbRoundRectSize; }
                      set
                      {
                            int h = value.Height, w = value.Width;
                            if (h <= 0) h = 1;
                            if (w <= 0) w = 1;
                            thumbRoundRectSize = new Size(w, h);
                            Invalidate();
                      }
                }
     
                private Size borderRoundRectSize = new Size(8, 8);
                /// <summary>
                /// Gets or sets the size of the border round rect.
                /// </summary>
                /// <value>The size of the border round rect.</value>
                [Description("Set Slider's border round rect size")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Size), "8; 8")]
                public Size BorderRoundRectSize
                {
                      get { return borderRoundRectSize; }
                      set
                      {
                            int h = value.Height, w = value.Width;
                            if (h <= 0) h = 1;
                            if (w <= 0) w = 1;
                            borderRoundRectSize = new Size(w, h);
                            Invalidate();
                      }
                }
     
                private Orientation barOrientation = Orientation.Horizontal;
                /// <summary>
                /// Gets or sets the orientation of Slider.
                /// </summary>
                /// <value>The orientation.</value>
                [Description("Set Slider orientation")]
                [Category("ColorSlider")]
                [DefaultValue(Orientation.Horizontal)]
                public Orientation Orientation
                {
                      get { return barOrientation; }
                      set
                      {
                            if (barOrientation != value)
                            {
                                  barOrientation = value;
                                  int temp = Width;
                                  Width = Height;
                                  Height = temp;
                                  if (thumbCustomShape != null)
                                        thumbSize =
                                              (int)
                                              (barOrientation == Orientation.Horizontal
                                                    ? thumbCustomShape.GetBounds().Width
                                                    : thumbCustomShape.GetBounds().Height) + 1;
                                  Invalidate();
                            }
                      }
                }
     

                private int trackerValue = 50;
                /// <summary>
                /// Gets or sets the value of Slider.
                /// </summary>
                /// <value>The value.</value>
                /// <exception cref="T:System.ArgumentOutOfRangeException">exception thrown when value is outside appropriate range (min, max)</exception>
                [Description("Set Slider value")]
                [Category("ColorSlider")]
                [DefaultValue(50)]
                public int Value
                {
                      get { return trackerValue; }
                      set
                      {
                            if (value >= barMinimum & value <= barMaximum)
                            {
                                  trackerValue = value;
                                  if (ValueChanged != null) ValueChanged(this, new EventArgs());
                                  Invalidate();
                            }
                            else throw new ArgumentOutOfRangeException("Value is outside appropriate range (min, max)");
                      }
                }
     

                private int barMinimum = 0;
                /// <summary>
                /// Gets or sets the minimum value.
                /// </summary>
                /// <value>The minimum value.</value>
                /// <exception cref="T:System.ArgumentOutOfRangeException">exception thrown when minimal value is greather than maximal one</exception>
                [Description("Set Slider minimal point")]
                [Category("ColorSlider")]
                [DefaultValue(0)]
                public int Minimum
                {
                      get { return barMinimum; }
                      set
                      {
                            if (value < barMaximum)
                            {
                                  barMinimum = value;
                                  if (trackerValue < barMinimum)
                                  {
                                        trackerValue = barMinimum;
                                        if (ValueChanged != null) ValueChanged(this, new EventArgs());
                                  }
                                  Invalidate();
                            }
                            else throw new ArgumentOutOfRangeException("Minimal value is greather than maximal one");
                      }
                }
     

                private int barMaximum = 100;
                /// <summary>
                /// Gets or sets the maximum value.
                /// </summary>
                /// <value>The maximum value.</value>
                /// <exception cref="T:System.ArgumentOutOfRangeException">exception thrown when maximal value is lower than minimal one</exception>
                [Description("Set Slider maximal point")]
                [Category("ColorSlider")]
                [DefaultValue(100)]
                public int Maximum
                {
                      get { return barMaximum; }
                      set
                      {
                            if (value > barMinimum)
                            {
                                  barMaximum = value;
                                  if (trackerValue > barMaximum)
                                  {
                                        trackerValue = barMaximum;
                                        if (ValueChanged != null) ValueChanged(this, new EventArgs());
                                  }
                                  Invalidate();
                            }
                            else throw new ArgumentOutOfRangeException("Maximal value is lower than minimal one");
                      }
                }
     
                private uint smallChange = 1;
                /// <summary>
                /// Gets or sets trackbar's small change. It affects how to behave when directional keys are pressed
                /// </summary>
                /// <value>The small change value.</value>
                [Description("Set trackbar's small change")]
                [Category("ColorSlider")]
                [DefaultValue(1)]
                public uint SmallChange
                {
                      get { return smallChange; }
                      set { smallChange = value; }
                }
     
                private uint largeChange = 5;
     
                /// <summary>
                /// Gets or sets trackbar's large change. It affects how to behave when PageUp/PageDown keys are pressed
                /// </summary>
                /// <value>The large change value.</value>
                [Description("Set trackbar's large change")]
                [Category("ColorSlider")]
                [DefaultValue(5)]
                public uint LargeChange
                {
                      get { return largeChange; }
                      set { largeChange = value; }
                }
     
                private bool drawFocusRectangle = true;
                /// <summary>
                /// Gets or sets a value indicating whether to draw focus rectangle.
                /// </summary>
                /// <value><c>true</c> if focus rectangle should be drawn; otherwise, <c>false</c>.</value>
                [Description("Set whether to draw focus rectangle")]
                [Category("ColorSlider")]
                [DefaultValue(true)]
                public bool DrawFocusRectangle
                {
                      get { return drawFocusRectangle; }
                      set
                      {
                            drawFocusRectangle = value;
                            Invalidate();
                      }
                }
     
                private bool drawSemitransparentThumb = true;
                /// <summary>
                /// Gets or sets a value indicating whether to draw semitransparent thumb.
                /// </summary>
                /// <value><c>true</c> if semitransparent thumb should be drawn; otherwise, <c>false</c>.</value>
                [Description("Set whether to draw semitransparent thumb")]
                [Category("ColorSlider")]
                [DefaultValue(true)]
                public bool DrawSemitransparentThumb
                {
                      get { return drawSemitransparentThumb; }
                      set
                      {
                            drawSemitransparentThumb = value;
                            Invalidate();
                      }
                }
     
                private bool mouseEffects = true;
                /// <summary>
                /// Gets or sets whether mouse entry and exit actions have impact on how control look.
                /// </summary>
                /// <value><c>true</c> if mouse entry and exit actions have impact on how control look; otherwise, <c>false</c>.</value>
                [Description("Set whether mouse entry and exit actions have impact on how control look")]
                [Category("ColorSlider")]
                [DefaultValue(true)]
                public bool MouseEffects
                {
                      get { return mouseEffects; }
                      set
                      {
                            mouseEffects = value;
                            Invalidate();
                      }
                }
     
                private int mouseWheelBarPartitions = 10;
                /// <summary>
                /// Gets or sets the mouse wheel bar partitions.
                /// </summary>
                /// <value>The mouse wheel bar partitions.</value>
                /// <exception cref="T:System.ArgumentOutOfRangeException">exception thrown when value isn't greather than zero</exception>
                [Description("Set to how many parts is bar divided when using mouse wheel")]
                [Category("ColorSlider")]
                [DefaultValue(10)]
                public int MouseWheelBarPartitions
                {
                      get { return mouseWheelBarPartitions; }
                      set
                      {
                            if (value > 0)
                                  mouseWheelBarPartitions = value;
                            else throw new ArgumentOutOfRangeException("MouseWheelBarPartitions has to be greather than zero");
                      }
                }
     
                private Image thumbImage = null;
                /// <summary>
                /// Gets or sets the Image use to render the thumb.
                /// </summary>
                /// <value>the thumb Image</value>  
                [Description("Set to use a specific Image for the thumb")]
                [Category("ColorSlider")]
                [DefaultValue(null)]
                public Image ThumbImage
                {
                      get { return thumbImage; }
                      set
                      {
                            if (value !=null )
                            {
                                  thumbImage = value;
                            }
                      }
                }
               
                private Color thumbOuterColor = Color.White;
                /// <summary>
                /// Gets or sets the thumb outer color .
                /// </summary>
                /// <value>The thumb outer color.</value>
                [Description("Set Slider thumb outer color")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Color), "White")]
                public Color ThumbOuterColor
                {
                      get { return thumbOuterColor; }
                      set
                      {
                            thumbOuterColor = value;
                            Invalidate();
                      }
                }
     

                private Color thumbInnerColor = Color.Gainsboro;
                /// <summary>
                /// Gets or sets the inner color of the thumb.
                /// </summary>
                /// <value>The inner color of the thumb.</value>
                [Description("Set Slider thumb inner color")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Color), "Gainsboro")]
                public Color ThumbInnerColor
                {
                      get { return thumbInnerColor; }
                      set
                      {
                            thumbInnerColor = value;
                            Invalidate();
                      }
                }
     

                private Color thumbPenColor = Color.Silver;
                /// <summary>
                /// Gets or sets the color of the thumb pen.
                /// </summary>
                /// <value>The color of the thumb pen.</value>
                [Description("Set Slider thumb pen color")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Color), "Silver")]
                public Color ThumbPenColor
                {
                      get { return thumbPenColor; }
                      set
                      {
                            thumbPenColor = value;
                            Invalidate();
                      }
                }
     

                private Color barOuterColor = Color.SkyBlue;
                /// <summary>
                /// Gets or sets the outer color of the bar.
                /// </summary>
                /// <value>The outer color of the bar.</value>
                [Description("Set Slider bar outer color")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Color), "SkyBlue")]
                public Color BarOuterColor
                {
                      get { return barOuterColor; }
                      set
                      {
                            barOuterColor = value;
                            Invalidate();
                      }
                }
     

                private Color barInnerColor = Color.DarkSlateBlue;
                /// <summary>
                /// Gets or sets the inner color of the bar.
                /// </summary>
                /// <value>The inner color of the bar.</value>
                [Description("Set Slider bar inner color")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Color), "DarkSlateBlue")]
                public Color BarInnerColor
                {
                      get { return barInnerColor; }
                      set
                      {
                            barInnerColor = value;
                            Invalidate();
                      }
                }
     

                private Color barPenColor = Color.Gainsboro;
                /// <summary>
                /// Gets or sets the color of the bar pen.
                /// </summary>
                /// <value>The color of the bar pen.</value>
                [Description("Set Slider bar pen color")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Color), "Gainsboro")]
                public Color BarPenColor
                {
                      get { return barPenColor; }
                      set
                      {
                            barPenColor = value;
                            Invalidate();
                      }
                }
     
                private Color elapsedOuterColor = Color.DarkGreen;
                /// <summary>
                /// Gets or sets the outer color of the elapsed.
                /// </summary>
                /// <value>The outer color of the elapsed.</value>
                [Description("Set Slider's elapsed part outer color")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Color), "DarkGreen")]
                public Color ElapsedOuterColor
                {
                      get { return elapsedOuterColor; }
                      set
                      {
                            elapsedOuterColor = value;
                            Invalidate();
                      }
                }
     
                private Color elapsedInnerColor = Color.Chartreuse;
                /// <summary>
                /// Gets or sets the inner color of the elapsed.
                /// </summary>
                /// <value>The inner color of the elapsed.</value>
                [Description("Set Slider's elapsed part inner color")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(Color), "Chartreuse")]
                public Color ElapsedInnerColor
                {
                      get { return elapsedInnerColor; }
                      set
                      {
                            elapsedInnerColor = value;
                            Invalidate();
                      }
                }
     
                #endregion
     
                #region Color schemas
     
                //define own color schemas
                private Color[,] aColorSchema = new Color[,]
                      {
                            {
                                  Color.White, Color.Gainsboro, Color.Silver, Color.SkyBlue, Color.DarkSlateBlue, Color.Gainsboro,
                                  Color.DarkGreen, Color.Chartreuse
                            },
                            {
                                  Color.White, Color.Gainsboro, Color.Silver, Color.Red, Color.DarkRed, Color.Gainsboro, Color.Coral,
                                  Color.LightCoral
                            },
                            {
                                  Color.White, Color.Gainsboro, Color.Silver, Color.GreenYellow, Color.Yellow, Color.Gold, Color.Orange,
                                  Color.OrangeRed
                            },
                            {
                                  Color.White, Color.Gainsboro, Color.Silver, Color.Red, Color.Crimson, Color.Gainsboro, Color.DarkViolet
                                  , Color.Violet
                            }
                      };
     
                public enum ColorSchemas
                {
                      PerlBlueGreen,
                      PerlRedCoral,
                      PerlGold,
                      PerlRoyalColors
                }
     
                private ColorSchemas colorSchema = ColorSchemas.PerlBlueGreen;
                /// <summary>
                /// Sets color schema. Color generalization / fast color changing. Has no effect when slider colors are changed manually after schema was applied.
                /// </summary>
                /// <value>New color schema value</value>
                [Description("Set Slider color schema. Has no effect when slider colors are changed manually after schema was applied.")]
                [Category("ColorSlider")]
                [DefaultValue(typeof(ColorSchemas), "PerlBlueGreen")]
                public ColorSchemas ColorSchema
                {
                      get { return colorSchema; }
                      set
                      {
                            colorSchema = value;
                            byte sn = (byte)value;
                            thumbOuterColor = aColorSchema[sn, 0];
                            thumbInnerColor = aColorSchema[sn, 1];
                            thumbPenColor = aColorSchema[sn, 2];
                            barOuterColor = aColorSchema[sn, 3];
                            barInnerColor = aColorSchema[sn, 4];
                            barPenColor = aColorSchema[sn, 5];
                            elapsedOuterColor = aColorSchema[sn, 6];
                            elapsedInnerColor = aColorSchema[sn, 7];
     
                            Invalidate();
                      }
                }
     
                #endregion
               
                #region Constructors
     
                /// <summary>
                /// Initializes a new instance of the <see cref="ColorSlider"/> class.
                /// </summary>
                /// <param name="min">The minimum value.</param>
                /// <param name="max">The maximum value.</param>
                /// <param name="value">The current value.</param>
                public ColorSlider(int min, int max, int value)
                {
                      InitializeComponent();
                      SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer |
                                  ControlStyles.ResizeRedraw | ControlStyles.Selectable |
                                  ControlStyles.SupportsTransparentBackColor | ControlStyles.UserMouse |
                                  ControlStyles.UserPaint, true);
                      BackColor = Color.Transparent;
     
                      Minimum = min;
                      Maximum = max;
                      Value = value;
                }
     
                /// <summary>
                /// Initializes a new instance of the <see cref="ColorSlider"/> class.
                /// </summary>
                public ColorSlider() : this(0, 100, 50) { }
     
                #endregion
     
                #region Paint
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.Paint"></see> event.
                /// </summary>
                /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"></see> that contains the event data.</param>
                protected override void OnPaint(PaintEventArgs e)
                {
                      if (!Enabled)
                      {
                            Color[] desaturatedColors = DesaturateColors(thumbOuterColor, thumbInnerColor, thumbPenColor,
                                                                                              barOuterColor, barInnerColor, barPenColor,
                                                                                              elapsedOuterColor, elapsedInnerColor);
                            DrawColorSlider(e, desaturatedColors[0], desaturatedColors[1], desaturatedColors[2],
                                                    desaturatedColors[3],
                                                    desaturatedColors[4], desaturatedColors[5], desaturatedColors[6], desaturatedColors[7]);
                      }
                      else
                      {
                            if (mouseEffects && mouseInRegion)
                            {
                                  Color[] lightenedColors = LightenColors(thumbOuterColor, thumbInnerColor, thumbPenColor,
                                                                                              barOuterColor, barInnerColor, barPenColor,
                                                                                              elapsedOuterColor, elapsedInnerColor);
                                  DrawColorSlider(e, lightenedColors[0], lightenedColors[1], lightenedColors[2], lightenedColors[3],
                                                          lightenedColors[4], lightenedColors[5], lightenedColors[6], lightenedColors[7]);
                            }
                            else
                            {
                                  DrawColorSlider(e, thumbOuterColor, thumbInnerColor, thumbPenColor,
                                                          barOuterColor, barInnerColor, barPenColor,
                                                          elapsedOuterColor, elapsedInnerColor);
                            }
                      }
                }
     
                /// <summary>
                /// Draws the colorslider control using passed colors.
                /// </summary>
                /// <param name="e">The <see cref="T:System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param>
                /// <param name="thumbOuterColorPaint">The thumb outer color paint.</param>
                /// <param name="thumbInnerColorPaint">The thumb inner color paint.</param>
                /// <param name="thumbPenColorPaint">The thumb pen color paint.</param>
                /// <param name="barOuterColorPaint">The bar outer color paint.</param>
                /// <param name="barInnerColorPaint">The bar inner color paint.</param>
                /// <param name="barPenColorPaint">The bar pen color paint.</param>
                /// <param name="elapsedOuterColorPaint">The elapsed outer color paint.</param>
                /// <param name="elapsedInnerColorPaint">The elapsed inner color paint.</param>
                private void DrawColorSlider(PaintEventArgs e, Color thumbOuterColorPaint, Color thumbInnerColorPaint,
                                                          Color thumbPenColorPaint, Color barOuterColorPaint, Color barInnerColorPaint,
                                                          Color barPenColorPaint, Color elapsedOuterColorPaint, Color elapsedInnerColorPaint)
                {
                      try
                      {
                            //set up thumbRect aproprietly
                            if (barOrientation == Orientation.Horizontal)
                            {
                                  int TrackX = (((trackerValue - barMinimum) * (ClientRectangle.Width - thumbSize)) / (barMaximum - barMinimum));
                                  thumbRect = new Rectangle(TrackX, 1, thumbSize - 1, ClientRectangle.Height - 3);
                            }
                            else
                            {
                                  int TrackY = (((trackerValue - barMinimum) * (ClientRectangle.Height - thumbSize)) / (barMaximum - barMinimum));
                                  thumbRect = new Rectangle(1, TrackY, ClientRectangle.Width - 3, thumbSize - 1);
                            }
     
                            //adjust drawing rects
                            barRect = ClientRectangle;
                            thumbHalfRect = thumbRect;
                            LinearGradientMode gradientOrientation;
                            if (barOrientation == Orientation.Horizontal)
                            {
                                  barRect.Inflate(-1, -barRect.Height / 3);
                                  barHalfRect = barRect;
                                  barHalfRect.Height /= 2;
                                  gradientOrientation = LinearGradientMode.Vertical;
                                  thumbHalfRect.Height /= 2;
                                  elapsedRect = barRect;
                                  elapsedRect.Width = thumbRect.Left + thumbSize / 2;
                            }
                            else
                            {
                                  barRect.Inflate(-barRect.Width / 3, -1);
                                  barHalfRect = barRect;
                                  barHalfRect.Width /= 2;
                                  gradientOrientation = LinearGradientMode.Horizontal;
                                  thumbHalfRect.Width /= 2;
                                  elapsedRect = barRect;
                                  elapsedRect.Height = thumbRect.Top + thumbSize / 2;
                            }
                            //get thumb shape path
                            GraphicsPath thumbPath;
                            if (thumbCustomShape == null)
                                  thumbPath = CreateRoundRectPath(thumbRect, thumbRoundRectSize);
                            else
                            {
                                  thumbPath = thumbCustomShape;
                                  Matrix m = new Matrix();
                                  m.Translate(thumbRect.Left - thumbPath.GetBounds().Left, thumbRect.Top - thumbPath.GetBounds().Top);
                                  thumbPath.Transform(m);
                            }
     
                            //draw bar
                            using (
                                  LinearGradientBrush lgbBar =
                                        new LinearGradientBrush(barHalfRect, barOuterColorPaint, barInnerColorPaint, gradientOrientation)
                                  )
                            {
                                  lgbBar.WrapMode = WrapMode.TileFlipXY;
                                  e.Graphics.FillRectangle(lgbBar, barRect);
                                  //draw elapsed bar
                                  using (
                                        LinearGradientBrush lgbElapsed =
                                              new LinearGradientBrush(barHalfRect, elapsedOuterColorPaint, elapsedInnerColorPaint,
                                                                                  gradientOrientation))
                                  {
                                        lgbElapsed.WrapMode = WrapMode.TileFlipXY;
                                        if (Capture && drawSemitransparentThumb)
                                        {
                                              Region elapsedReg = new Region(elapsedRect);
                                              elapsedReg.Exclude(thumbPath);
                                              e.Graphics.FillRegion(lgbElapsed, elapsedReg);
                                        }
                                        else
                                              e.Graphics.FillRectangle(lgbElapsed, elapsedRect);
                                  }
                                  //draw bar band                             
                                  using (Pen barPen = new Pen(barPenColorPaint, 0.5f))
                                  {
                                        e.Graphics.DrawRectangle(barPen, barRect);
                                  }
                            }
     
                            //draw thumb
                            Color newthumbOuterColorPaint = thumbOuterColorPaint, newthumbInnerColorPaint = thumbInnerColorPaint;
                            if (Capture && drawSemitransparentThumb)
                            {
                                  newthumbOuterColorPaint = Color.FromArgb(175, thumbOuterColorPaint);
                                  newthumbInnerColorPaint = Color.FromArgb(175, thumbInnerColorPaint);
                            }
                            using (
                                  LinearGradientBrush lgbThumb =
                                        new LinearGradientBrush(thumbHalfRect, newthumbOuterColorPaint, newthumbInnerColorPaint,
                                                                            gradientOrientation))
                            {
                                  lgbThumb.WrapMode = WrapMode.TileFlipXY;
                                  e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;                             
                                  //draw thumb band
                                  Color newThumbPenColor = thumbPenColorPaint;
                                  if (mouseEffects && (Capture || mouseInThumbRegion))
                                        newThumbPenColor = ControlPaint.Dark(newThumbPenColor);
                                  using (Pen thumbPen = new Pen(newThumbPenColor))
                                  {
                                        if (thumbImage != null)
                                        {
                                              e.Graphics.DrawImage(thumbImage, thumbRect);
                                        }
                                        else
                                        {
                                              e.Graphics.FillPath(lgbThumb, thumbPath);
                                              e.Graphics.DrawPath(thumbPen, thumbPath);
                                        }
                                  }
                                  //gp.Dispose();                             
                                  /*if (Capture || mouseInThumbRegion)
                                        using (LinearGradientBrush lgbThumb2 = new LinearGradientBrush(thumbHalfRect, Color.FromArgb(150, Color.Blue), Color.Transparent, gradientOrientation))
                                        {
                                              lgbThumb2.WrapMode = WrapMode.TileFlipXY;
                                              e.Graphics.FillPath(lgbThumb2, gp);
                                        }*/
                            }
     
                            //draw focusing rectangle
                            if (Focused & drawFocusRectangle)
                                  using (Pen p = new Pen(Color.FromArgb(200, barPenColorPaint)))
                                  {
                                        p.DashStyle = DashStyle.Dot;
                                        Rectangle r = ClientRectangle;
                                        r.Width -= 2;
                                        r.Height--;
                                        r.X++;
                                        //ControlPaint.DrawFocusRectangle(e.Graphics, r);                                   
                                        using (GraphicsPath gpBorder = CreateRoundRectPath(r, borderRoundRectSize))
                                        {
                                              e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                                              e.Graphics.DrawPath(p, gpBorder);
                                        }
                                  }
                      }
                      catch (Exception Err)
                      {
                            Console.WriteLine("DrawBackGround Error in " + Name + ":" + Err.Message);
                      }
                      finally
                      {
                      }
                }
     
                #endregion
     
                #region Overided events
     
                private bool mouseInRegion = false;
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.EnabledChanged"></see> event.
                /// </summary>
                /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
                protected override void OnEnabledChanged(EventArgs e)
                {
                      base.OnEnabledChanged(e);
                      Invalidate();
                }
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.MouseEnter"></see> event.
                /// </summary>
                /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
                protected override void OnMouseEnter(EventArgs e)
                {
                      base.OnMouseEnter(e);
                      mouseInRegion = true;
                      Invalidate();
                }
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.MouseLeave"></see> event.
                /// </summary>
                /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
                protected override void OnMouseLeave(EventArgs e)
                {
                      base.OnMouseLeave(e);
                      mouseInRegion = false;
                      mouseInThumbRegion = false;
                      Invalidate();
                }
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.MouseDown"></see> event.
                /// </summary>
                /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data.</param>
                protected override void OnMouseDown(MouseEventArgs e)
                {
                      base.OnMouseDown(e);
                      if (e.Button == MouseButtons.Left)
                      {
                            Capture = true;
                            if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.ThumbTrack, trackerValue));
                            if (ValueChanged != null) ValueChanged(this, new EventArgs());
                            OnMouseMove(e);
                      }
                }
     
                private bool mouseInThumbRegion = false;
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.MouseMove"></see> event.
                /// </summary>
                /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data.</param>
                protected override void OnMouseMove(MouseEventArgs e)
                {
                      base.OnMouseMove(e);
                      mouseInThumbRegion = IsPointInRect(e.Location, thumbRect);
                      if (Capture & e.Button == MouseButtons.Left)
                      {
                            ScrollEventType set = ScrollEventType.ThumbPosition;
                            Point pt = e.Location;
                            int p = barOrientation == Orientation.Horizontal ? pt.X : pt.Y;
                            int margin = thumbSize >> 1;
                            p -= margin;
                            float coef = (float)(barMaximum - barMinimum) /
                                              (float)
                                              ((barOrientation == Orientation.Horizontal ? ClientSize.Width : ClientSize.Height) -
                                                 2 * margin);
                            trackerValue = (int)(p * coef + barMinimum);
     
                            if (trackerValue <= barMinimum)
                            {
                                  trackerValue = barMinimum;
                                  set = ScrollEventType.First;
                            }
                            else if (trackerValue >= barMaximum)
                            {
                                  trackerValue = barMaximum;
                                  set = ScrollEventType.Last;
                            }
     
                            if (Scroll != null) Scroll(this, new ScrollEventArgs(set, trackerValue));
                            if (ValueChanged != null) ValueChanged(this, new EventArgs());
                      }
                      Invalidate();
                }
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp"></see> event.
                /// </summary>
                /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data.</param>
                protected override void OnMouseUp(MouseEventArgs e)
                {
                      base.OnMouseUp(e);
                      Capture = false;
                      mouseInThumbRegion = IsPointInRect(e.Location, thumbRect);
                      if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.EndScroll, trackerValue));
                      if (ValueChanged != null) ValueChanged(this, new EventArgs());
                      Invalidate();
                }
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.MouseWheel"></see> event.
                /// </summary>
                /// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"></see> that contains the event data.</param>
                protected override void OnMouseWheel(MouseEventArgs e)
                {
                      base.OnMouseWheel(e);
                      int v = e.Delta / 120 * (barMaximum - barMinimum) / mouseWheelBarPartitions;                 
                      SetProperValue(Value + v);
                      if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.EndScroll, trackerValue));
                }
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.GotFocus"></see> event.
                /// </summary>
                /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
                protected override void OnGotFocus(EventArgs e)
                {
                      base.OnGotFocus(e);
                      Invalidate();
                }
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.LostFocus"></see> event.
                /// </summary>
                /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
                protected override void OnLostFocus(EventArgs e)
                {
                      base.OnLostFocus(e);
                      Invalidate();
                }
     
                /// <summary>
                /// Raises the <see cref="E:System.Windows.Forms.Control.KeyUp"></see> event.
                /// </summary>
                /// <param name="e">A <see cref="T:System.Windows.Forms.KeyEventArgs"></see> that contains the event data.</param>
                protected override void OnKeyUp(KeyEventArgs e)
                {
                      base.OnKeyUp(e);
                      switch (e.KeyCode)
                      {
                            case Keys.Down:
                            case Keys.Left:
                                  SetProperValue(Value - (int)smallChange);
                                  if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.SmallDecrement, Value));
                                  break;
                            case Keys.Up:
                            case Keys.Right:
                                  SetProperValue(Value + (int)smallChange);
                                  if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.SmallIncrement, Value));
                                  break;
                            case Keys.Home:
                                  Value = barMinimum;
                                  break;
                            case Keys.End:
                                  Value = barMaximum;
                                  break;
                            case Keys.PageDown:
                                  SetProperValue(Value - (int)largeChange);
                                  if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.LargeDecrement, Value));
                                  break;
                            case Keys.PageUp:
                                  SetProperValue(Value + (int)largeChange);
                                  if (Scroll != null) Scroll(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, Value));
                                  break;
                      }
                      if (Scroll != null && Value == barMinimum) Scroll(this, new ScrollEventArgs(ScrollEventType.First, Value));
                      if (Scroll != null && Value == barMaximum) Scroll(this, new ScrollEventArgs(ScrollEventType.Last, Value));
                      Point pt = PointToClient(Cursor.Position);
                      OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, pt.X, pt.Y, 0));
                }
     
                /// <summary>
                /// Processes a dialog key.
                /// </summary>
                /// <param name="keyData">One of the <see cref="T:System.Windows.Forms.Keys"></see> values that represents the key to process.</param>
                /// <returns>
                /// true if the key was processed by the control; otherwise, false.
                /// </returns>
                protected override bool ProcessDialogKey(Keys keyData)
                {
                      if (keyData == Keys.Tab | ModifierKeys == Keys.Shift)
                            return base.ProcessDialogKey(keyData);
                      else
                      {
                            OnKeyDown(new KeyEventArgs(keyData));
                            return true;
                      }
                }
     
                #endregion
     
                #region Help routines
     
                /// <summary>
                /// Creates the round rect path.
                /// </summary>
                /// <param name="rect">The rectangle on which graphics path will be spanned.</param>
                /// <param name="size">The size of rounded rectangle edges.</param>
                /// <returns></returns>
                public static GraphicsPath CreateRoundRectPath(Rectangle rect, Size size)
                {
                      GraphicsPath gp = new GraphicsPath();
                      gp.AddLine(rect.Left + size.Width / 2, rect.Top, rect.Right - size.Width / 2, rect.Top);
                      gp.AddArc(rect.Right - size.Width, rect.Top, size.Width, size.Height, 270, 90);
     
                      gp.AddLine(rect.Right, rect.Top + size.Height / 2, rect.Right, rect.Bottom - size.Width / 2);
                      gp.AddArc(rect.Right - size.Width, rect.Bottom - size.Height, size.Width, size.Height, 0, 90);
     
                      gp.AddLine(rect.Right - size.Width / 2, rect.Bottom, rect.Left + size.Width / 2, rect.Bottom);
                      gp.AddArc(rect.Left, rect.Bottom - size.Height, size.Width, size.Height, 90, 90);
     
                      gp.AddLine(rect.Left, rect.Bottom - size.Height / 2, rect.Left, rect.Top + size.Height / 2);
                      gp.AddArc(rect.Left, rect.Top, size.Width, size.Height, 180, 90);
                      return gp;
                }
     
                /// <summary>
                /// Desaturates colors from given array.
                /// </summary>
                /// <param name="colorsToDesaturate">The colors to be desaturated.</param>
                /// <returns></returns>
                public static Color[] DesaturateColors(params Color[] colorsToDesaturate)
                {
                      Color[] colorsToReturn = new Color[colorsToDesaturate.Length];
                      for (int i = 0; i < colorsToDesaturate.Length; i++)
                      {
                            //use NTSC weighted avarage
                            int gray =
                                  (int)(colorsToDesaturate[i].R * 0.3 + colorsToDesaturate[i].G * 0.6 + colorsToDesaturate[i].B * 0.1);
                            colorsToReturn[i] = Color.FromArgb(-0x010101 * (255 - gray) - 1);
                      }
                      return colorsToReturn;
                }
     
                /// <summary>
                /// Lightens colors from given array.
                /// </summary>
                /// <param name="colorsToLighten">The colors to lighten.</param>
                /// <returns></returns>
                public static Color[] LightenColors(params Color[] colorsToLighten)
                {
                      Color[] colorsToReturn = new Color[colorsToLighten.Length];
                      for (int i = 0; i < colorsToLighten.Length; i++)
                      {
                            colorsToReturn[i] = ControlPaint.Light(colorsToLighten[i]);
                      }
                      return colorsToReturn;
                }
     
                /// <summary>
                /// Sets the trackbar value so that it wont exceed allowed range.
                /// </summary>
                /// <param name="val">The value.</param>
                private void SetProperValue(int val)
                {
                      if (val < barMinimum) Value = barMinimum;
                      else if (val > barMaximum) Value = barMaximum;
                      else Value = val;
                }
     
                /// <summary>
                /// Determines whether rectangle contains given point.
                /// </summary>
                /// <param name="pt">The point to test.</param>
                /// <param name="rect">The base rectangle.</param>
                /// <returns>
                ///      <c>true</c> if rectangle contains given point; otherwise, <c>false</c>.
                /// </returns>
                private static bool IsPointInRect(Point pt, Rectangle rect)
                {
                      if (pt.X > rect.Left & pt.X < rect.Right & pt.Y > rect.Top & pt.Y < rect.Bottom)
                            return true;
                      else return false;
                }
     
                #endregion
          }
    }
    GeneralRe: Slight improvementsmemberMichal Brylka14 Feb '08 - 17:43 
    Thanks, nice job Smile | :)
     
    Michal Brylka
     
    Theory is when you know something, but it doesn't work.
    Practice is when something works, but you don't know why.
    Programmers combine theory and practice: Nothing works and they don't know why.

    GeneralGreat controlmemberRoss_MacGregor25 Jul '07 - 8:59 
    This is an excellent control, thanks. I made two small changes for my project. The focus rectangle was being rendered too faintly so I needed to change its color. It may be useful to have its color as a separate color property. I also moved the focus rendering code before the knob rendering because the rectangle was being rendered on top of the knob which did not look right at all.
     
    Ever think of doing a good bitmap button control? I could use one of those too.

    GeneralMulitple TrackPointsmemberbizzysim6 Jul '07 - 9:36 
    Hey dude great control... is there a way to have multiple track points that you can slide on the same tab strip?
    GeneralRe: Mulitple TrackPointsmemberMichal Brylka6 Jul '07 - 10:26 
    yes, there is such possibility, I even wanted to implement such capability (ie. RangeBar), however I never had time to do so.
     
    Michał Bryłka

    NewsGreat Control - added ToolStrip supportmemberThomas-H.28 Jun '07 - 5:08 
    First of all thanks for your work. This is a very good Slidercontrol.
     
    I am in need for such a control for use in a toolbar. I tried different existing versions plus used ToolStripControlHost with TrackBar to implement one on my own but I either had performance issues (flickering, etc) or simply could not make the TrackBar leave overwriting the ToolStripBackground (even with transparent background).
     
    Finally I saw your control, took the code and inherited your control from ToolStripItem instead of Control. The few changes needed were made fast and now I got a pretty highly customizable slidercontrol .
     
    Thanks.
     

    P.S.: I would like to send you the changed code, but could not find your email.
    GeneralRe: Great Control - added ToolStrip support [modified]memberMichal Brylka28 Jun '07 - 7:34 
    Hi,
    nice to hear that somebody is interested in my control.
    If you'd like to send me your code, feel free to do so, I'd appreciate it; here is my email:
    michal.brylka[you-know-what-comes-here-at_sign]op.pl
     
    Regards and thanks in advance
     
    Michal Brylka
    modified on Friday, February 22, 2008 8:45 AM

    Generalyour control is very good,I want Two blocks in your control,memberfrequent30 May '07 - 18:55 
    sorry,my english is poor.
    your control is exactly what i was looking for.
    But i want this trackbar have two blocks to Restrictions a scope,i shoud how to modify your code?
    Thank you very much.
    GeneralRe: your control is very good,I want Two blocks in your control,memberMichal Brylka31 May '07 - 8:35 
    Yes, you can modify me code. Is this what you wanted permission for?
     
    Regards
     
    Michał Bryłka

    QuestionAccessiblity?memberZorbek5 Feb '07 - 21:59 
    Just wanted to spread my new acquited nighmare. Shouldn't all custom controls implement accessibility?
     
    /Xav

    AnswerRe: Accessiblity?memberMichal Brylka7 Feb '07 - 1:55 
    Yes, you're probably right. Any hint how to do that?
     
    Michał Bryłka

    GeneralRe: Accessiblity?memberZorbek7 Feb '07 - 13:06 
    Well, not realy... but I know in your components case it should be about defining interactive areas (like the large change click and the slider itself etc). And report their position, name and funtions. The technology exists and is easily implemented i Visual Studio 2003/2005.
     
    - Good luck!
     
    /Xav

    GeneralInteresting ideamemberPete O'Hanlon30 Jan '07 - 0:54 
    Well - an interesting idea, and well presented. Congratulations.
     
    Have you looked into WPF? If you could do this in WPF and post an article on it, then I for one would certainly be interested.
     
    Anyway, 5 out 5 from me.
     

    the last thing I want to see is some pasty-faced geek with skin so pale that it's almost translucent trying to bump parts with a partner - John Simmons / outlaw programmer

    Deja View - the feeling that you've seen this post before.

    GeneralRe: Interesting ideamemberMichal Brylka30 Jan '07 - 15:52 
    I'm installing Vista as soon as it is available at MSDN AA. I'll then take a glance at WPF. Hopefully I'll be able to catch with this technology.
     
    Michał Bryłka

    GeneralAdd few thing to become ultimate ;)memberThe Monz30 Jan '07 - 0:42 
    There are fiew things that could be done and which will put your fader into
    the ultimate fader I will soon code if not finding it...
     
    Theses functionnalities are :
     
    Able to set the image for the Background
    Able to set the image for the bar in the middle (define also its position)
    able to set a list of Tick... (this could allow us to put them where we want)
     
    Thanks
     
    The Monz, Toulouse, France

    GeneralRe: Add few thing to become ultimate ;)memberMichal Brylka7 Feb '07 - 2:05 
    I'll implement those 2 image-properties for sure. However I don't know if ticks are appropriate. This is slider rather trackbar control. But it definetly will be taken into consideration.
    What do you understand under "fader" ?
     
    Michał Bryłka

    GeneralRe: Add few thing to become ultimate ;)memberJ.e.e.P21 Apr '09 - 2:31 
    I also needed ticks so I changed DrawColorSlider-methods and used barPenColor to paint ticks:
     
                   //draw bar band  && ticks
                        using (Pen barPen = new Pen(barPenColorPaint, 0.5f))
                        {
                            e.Graphics.DrawRectangle(barPen, barRect);
     
                            int i = (int)LargeChange;
                            int y1 = barRect.Y;
                            int y2 = barRect.Bottom;
                            int width = barRect.Width;
                            while (i < Maximum)
                            {
                                int x = width * i / Maximum;
                                e.Graphics.DrawLine(barPen, x, y1, x, y2);
                                i += (int)LargeChange;
                            }
                        }

     
    Jeep can't code.
    Code can Jeep

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

    Permalink | Advertise | Privacy | Mobile
    Web02 | 2.6.130516.1 | Last Updated 30 Jan 2007
    Article Copyright 2007 by Michal Brylka
    Everything else Copyright © CodeProject, 1999-2013
    Terms of Use
    Layout: fixed | fluid