就为long类型属性,写了个水平滚动条。

就为long类型属性,写了个水平滚动条。



public partial public partial class HScrollbar : UserControl
    {
        public HScrollbar()
        {
            InitializeComponent();
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            MouseLeave += HScrollbar_MouseLeave;
        }


        #region 属性
        public long Maximum = 0;

        #endregion

        public long BarOffset = 0;

        public event System.Windows.Forms.ScrollEventHandler Scroll;

        private bool IsShowBar = true;


        private void HScrollbar_Paint(object sender, PaintEventArgs e)
        {
            AutoSize(Width, Height, ref IsShowBar);
            Graphics g = e.Graphics;
            g.Clear(Color.White);
            SmoothingMode sm = g.SmoothingMode;
            g.SmoothingMode = SmoothingMode.HighQuality;

            g.FillRectangle(new SolidBrush(ColorBackground), rectBackground.Rectangle);

            if (IsShowBar)
            {
                DrawBar(g);
            }
            g.FillRectangle(new SolidBrush(GetColorButtonBackgrond(rectLeft, IsBegin)), rectLeft.Rectangle);
            g.FillRectangle(new SolidBrush(GetColorButtonBackgrond(rectRight, IsEnd)), rectRight.Rectangle);
            DrawLeftArrow(g, GetColorArrow(true));
            DrawRightArrow(g, GetColorArrow(false));
            g.SmoothingMode = sm;
        }

        private bool IsBegin
        {
            get
            {
                long begin = 0;
                bool bRet = begin == BarOffset;
                return bRet;
            }
        }

        private bool IsEnd
        {
            get
            {
                long end = (long)(MaxBarWidth - rectBar.Width);
                bool bRet = end == BarOffset;
                return bRet;
            }
        }

        private Color GetColorArrow(bool isLeft)
        {
            if (IsShowBar && !IsBegin && isLeft && enumHitObject == EnumHitObject.HO_Left)
            {
                return ColorArrowButtonDown;
            }

            if (IsShowBar && !IsEnd && !isLeft && enumHitObject == EnumHitObject.HO_Right)
            {
                return ColorArrowButtonDown;
            }
            return ColorArrow;
        }

        private Color GetColorButtonBackgrond(Rect2 rect, bool stopFlag)
        {
            if (IsShowBar && !stopFlag && !IsMouseLevel && rect.Rectangle.Contains(PointMouse))
            {
                return ColorButtonMoveOn;
            }
            else
            {
                return ColorBackground;
            }
        }
        private int SpaceWidth = 3;
        private void AutoSize(int barWidth, int barHeight, ref bool showBar)
        {
            showBar = false;
            int rectWidth = 12 + SpaceWidth;
            //
            rectBackground.Left = 0;
            rectBackground.Top = 0;
            rectBackground.Width = barWidth;
            rectBackground.Height = barHeight;
            //
            rectLeft.Left = 0;
            rectLeft.Top = 0;
            rectLeft.Width = rectWidth;
            rectLeft.Height = barHeight;
            //
            rectRight.Left = Right - rectWidth;
            rectRight.Width = rectWidth;
            rectRight.Top = 0;
            rectRight.Height = barHeight;
            //
            rectCetner.Top = 0;
            rectCetner.Height = barHeight;
            rectCetner.Left = rectLeft.Right;
            rectCetner.Width = rectRight.Left - rectCetner.Left;

            double maxBarWidth = MaxBarWidth;
            if (BarOffset > Maximum)
                BarOffset = Maximum;
            if (maxBarWidth > 0 && Maximum > maxBarWidth)
            {
                showBar = true;
            }
            double movemax = Maximum - rectBackground.Width;
            float width = 20;
            if (movemax >= 0 && movemax < maxBarWidth)
            {
                width = (float)(maxBarWidth - movemax);
            }
            float left = rectLeft.Right + PaddingBar + BarOffset;//(float)((double)Value / (double)Maximum * (rectBackground.Width));

            rectBar.Top = Top + PaddingBar;
            rectBar.Left = left;
            rectBar.Width = width;
            rectBar.Height = barHeight - 2 * PaddingBar - 1;
        }

        private Rect2 rectLeft = new Rect2();
        private Rect2 rectRight = new Rect2();
        private Rect2 rectCetner = new Rect2();
        private Rect2 rectBackground = new Rect2();
        private Rect2 rectBar = new Rect2();

        private int PaddingBar = 2;
        private int PaddingArrowX = 4;
        private int PaddingArrowY = 4;
        //配色
        private Color ColorArrow = Color.FromArgb(163, 163, 163);
        private Color ColorArrowButtonDown = Color.White;
        private Color ColorBackground = Color.FromArgb(241, 241, 241);
        private Color ColorButtonMoveOn = Color.FromArgb(210, 210, 210);
        private Color ColorButtonDown = Color.FromArgb(120, 120, 120);
        private Color ColorBar = Color.FromArgb(170, 170, 171);
        private Color ColorBarButtonDown = Color.FromArgb(141, 141, 142);
        private Color ColorBarBorder = Color.FromArgb(154, 154, 154);
        private Brush brDebug = new SolidBrush(Color.Red);

        private double MaxBarWidth
        {
            get
            {
                double maxBarWidth = rectBackground.Width - 2 * PaddingBar - rectLeft.Width - rectRight.Width;
                return maxBarWidth;
            }
        }
        private void DrawLeftArrow(Graphics g, Color color)
        {
            Rect2 rectArrow = new Rect2();
            rectLeft.Copy(ref rectArrow);
            rectArrow.InflateRect(-PaddingArrowX, -PaddingArrowY);
            rectArrow.Height -= 1;
            PointF pt0 = rectArrow.TopRight;
            PointF pt1 = rectArrow.BottomRight;
            PointF pt2 = rectArrow.LeftCenter;
            pt0.X -= SpaceWidth;
            pt1.X -= SpaceWidth;
            GraphicsPath gPath = new GraphicsPath();
            gPath.AddLine(pt0, pt1);
            gPath.AddLine(pt1, pt2);
            gPath.AddLine(pt2, pt0);

            g.FillPath(new SolidBrush(color), gPath);

        }

        private void DrawRightArrow(Graphics g, Color color)
        {
            Rect2 rectArrow = new Rect2();
            rectRight.Copy(ref rectArrow);
            rectArrow.InflateRect(-PaddingArrowX, -PaddingArrowY);
            rectArrow.Height -= 1;
            //g.FillRectangle(brDebug, rectArrow.Rectangle);
            PointF pt0 = rectArrow.TopLeft;
            PointF pt1 = rectArrow.BottomLeft;
            PointF pt2 = rectArrow.RightCenter;
            pt0.X += SpaceWidth;
            pt1.X += SpaceWidth;
            GraphicsPath gPath = new GraphicsPath();
            gPath.AddLine(pt0, pt1);
            gPath.AddLine(pt1, pt2);
            gPath.AddLine(pt2, pt0);
            g.FillPath(new SolidBrush(color), gPath);
        }

        private void DrawBar(Graphics g)
        {
            g.FillRectangle(new SolidBrush(GetColorBar()), rectBar.Rectangle);
            g.DrawRectangle(new Pen(new SolidBrush(ColorBarBorder)), rectBar.Rectangle);
        }
        private Color GetColorBar()
        {
            if (enumHitObject == EnumHitObject.HO_Bar)
            {
                return ColorBarButtonDown;
            }
            else
            {
                return ColorBar;
            }
        }
        private enum EnumHitObject
        {
            HO_None,
            HO_Left,
            HO_Right,
            HO_Bar,
            HO_BarSpace
        }

        private EnumHitObject enumHitObject = EnumHitObject.HO_None;

        private EnumHitObject HitTest(Point pointMouse)
        {
            EnumHitObject ho = EnumHitObject.HO_None;
            if (rectLeft.Rectangle.Contains(pointMouse))
            {
                ho = EnumHitObject.HO_Left;
            }
            else if (rectRight.Rectangle.Contains(pointMouse))
            {
                ho = EnumHitObject.HO_Right;
            }
            else if (rectBar.Rectangle.Contains(pointMouse))
            {
                ho = EnumHitObject.HO_Bar;
            }
            else if (rectBackground.Rectangle.Contains(pointMouse))
            {
                ho = EnumHitObject.HO_BarSpace;
            }
            return ho;
        }

        private DateTime LButtonDownTime = DateTime.Now;
        private Point LButtonDownMousePoint = new Point();
        private void HScrollbar_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                Point ptMouse = new Point(e.X, e.Y);
                enumHitObject = HitTest(ptMouse);
                LButtonDownMousePoint.X = e.X;
                LButtonDownMousePoint.Y = e.Y;
                LButtonDownTime = DateTime.Now;
                switch (enumHitObject)
                {
                    case EnumHitObject.HO_BarSpace:
                        {
                            SetBarOffset(e.X);
                        }
                        break;
                }
            }
        }

        private void SetBarOffset(long screenPixcel)
        {
            screenPixcel = (long)(screenPixcel - rectLeft.Right - PaddingBar);

            if (screenPixcel <= 0)
            {
                screenPixcel = 0;
            }
            if (screenPixcel >= (MaxBarWidth - rectBar.Width))
            {
                screenPixcel = (long)(MaxBarWidth - rectBar.Width);
            }
            BarOffset = screenPixcel;
        }

        private Point PointMouse = new Point();

        private bool IsMouseLevel = true;

        private void HScrollbar_MouseLeave(object sender, EventArgs e)
        {
            IsMouseLevel = true;
        }
        private void HScrollbar_MouseMove(object sender, MouseEventArgs e)
        {
            PointMouse.X = e.X;
            PointMouse.Y = e.Y;
            IsMouseLevel = false;

            if (enumHitObject == EnumHitObject.HO_Bar
                || enumHitObject == EnumHitObject.HO_BarSpace && e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                SetBarOffset(e.X);
                Debug();
            }
        }

        private void HScrollbar_MouseUp(object sender, MouseEventArgs e)
        {
            enumHitObject = EnumHitObject.HO_None;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            long step = Maximum / 20;
            double ms = (DateTime.Now - LButtonDownTime).TotalMilliseconds;
            if (ms > 200)
            {
                step = Maximum / 10;
            }
            long newValue = Value;
            if (enumHitObject == EnumHitObject.HO_Left)
            {
                newValue -= step;
                Value = newValue;
            }
            else if (enumHitObject == EnumHitObject.HO_Right)
            {
                newValue += step;
                Value = newValue;
            }
            Invalidate();
        }

        public int SliderWidth//滑块宽度
        {
            get
            {
                return (int)rectBar.Width;
            }
        }

        private double MaxValue
        {
            get
            {
                double maxValue = (double)(Maximum - rectBackground.Width);
                if (maxValue < 0)
                    maxValue = 0;
                return maxValue;
            }
        }

        public long Value
        {
            get
            {
                double maxPixcel = (double)(MaxBarWidth - rectBar.Width);
                double maxValue = MaxValue;
                //像素转值
                long value = (long)((double)BarOffset * maxValue / maxPixcel + 0.5d);
                return value;
            }
            set
            {
                double maxPixcel = (double)(MaxBarWidth - rectBar.Width);
                double maxValue = MaxValue;
                double v = value;
                if (v < 0)
                {
                    v = 0;
                }
                if (v > maxValue && maxValue >= 0)
                    v = maxValue;
                //值转像素
                BarOffset = (long)(v * maxPixcel / maxValue + 0.5d);
                if (BarOffset < 0)
                    BarOffset = 0;
                Debug();
            }
        }

        private void Debug()
        {
            System.Console.WriteLine(string.Format("Begin:{0},End:{1}", Value, Value + rectBackground.Width));
        }

        private int PrevWidth = 0;
        private int PrevHeight = 0;

        private void HScrollbar_Resize(object sender, EventArgs e)
        {

            bool isShowbar = false;
            AutoSize(PrevWidth, PrevHeight, ref isShowbar);
            double prevMaxBarWidth = MaxBarWidth - rectBar.Width;
            AutoSize(Width, Height, ref isShowbar);
            double maxBarWidth = MaxBarWidth - rectBar.Width;

            double xscale = BarOffset / (double)prevMaxBarWidth;


            double screenPixcel = xscale * maxBarWidth + rectLeft.Right + PaddingBar;
            if (double.IsNaN(screenPixcel))
            {
                SetBarOffset(0);
            }
            else
            {
                SetBarOffset((long)screenPixcel);
            }

            PrevWidth = Width;
            PrevHeight = Height;
            Debug();
        }








    }



