TrackBar component with two meters

1

I've created a trackbar component with 2 meters, plus when I manually render it in xaml , barra and marcadores misconfigure and barra goes up and marcadores goes by. Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace TrackBarDouble
{
    public partial class DoubleTrackbar : UserControl
    {        
        #region Internal Enumerator
        public enum Thumbs
        {
            None = 0,
            Left = 1,
            Right = 2,
        }
        #endregion

        #region Constructor

        public DoubleTrackbar()
        {
            InitializeComponent();
            this.AutoSize = true;
            this.DoubleBuffered = true;
            this.SetDefaults();
        }

        #endregion

        #region Declarations

        private int _minimum;
        private int _maximum;
        private int _valueRight;
        private int _valueLeft;
        public event EventHandler ValueChanged;
        public event EventHandler LeftValueChanged;
        public event EventHandler RightValueChanged;
        private TrackBarThumbState leftThumbState;
        private TrackBarThumbState rightThumbState;
        private bool draggingLeft, draggingRight;
        private Thumbs selectedThumb;

        #endregion

        #region Properties

        [Description("Orientação do Slider")]
        [DefaultValue(typeof(Orientation), "Horizontal")]
        public Orientation Orientation
        {
            get;
            set;
        }

        [Description("Valor de mudança mínima para cada seletor")]
        public int SmallChange
        {
            get;
            set;
        }

        [Description("Valor mínimo do trackbar")]
        public int Minimum
        {
            get { return _minimum; }[![inserir a descrição da imagem aqui][1]][1]
            set
            {
                if (value >= Maximum)
                    throw new ArgumentException(String.Format("Valor de '{0}' não é válido para 'Minimum'. 'Minimum' deve ser menor que 'Maximum'.", value.ToString()), "Minimum");
                _minimum = value;
                this.Invalidate();
            }
        }

        [Description("Valor máximo do trackbar")]
        public int Maximum
        {
            get { return _maximum; }
            set
            {
                if (value <= Minimum)
                    throw new ArgumentException(String.Format("Valor de '{0}' não é válido para 'Maximum'. 'Maximum' deve ser maior que 'Minimum'.", value.ToString()), "Maximum");
                _maximum = value;
                this.Invalidate();
            }
        }

        [Description("Valor do seletor direito")]
        public int ValueRight
        {
            get { return _valueRight; }
            set
            {
                if (((value < this.Minimum)
                        || (value > this.Maximum)))
                {
                    throw new ArgumentException(string.Format("Valor de \'{0}\' não é válido para \'ValueRight\'. \'ValueRight\' deve estar entre \'Minimum\' e \'Maximum\'.", value.ToString()), "ValueRight");
                }

                if ((value <= this.ValueLeft))
                {
                    value = this.ValueLeft;
                }

                _valueRight = value;
                this.OnValueChanged(EventArgs.Empty);
                this.OnRightValueChanged(EventArgs.Empty);
                this.Invalidate();
            }
        }

        [Description("Valor do seletor esquerdo")]
        public int ValueLeft
        {
            get { return _valueLeft; }
            set
            {
                if (((value < this.Minimum) || (value > this.Maximum)))
                    throw new ArgumentException(string.Format("Valor de \'{0}\' não é válido para \'ValueLeft\'. \'ValueLeft\' deve estar entre \'Minimum\' e \'Maximum\'", value.ToString()), "ValueLeft");

                if ((value > this.ValueRight))
                    throw new ArgumentException(string.Format("Valor de \'{0}\' não é válido para \'ValueLeft\'. \'ValueLeft\' deve ser menor que \'ValueRight\'", value.ToString()), "ValueLeft");


                _valueLeft = value;
                this.OnValueChanged(EventArgs.Empty);
                this.OnLeftValueChanged(EventArgs.Empty);
                this.Invalidate();
            }
        }

        [Description("Retorna qual seletor está em uso")]
        public Thumbs SelectedThumb
        {
            get { return selectedThumb; }
            private set { selectedThumb = value; }
        }

        #region Private Properties

        private double RelativeValueLeft
        {
            get
            {
                double diff = this.Maximum - this.Minimum;
                return (diff != 0) ? (this.ValueLeft / diff) : this.ValueLeft;
            }
        }

        private double RelativeValueRight
        {
            get
            {
                double diff = (this.Maximum - this.Minimum);
                return (diff != 0) ? (this.ValueRight / diff) : this.ValueLeft;
            }
        }

        #endregion

        #endregion

        #region Internal Events Implementation

        protected void OnValueChanged(EventArgs e)
        {
            if (ValueChanged != null)
                ValueChanged(this, e);
        }

        protected void OnLeftValueChanged(EventArgs e)
        {
            if (LeftValueChanged != null)
                LeftValueChanged(this, e);
        }

        protected void OnRightValueChanged(EventArgs e)
        {
            if (RightValueChanged != null)
                RightValueChanged(this, e);
        }

        #endregion

        #region Private Methods

        private void SetDefaults()
        {
            this.Orientation = Orientation.Horizontal;
            this.SmallChange = 1;
            this.Maximum = 10;
            this.Minimum = 0;
            this.ValueRight = Maximum - 1;
            this.ValueLeft = Minimum + 1;
        }

        private Rectangle GetLeftThumbRectangle(Graphics g)
        {
            if (g == null)
                g = this.CreateGraphics();

            Rectangle rect = this.GetThumbRectangle(this.RelativeValueLeft, g);
            if (g == null)
                g.Dispose();

            return rect;
        }

        private Rectangle GetRightThumbRectangle(Graphics g)
        {
            if (g == null)
                g = this.CreateGraphics();

            Rectangle rect = this.GetThumbRectangle(this.RelativeValueRight, g);
            if (g == null)
                g.Dispose();

            return rect;
        }

        private Rectangle GetThumbRectangle(double relativeValue, Graphics g)
        {
            if (Orientation == Orientation.Horizontal)
            {
                Size size = TrackBarRenderer.GetBottomPointingThumbSize(g, TrackBarThumbState.Normal);
                int border = size.Width / 2;
                int w = this.GetTrackRectangle(border).Width;
                int x = Convert.ToInt16(Math.Round(((Math.Abs(this.Minimum) / ((this.Maximum - this.Minimum) * w)) + (relativeValue * w)), 0));
                int y = (this.Height - size.Height) / 2;

                return new Rectangle(new Point(x, y), size);
            }
            else
            {
                Size size = TrackBarRenderer.GetBottomPointingThumbSize(g, TrackBarThumbState.Normal);
                int border = size.Height / 2;
                int w = this.GetTrackRectangle(border).Height;
                int x = Convert.ToInt16(Math.Round(((Math.Abs(this.Minimum) / ((this.Maximum - this.Minimum) * w)) + (relativeValue * w)), 0));
                int y = (this.Width - size.Width) / 25;

                return new Rectangle(new Point(y, x), size);
            }

        }

        private Rectangle GetTrackRectangle(int border)
        {
            if (Orientation == Orientation.Horizontal)
            {

                return new Rectangle(border, (Convert.ToInt16(this.Height / 2) - 3), (this.Width - ((3 * border) - 1)), 10);

            }

            else
            {
                return new Rectangle(border, (Convert.ToInt16(this.Width / 10) - 2), 10, (this.Height - ((3 * border) - 1)));
            }
        }

        private bool IsValidValueLeft(int value)
        {
            return ((value >= this.Minimum) && ((value <= this.Maximum) && (value < this.ValueRight)));
        }

        private bool IsValidValueRight(int value)
        {
            return ((value >= this.Minimum) && ((value <= this.Maximum) && (value > this.ValueLeft)));
        }

        private void SetThumbState(Point location, TrackBarThumbState newState)
        {
            Rectangle leftThumbRect = this.GetLeftThumbRectangle(null);
            Rectangle rightThumbRect = this.GetRightThumbRectangle(null);

            if (leftThumbRect.Contains(location))
                leftThumbState = newState;
            else if ((this.SelectedThumb == Thumbs.Left))
                leftThumbState = System.Windows.Forms.VisualStyles.TrackBarThumbState.Hot;
            else
                leftThumbState = System.Windows.Forms.VisualStyles.TrackBarThumbState.Normal;

            if (rightThumbRect.Contains(location))
                rightThumbState = newState;
            else if ((this.SelectedThumb == Thumbs.Right))
                rightThumbState = System.Windows.Forms.VisualStyles.TrackBarThumbState.Hot;
            else
                rightThumbState = System.Windows.Forms.VisualStyles.TrackBarThumbState.Normal;
        }

        private Thumbs GetClosestSlider(Point point)
        {
            Rectangle leftThumbRect = this.GetLeftThumbRectangle(null);
            Rectangle rightThumbRect = this.GetRightThumbRectangle(null);
            if ((this.Orientation == Orientation.Horizontal))
            {
                if (((Math.Abs((leftThumbRect.X - point.X)) > Math.Abs((rightThumbRect.X - point.X)))
                && ((Math.Abs((leftThumbRect.Right - point.X)) > Math.Abs((rightThumbRect.Right - point.X))))))
                {
                    return Thumbs.Right;
                }
                else
                    return Thumbs.Left;

            }
            else
            {
                // Vertical Slider doesn't work.  It took me long enough to type in the horizontal.  Have fun with it!
                if (((Math.Abs((leftThumbRect.Y - point.Y)) > Math.Abs((rightThumbRect.Y - point.Y)))
                && (Math.Abs((leftThumbRect.Bottom - point.Y)) > Math.Abs((rightThumbRect.Bottom - point.Y)))))
                {
                    return Thumbs.Right;
                }
                else
                {
                    return Thumbs.Left;
                }
            }
        }

        #endregion

        #region Overrided Events

        protected override void OnPaint(PaintEventArgs e)
        {
              base.OnPaint(e); 

            if (Orientation == Orientation.Horizontal)
            {

                Size thumbSize = this.GetThumbRectangle(0, e.Graphics).Size;
                Rectangle trackRect = this.GetTrackRectangle(Convert.ToInt16(thumbSize.Width / 2));
                Rectangle ticksRect = trackRect;
                ticksRect.Offset(0,15);
                TrackBarRenderer.DrawVerticalTrack(e.Graphics, trackRect);
                TrackBarRenderer.DrawVerticalTicks(e.Graphics, ticksRect, ((this.Maximum - this.Minimum) + 1), System.Windows.Forms.VisualStyles.EdgeStyle.Etched);
                TrackBarRenderer.DrawRightPointingThumb(e.Graphics, this.GetLeftThumbRectangle(e.Graphics), leftThumbState);
                TrackBarRenderer.DrawRightPointingThumb(e.Graphics, this.GetRightThumbRectangle(e.Graphics), rightThumbState);


            }
            else 
            {  

                Size thumbSize = this.GetThumbRectangle(0, e.Graphics).Size;

                Rectangle trackRect = this.GetTrackRectangle(Convert.ToInt16(thumbSize.Height / 2));

                Rectangle ticksRect = trackRect;

                ticksRect.Offset(15, 0);

                TrackBarRenderer.DrawVerticalTrack(e.Graphics, trackRect);

                TrackBarRenderer.DrawVerticalTicks(e.Graphics, ticksRect, ((this.Maximum - this.Minimum) + 1), System.Windows.Forms.VisualStyles.EdgeStyle.Etched);

                TrackBarRenderer.DrawRightPointingThumb(e.Graphics, this.GetLeftThumbRectangle(e.Graphics), leftThumbState);

                TrackBarRenderer.DrawRightPointingThumb(e.Graphics, this.GetRightThumbRectangle(e.Graphics), rightThumbState);
           }

            }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            this.SetThumbState(e.Location, TrackBarThumbState.Hot);
            double offset = ((double)e.Location.X / this.Width) * (this.Maximum - this.Minimum);
            int newValue = (this.Minimum + Convert.ToInt16(offset));

            if (draggingLeft && this.IsValidValueLeft(newValue))
                this.ValueLeft = newValue;
            else if (draggingRight && this.IsValidValueRight(newValue))
                this.ValueRight = newValue;


            this.Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            this.Focus();
            this.SetThumbState(e.Location, TrackBarThumbState.Pressed);
            draggingLeft = (leftThumbState == TrackBarThumbState.Pressed);
            draggingRight = (rightThumbState == TrackBarThumbState.Pressed);

            this.SelectedThumb = draggingLeft ? Thumbs.Left : draggingRight ? Thumbs.Right : Thumbs.None;

            if (!draggingLeft && !draggingRight)
            {
                if ((this.GetClosestSlider(e.Location) == Thumbs.Left))
                {
                    if ((e.X < this.GetLeftThumbRectangle(null).X))
                        this.DecrementLeft();
                    else
                        this.IncrementLeft();


                    this.SelectedThumb = Thumbs.Left;
                }
                else if ((this.GetClosestSlider(e.Location) == Thumbs.Right))
                {
                    if ((e.X < this.GetRightThumbRectangle(null).X))
                        this.DecrementRight();
                    else
                        this.IncrementRight();
                }
                this.SelectedThumb = Thumbs.Right;
            }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            draggingLeft = false;
            draggingRight = false;
            this.Invalidate();
        }

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            base.OnMouseWheel(e);

            if ((e.Delta == 0))
                return;

            if ((this.SelectedThumb == Thumbs.Left))
            {
                if ((e.Delta > 0))
                    this.IncrementLeft();
                else
                    this.DecrementLeft();

            }
            else if ((this.SelectedThumb == Thumbs.Right))
            {
                if ((e.Delta > 0))
                    this.IncrementRight();
                else
                    this.DecrementRight();

            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Incrementa 1 no valor e posição do seletor esquerdo
        /// </summary>
        public void IncrementLeft()
        {
            int newValue = Math.Min((this.ValueLeft + 1), this.Maximum);
            if (this.IsValidValueLeft(newValue))
                this.ValueLeft = newValue;

            this.Invalidate();

        }

        /// <summary>
        /// Incrementa 1 no valor e posição do seletor direito
        /// </summary>
        public void IncrementRight()
        {
            int newValue = Math.Min((this.ValueRight + 1), this.Maximum);
            if (this.IsValidValueRight(newValue))
                this.ValueRight = newValue;

            this.Invalidate();

        }

        /// <summary>
        /// Decrementa 1 no valor e posição do seletor esquerdo
        /// </summary>
        public void DecrementLeft()
        {
            int newValue = Math.Max((this.ValueLeft - 1), this.Minimum);
            if (this.IsValidValueLeft(newValue))
                this.ValueLeft = newValue;

            this.Invalidate();

        }

        /// <summary>
        /// Incrementa 1 no valor e posição do seletor direito
        /// </summary>
        public void DecrementRight()
        {
            int newValue = Math.Max((this.ValueRight - 1), this.Minimum);
            if (this.IsValidValueRight(newValue))
                this.ValueRight = newValue;

            this.Invalidate();

        }

        #endregion
    }
}
    
asked by anonymous 14.04.2016 / 18:20

0 answers