C#winform自定义滚动条

1.控件

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

2.实现功能

(1)设置滚动条背景颜色和背景图片

(2)设置滚动条滑块的背景颜色和背景图片

(3)鼠标左键拖动滑块上下滑动

(4)鼠标进入和离开滑块事件

(5)滚动鼠标中间滚轮事件

(6)鼠标左键点击滚动条除去滑块的位置,上下移动滑块

(7)鼠标左键长时间按住滚动条除去滑块的位置,上下移动滑块

3.关键数据

 

滑块大小:  BoxPanelHeight/ContentPanelHeight*ScrollBgHeight

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

4.代码

(1)自定义控件

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.ScrollBar.Top = 0;
            this.MouseWheel += ScrollBar_MouseWheel;
            ScrollBar.MouseWheel += ScrollBar_MouseWheel;
            ScrollTimer = new Timer();
            ScrollTimer.Interval = 200;
            ScrollTimer.Tick += Timer_Tick;
        }

        #region public

        /// <summary>
        /// 滑块高度
        /// </summary>
        public int ScrollBarHeight
        {
            get { return this.ScrollBar.Height; }
        }

        /// <summary>
        /// 滑块在滚动条上的位置
        /// </summary>
        public int ScrollBarTop
        {
            set { ScrollBarAndContent(value); }
            get { return this.ScrollBar.Top; }
        }

        /// <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

(2)使用

        private void Form2_Load(object sender, EventArgs e)
        {
            scrollBarBg1.ScrollBarScroll += ScrollBarScroll;
            pnContent.MouseWheel += PnContent_MouseWheel;

            scrollBarBg1.SetScrollBarHeight(this.pnBox.Height, this.pnContent.Height);
            scrollBarBg1.ScrollBarTop = 0;
        }

        private void PnContent_MouseWheel(object sender, MouseEventArgs e)
        {
            scrollBarBg1.ContentPanelMouseWheel(sender, e);
        }

        private void ScrollBarScroll(int y)
        {
            this.pnContent.Top = y;
        }
View Code

 

posted @ 2019-04-12 18:50  翻白眼的哈士奇  阅读(6499)  评论(6编辑  收藏  举报