public class Rect2
    {
        public float Left = 0;
        public float Width = 0;
        public float Top = 0;
        public float Height = 0;

        public Rect2()
        {

        }



        public static void TestDraw(Graphics g, RectangleF rect)
        {
            g.FillRectangle(new SolidBrush(Color.Gray), rect);
        }

        public Rect2(float Left, float Top, float Width, float Height)
        {
            this.Left = Left;
            this.Width = Width;
            this.Top = Top;
            this.Height = Height;
        }

        #region 点
        public float Right
        {
            get
            {
                return Left + Width;
            }
        }

        public float Bottom
        {
            get
            {
                return Top + Height;
            }
        }


        public PointF TopLeft
        {
            get
            {
                PointF pt = new PointF(Left, Top);
                return pt;
            }
        }

        public PointF TopRight
        {
            get
            {
                PointF pt = new PointF(Right, Top);
                return pt;
            }
        }

        public PointF BottomLeft
        {
            get
            {
                PointF pt = new PointF(Left, Bottom);
                return pt;
            }
        }

        public PointF BottomRight
        {
            get
            {
                PointF pt = new PointF(Right, Bottom);
                return pt;
            }
        }

        public PointF Center
        {
            get
            {
                PointF pt = new PointF(Left + Width / 2.0f, Top + Height / 2.0f);
                return pt;
            }
        }

        public PointF LeftCenter
        {
            get
            {
                PointF pt = new PointF(Left, Top + Height / 2.0f);
                return pt;
            }
        }

        public PointF RightCenter
        {
            get
            {
                PointF pt = new PointF(Right, Top + Height / 2.0f);
                return pt;
            }
        }

        public PointF TopCenter
        {
            get
            {
                PointF pt = new PointF(Left + Width / 2.0f, Top);
                return pt;
            }
        }

        public PointF BottomCenter
        {
            get
            {
                PointF pt = new PointF(Left + Width / 2.0f, Bottom);
                return pt;
            }
        }

        public RectangleF RectangleF
        {
            get
            {
                RectangleF rect = new RectangleF(Left, Top, Width, Height);
                return rect;
            }
        }

        public Rectangle Rectangle
        {
            get
            {
                Rectangle rect = new Rectangle((int)Left, (int)Top, (int)Width, (int)Height);
                return rect;
            }
        }

        public void Set(RectangleF rect)
        {
            this.Left = rect.X;
            this.Width = rect.Width;
            this.Top = rect.Y;
            this.Height = rect.Height;
        }

        public void InflateRect(float x, float y)
        {
            Left -= x;
            Width += 2 * x;
            Top -= y;
            Height += 2 * y;
        }

        public void Copy(ref Rect2 rect)
        {
            rect.Left = Left;
            rect.Top = Top;
            rect.Width = Width;
            rect.Height = Height;
        }

        #endregion

        #region 计算矩形位置
        public enum EnumPosition
        {
            EnumPosition_Center,
            EnumPosition_LeftCenter,
            EnumPosition_RightCenter,
            EnumPosition_TopCenter,
            EnumPosition_BottomCenter
        }

        public static Rect2 Postion(PointF point, SizeF sz, EnumPosition enumPostion)
        {
            Rect2 rect = new Rect2();
            switch (enumPostion)
            {
                case EnumPosition.EnumPosition_LeftCenter:
                    rect = new Rect2(point.X - sz.Width, point.Y - sz.Height / 2.0f, sz.Width, sz.Height);
                    break;
                case EnumPosition.EnumPosition_RightCenter:
                    rect = new Rect2(point.X, point.Y - sz.Height / 2.0f, sz.Width, sz.Height);
                    break;
                case EnumPosition.EnumPosition_TopCenter:
                    rect = new Rect2(point.X - sz.Width / 2.0f, point.Y - sz.Height, sz.Width, sz.Height);
                    break;
                case EnumPosition.EnumPosition_BottomCenter:
                    rect = new Rect2(point.X - sz.Width / 2.0f, point.Y, sz.Width, sz.Height);
                    break;
                case EnumPosition.EnumPosition_Center:
                    rect = new Rect2(point.X - sz.Width / 2.0f, point.Y - sz.Height / 2.0f, sz.Width, sz.Height);
                    break;

            }
            return rect;
        }


        #endregion
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值