C#winform自定义滚动条

1.控件

一个UserControl作为ScrollBg,一个panel作为ScrollBar

 2.关键数据

滑块大小:  BoxPanelHeight/ContentPanelHeight*ScrollBgHeight

ContenPanel纵坐标:  -ScrollBar.Top /( ScrollBgHeigh - ScrollBgHeight)* (ContentPanelHeight - BoxPanelHeight));

 3代码

    public partial class ScrollBarBg : UserControl
    {
        #region private properties

        private Timer ScrollTimer = null;

        /// <summary>
        /// 框架面板高度
        /// </summary>
        private int BoxPanelHeight = 0;

        /// <summary>
        /// 内容面板高度
        /// </summary>
        private int ContentPanelHeight = 0;

        /// <summary>
        /// 滚动条滑块鼠标左键是否按下
        /// </summary>
        private bool IsLeftKeyDown_ScrollBar = false;

        /// <summary>
        /// 滚动条背景板鼠标左键是否按下
        /// </summary>
        private bool IsLeftKeyDown_ScrollBg = false;

        /// <summary>
        /// 鼠标相对有屏幕的Y坐标
        /// </summary>
        private int MouseYToScreen = 0;

        #endregion

        public ScrollBarBg()
        {
            InitializeComponent();
            this.MouseWheel += ScrollBar_MouseWheel;
            ScrollBar.MouseWheel += ScrollBar_MouseWheel;
            ScrollTimer = new Timer();
            ScrollTimer.Interval = 200;
            ScrollTimer.Tick += Timer_Tick;
        }

        #region public

        /// <summary>
        /// 滑块背景颜色
        /// </summary>
        public Color ScrollBarBackColor
        {
            set { this.ScrollBar.BackColor = value; }
            get { return ScrollBar.BackColor; }
        }

        /// <summary>
        /// 滑块背景图片
        /// </summary>
        public Image ScrollBarBackgroundImage
        {
            set { this.ScrollBar.BackgroundImage = value; }
            get { return ScrollBar.BackgroundImage; }
        }

        /// <summary>
        /// 鼠标进入滚动条滑块事件
        /// </summary>
        public event EventHandler ScrollBarMouseEnter = null;

        /// <summary>
        /// 鼠标离开滚动条滑块事件
        /// </summary>
        public event EventHandler ScrollBarMouseLeave = null;

        /// <summary>
        /// 滑块滚动发生
        /// int:内容面板相对于框架面板的高度
        /// </summary>
        public Action<int> ScrollBarScroll = null;

        /// <summary>
        /// 鼠标转动滚轮滑块滚动的单位高度,影响滚动速度
        /// </summary>
        private int mouseWheelUnitHeight = 10;
        public int MouseWheelUnitHeight
        {
            set { mouseWheelUnitHeight = value; }
            get { return mouseWheelUnitHeight; }
        }

        /// <summary>
        /// 长按滚动条背景框滑块滚动的单位高度,影响滚动速度
        /// </summary>
        private int timerScrollUnitHeight = 40;
        public int TimerScrollUnitHeight
        {
            set { timerScrollUnitHeight = value; }
            get { return timerScrollUnitHeight; }
        }

        /// <summary>
        /// 设置滑块高度
        /// </summary>
        /// <param name="panelHeight">面板高度</param>
        /// <param name="contentHeight">内容高度</param>
        public void SetScrollBarHeight(int boxPanelHeight, int contentPanelHeight)
        {
            BoxPanelHeight = boxPanelHeight;
            ContentPanelHeight = contentPanelHeight;
            ScrollBar.Height = (int)((double)boxPanelHeight / contentPanelHeight * this.Height);
            MouseWheel += ScrollBar_MouseWheel;
        }

        /// <summary>
        /// 内容面板鼠标滚动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ContentPanelMouseWheel(object sender, MouseEventArgs e)
        {
            ScrollBar_MouseWheel(sender, e);
        }

        #endregion

        #region private

        private void ScrollBar_MouseWheel(object sender, MouseEventArgs e)
        {
            int ScrollBarTop = e.Delta > 0 ? this.ScrollBar.Top - mouseWheelUnitHeight : this.ScrollBar.Top + mouseWheelUnitHeight;
            ScrollBarAndContent(ScrollBarTop);
        }

        private void ScrollBar_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                IsLeftKeyDown_ScrollBar = true;
                MouseYToScreen = Control.MousePosition.Y;
            }
        }

        private void ScrollBar_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                IsLeftKeyDown_ScrollBar = false;
        }

        private void ScrollBar_MouseMove(object sender, MouseEventArgs e)
        {
            if (IsLeftKeyDown_ScrollBar)
            {
                int ScrollBarTop = this.ScrollBar.Top + Control.MousePosition.Y - MouseYToScreen;
                MouseYToScreen = Control.MousePosition.Y;

                ScrollBarAndContent(ScrollBarTop);
            }
        }

        private void ScrollBar_MouseEnter(object sender, EventArgs e)
        {
            if (ScrollBarMouseEnter != null)
                ScrollBarMouseEnter(sender, e);
        }

        private void ScrollBar_MouseLeave(object sender, EventArgs e)
        {
            if (ScrollBarMouseLeave != null)
                ScrollBarMouseLeave(sender, e);
        }

        private void ScrollBarBg_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                IsLeftKeyDown_ScrollBg = true;
                ScrollTimer.Start();
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            if (!IsLeftKeyDown_ScrollBg)
                goto ret;

            int ScrollBarTop = this.ScrollBar.Top;
            int ScrollBarMiddlePointY = ScrollBarTop + ScrollBar.Height / 2;
            int MousePointToClientY = this.PointToClient(Control.MousePosition).Y;
            if (ScrollBarMiddlePointY > MousePointToClientY)
            {
                if (ScrollBarMiddlePointY - timerScrollUnitHeight < this.PointToClient(Control.MousePosition).Y)
                    goto ret;
                else
                    ScrollBarTop -= timerScrollUnitHeight;
            }
            else
            {
                if (ScrollBarMiddlePointY + timerScrollUnitHeight > this.PointToClient(Control.MousePosition).Y)
                    goto ret;
                else
                    ScrollBarTop += timerScrollUnitHeight;
            }

            this.BeginInvoke(new Action(() =>
            {
                ScrollBarAndContent(ScrollBarTop);
            }));
            return;

            ret:
            IsLeftKeyDown_ScrollBg = false;
            ScrollTimer.Stop();
        }

        private void ScrollBarBg_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && IsLeftKeyDown_ScrollBg)
            {
                IsLeftKeyDown_ScrollBg = false;
                int ScrollBarTop = this.ScrollBar.Top + ScrollBar.Height / 2 > e.Y ? this.ScrollBar.Top - timerScrollUnitHeight : this.ScrollBar.Top + timerScrollUnitHeight;
                ScrollBarAndContent(ScrollBarTop);
            }
        }

        private void ScrollBarControl_SizeChanged(object sender, EventArgs e)
        {
            this.ScrollBar.Width = this.Width;
        }

        private void ScrollBarAndContent(int ScrollBarTop)
        {
            if (ScrollBarTop <= 0)
                this.ScrollBar.Top = 0;
            else if (ScrollBarTop >= this.Height - this.ScrollBar.Height)
                this.ScrollBar.Top = this.Height - this.ScrollBar.Height;
            else
                this.ScrollBar.Top = ScrollBarTop;

            int Y = (int)(this.ScrollBar.Top / (double)(this.Height - this.ScrollBar.Height) * (ContentPanelHeight - BoxPanelHeight));
            if (ScrollBarScroll != null)
                ScrollBarScroll(-Y);
        }

        #endregion
    }
View Code

猜你喜欢

转载自www.cnblogs.com/yaosj/p/10697874.html