C# 自定义滚动条控件的实现

第一步 面板方面的配置

新建一个控件项目 取名叫blog_scrollbar
在这里插入图片描述
同时cs文件也改名叫blog_scrollbar在这里插入图片描述

新建一个panel控件
在这里插入图片描述

调整panel和面板的大小 为滚动条的样式
在这里插入图片描述

添加一个事时间控件 并配置好相关属性 将enabled属性设置为true interval设置为10毫秒
在这里插入图片描述
在这里插入图片描述

第二步 代码方面的配置

在控件类中 添加五个属性


        private bool wheel_move = false;
        [Description("标识滚轮是否发生了运动")]
        public bool Wheel_move
        {
            get { return wheel_move; }
            set { wheel_move = value; }
        }

        private string moveway = null;
        [Description("标识滚轮的滚动方向")]
        public string Moveway
        {
            get { return moveway; }
            set { moveway = value; }
        }

        private int winH = 0;                                   //定义一个 滚动条的属性 用于接收 窗口的高度
        [Description("需要滚动条控件的高度")]
        public int WinH
        {
            get { return winH; }
            set { winH = value; }
        }

        private Control con = null;                                                 //用于接收 需要滚动条的控件
        [Description("需要滚动条的控件")]
        public Control control
        {
            get { return con; }
            set
            {
                con = value;
            }
        }

        private bool control_move = false;                                   //用于标识 需要滚动条控件的主动移动  此时需要移动滑块到相应的位置
        [Description("标识是否通过其他途径改变了控件的位置")]
        public bool Control_move
        {
            get { return control_move; }
            set { control_move = value; }
        }

添加需要用到的变量

        private static bool IsMove = false;                 //标识 鼠标在滑块上的运动状态 初始为false
        private int Y;                                          //定义一个变量 用于记录鼠标进入滑块中并按下时的位置
        private int baY = 0;                                   //得到滑块的初始位置
        private int baY1 = -30000;                       //定义一个变量 用于记录 需要滚动条控件 的相对于窗口的 初始位置y坐标
        private int panH;                                   //用于记录 需要滚动条的控件的高度

添加一个load事件 用于初始化 控件的颜色 和变量

        private void UserControl1_Load(object sender, EventArgs e)
        {
            //this.BackColor = Color.FromArgb(191, 191, 191);
            panel1.BackColor = Color.FromArgb(178, 198, 187);           //设置滑块的初始颜色
            this.BackColor = Color.White;                                       //设置滑条的背景颜色
            panel1.Top = 0;                                                 //设置滑块相对于滑条的初始位置
            //baY = 0;                                                    //得到滑块的初始位置
        }

在这里插入图片描述
效果如下
在这里插入图片描述

添加panel的鼠标事件
添加时间控件的tick 事件

        private void panel1_MouseDown(object sender, MouseEventArgs e)          //鼠标对滑块的按下事件 
        {
            IsMove = true;                                               //当按下时候 标识 鼠标开始移动  
            Y = e.Location.Y;                                              //获取鼠标 的初始位置的y坐标
            panel1.BackColor = Color.FromArgb(10, 204, 61);         //滑块颜色变为深一点的绿色
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)      //鼠标对滑块的 移动 事件
        {
            if (IsMove == true)                             //如果鼠标开始移动
            {

                if (panel1.Bottom >= this.Height)                 //如果滑块到达了 滚动条的最底部 执行下面代码
                {
                    if ((e.Location.Y - Y) < 0)                     //如果 鼠标向上滑动  
                    {
                        panel1.Top += e.Location.Y - Y;         //将滑块的位置增加  增加的量是鼠标移动的距离
                    }
                    else                                                //如果鼠标向下移动
                    {
                        panel1.Top = this.Height - panel1.Height;         //滑块的位置始终为 滑条最底部的位置
                    }
                }
                else if (panel1.Top <= 0)                                       
                {
                    if ((e.Location.Y - Y) > 0)
                    {
                        panel1.Top += e.Location.Y - Y;
                    }
                    else
                    {
                        panel1.Top = 0;
                    }
                }
                else
                {
                    panel1.Top += e.Location.Y - Y;
                }
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)            //当鼠标松开时候 意味着 用户 不再需要滑动滑块
        {
            IsMove = false;                             //此时将标识变为false
            panel1.BackColor = Color.FromArgb(107, 197, 132);       //颜色变为原来的暗色
        }

        private void panel1_MouseEnter(object sender, EventArgs e)
        {
            panel1.BackColor = Color.FromArgb(107, 197, 132);
        }

        private void panel1_MouseLeave(object sender, EventArgs e)
        {
            panel1.BackColor = Color.FromArgb(147, 197, 161);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (con != null && baY1 == -30000)                           //当鼠标进入滑块时候  获取控件初始位置的y坐标  和控件的高度 用于计算滑块滑动时控件的移动距离
            {
                baY1 = con.Top;
                panH = con.Height;
            }

            if (IsMove == true)
            {
                if (con != null)                            //如果已经获取了 需要滚动条的控件
                {
                    con.Top = baY1 - (panel1.Top - baY) * (panH - winH) / (this.Height - panel1.Height);        //移动 控件的位置

                }
            }
            else if (control_move == true && IsMove == false)
            {
                if (con != null)
                {
                    if (con.Top - baY1 < 0)                            //如果需要滚动条的控件的位置小于 原来的位置
                    {
                        panel1.Top = (baY1 - con.Top) * (this.Height - panel1.Height) / (panH - winH) + baY;        //当控件运动的时候 滑块也相应的改变位置
                        control_move = false;
                    }
                    else                                                           //如果如果需要滚动条的控件的位置大于 原来的位置
                    {
                        panel1.Top = (con.Top - baY1) * (this.Height - panel1.Height) / (panH - winH) + baY;        //当控件运动的时候 滑块也相应的改变位置
                        control_move = false;
                    }

                }

            }



            //鼠标滚轮开始
            if(wheel_move == true && moveway != null)
            {
                if (panel1.Bottom >= this.Height)                 
                {
                    if (moveway=="up")                     //如果 鼠标向上滑动  
                    {
                        panel1.Location = new Point(panel1.Location.X, panel1.Location.Y - 10);
                    }
                    else                                                //如果鼠标向下移动
                    {
                        panel1.Top = this.Height - panel1.Height;         //滑块的位置始终为 滑条最底部的位置
                    }
                }
                else if (panel1.Top <= 0)                                        
                {
                    if (moveway == "down")
                    {
                        panel1.Location = new Point(panel1.Location.X, panel1.Location.Y + 10);
                    }
                    else
                    {
                        panel1.Top = 0;
                    }
                }
                else
                {
                    if (moveway == "up")                     //如果 鼠标向上滑动  
                    {
                        panel1.Location = new Point(panel1.Location.X, panel1.Location.Y - 10);
                    }
                    else
                    {
                        panel1.Location = new Point(panel1.Location.X, panel1.Location.Y + 10);
                    }
                }

                if (con != null)
                {
                    con.Top = baY1 - (panel1.Top - baY) * (panH - winH) / (this.Height - panel1.Height);
                    
                }
                wheel_move = false;
            }
            //鼠标滚轮结束


        }

并在对应的控件上添加对应的函数引用
在这里插入图片描述
在这里插入图片描述
效果如下
在这里插入图片描述
附上该项目中的所有代码

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

namespace blog_scrollbar
{
    public partial class blog_scrollbar: UserControl
    {
        public blog_scrollbar()
        {
            InitializeComponent();
        }

        private bool wheel_move = false;
        [Description("标识滚轮是否发生了运动")]
        public bool Wheel_move
        {
            get { return wheel_move; }
            set { wheel_move = value; }
        }

        private string moveway = null;
        [Description("标识滚轮的滚动方向")]
        public string Moveway
        {
            get { return moveway; }
            set { moveway = value; }
        }





        private int winH = 0;                                   //定义一个 滚动条的属性 用于接收 窗口的高度
        [Description("需要滚动条控件的高度")]
        public int WinH
        {
            get { return winH; }
            set { winH = value; }
        }

        private Control con = null;                                                 //用于接收 需要滚动条的控件
        [Description("需要滚动条的控件")]
        public Control control
        {
            get { return con; }
            set
            {
                con = value;
            }
        }

        private bool control_move = false;                                   //用于标识 需要滚动条控件的主动移动  此时需要移动滑块到相应的位置
        [Description("标识是否通过其他途径改变了控件的位置")]
        public bool Control_move
        {
            get { return control_move; }
            set { control_move = value; }
        }

        private static bool IsMove = false;                 //标识 鼠标在滑块上的运动状态 初始为false
        private int Y;                                          //定义一个变量 用于记录鼠标进入滑块中并按下时的位置
        private int baY = 0;                            //得到滑块的初始位置
        private int baY1 = -30000;                       //定义一个变量 用于记录 需要滚动条控件 的相对于窗口的 初始位置y坐标
        private int panH;                                   //用于记录 需要滚动条的控件的高度
        private void UserControl1_Load(object sender, EventArgs e)
        {
            panel1.BackColor = Color.FromArgb(178, 198, 187);           //设置滑块的初始颜色
            this.BackColor = Color.White;                                       //设置滑条的背景颜色
            panel1.Top = 0;                                                 //设置滑块相对于滑条的初始位置
        }
        private void panel1_MouseDown(object sender, MouseEventArgs e)          //鼠标对滑块的按下事件 
        {
            IsMove = true;                                               //当按下时候 标识 鼠标开始移动  
            Y = e.Location.Y;                                              //获取鼠标 的初始位置的y坐标
            panel1.BackColor = Color.FromArgb(10, 204, 61);         //滑块颜色变为深一点的绿色
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)      //鼠标对滑块的 移动 事件
        {
            if (IsMove == true)                             //如果鼠标开始移动
            {

                if (panel1.Bottom >= this.Height)                 
                {
                    if ((e.Location.Y - Y) < 0)                     //如果 鼠标向上滑动  
                    {
                        panel1.Top += e.Location.Y - Y;         //将滑块的位置增加  增加的量是鼠标移动的距离
                    }
                    else                                                //如果鼠标向下移动
                    {
                        panel1.Top = this.Height - panel1.Height;         //滑块的位置始终为 滑条最底部的位置
                    }
                }
                else if (panel1.Top <= 0)                                       
                {
                    if ((e.Location.Y - Y) > 0)
                    {
                        panel1.Top += e.Location.Y - Y;
                    }
                    else
                    {
                        panel1.Top = 0;
                    }
                }
                else
                {
                    panel1.Top += e.Location.Y - Y;
                }
            }

        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)            //当鼠标松开时候 意味着 用户 不再需要滑动滑块
        {
            IsMove = false;                             //此时将标识变为false
            panel1.BackColor = Color.FromArgb(107, 197, 132);       //颜色变为原来的暗色
        }

        private void panel1_MouseEnter(object sender, EventArgs e)
        {
            panel1.BackColor = Color.FromArgb(107, 197, 132);
        }

        private void panel1_MouseLeave(object sender, EventArgs e)
        {
            panel1.BackColor = Color.FromArgb(147, 197, 161);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (con != null && baY1 == -30000)                           //当鼠标进入滑块时候  获取控件初始位置的y坐标  和控件的高度 用于计算滑块滑动时控件的移动距离
            //这里baY1给个-30000 主要是为了给一个 控件不能达到的位置10000也行  同时使得下面的代码只执行一次 程序运行中 下次的tick不会再执行
            {
                baY1 = con.Top;
                panH = con.Height;
            }

            if (IsMove == true)
            {
                if (con != null)                            //如果已经获取了 需要滚动条的控件
                {
                    con.Top = baY1 - (panel1.Top - baY) * (panH - winH) / (this.Height - panel1.Height);        //移动 控件的位置

                }
            }
            else if (control_move == true && IsMove == false)
            {
                if (con != null)
                {
                    if (con.Top - baY1 < 0)                            //如果需要滚动条的控件的位置小于 原来的位置
                    {
                        panel1.Top = (baY1 - con.Top) * (this.Height - panel1.Height) / (panH - winH) + baY;        //当控件运动的时候 滑块也相应的改变位置
                        control_move = false;
                    }
                    else                                                           //如果如果需要滚动条的控件的位置大于 原来的位置
                    {
                        panel1.Top = (con.Top - baY1) * (this.Height - panel1.Height) / (panH - winH) + baY;        //当控件运动的时候 滑块也相应的改变位置
                        control_move = false;
                    }

                }

            }



            //鼠标滚轮开始
            if(wheel_move == true && moveway != null)       //只有开发人员将这两个参数都传入的时候才能执行下面的代码
            {
                if (panel1.Bottom >= this.Height)                //当滑块到达最底部的时候
                {
                    if (moveway=="up")                     //如果 鼠标滚轮向上滚动  
                    {
                        panel1.Location = new Point(panel1.Location.X, panel1.Location.Y - 10);
                    }
                    else                                                //如果鼠标滚轮向下滚动
                    {
                        panel1.Top = this.Height - panel1.Height;         //滑块的位置始终为 滑条最底部的位置
                    }
                }
                else if (panel1.Top <= 0)                              //当滑块到达最顶部的时候
                {
                    if (moveway == "down")
                    {
                        panel1.Location = new Point(panel1.Location.X, panel1.Location.Y + 10);
                    }
                    else
                    {
                        panel1.Top = 0;
                    }
                }
                else                        //滑不在顶部和底部时
                {
                    if (moveway == "up")          
                    {
                        panel1.Location = new Point(panel1.Location.X, panel1.Location.Y - 10);
                    }
                    else
                    {
                        panel1.Location = new Point(panel1.Location.X, panel1.Location.Y + 10);
                    }
                }

                if (con != null)            //调整需要滚动条的控件的位置
                {
                    con.Top = baY1 - (panel1.Top - baY) * (panH - winH) / (this.Height - panel1.Height);
                    
                }
                wheel_move = false;         //最后将wheel_move 设置为false 不然滑块可能会一直动
            }
            //鼠标滚轮结束


        }


    }
}


第三步 运用到新的窗口项目中

新建一个用于调试的窗口应用 并创建一个panel控件(将背景颜色改为蓝色便于观察) 3个按钮(有一个按钮在panel的最下面看不到 主要为了测试panel 的向上移动) 和一个刚刚自己定义的滚动条 (如果不知道如何在新窗口引用自己定义的滚动条到工具箱中 请看我的这篇文章

在这里插入图片描述
打开窗口的代码区 添加窗口的load事件函数 添加下面的代码

        private void Form1_Load(object sender, EventArgs e)
        {
            blog_scrollbar1.WinH = this.Height;			//传入窗口的高度
            blog_scrollbar1.control = panel1;			//传入需要滚动条的控件
        }

在这里插入图片描述

第四步 效果展示(由于某些原因下面有些图片没有显示鼠标位置)

此时 拉动滚动条 panel也会动
在这里插入图片描述
如果我们再增加一个按钮 来 主动的改变 panel的位置 会发现滚动条也会跟着变化

        private void button4_Click(object sender, EventArgs e)
        {
            panel1.Location = new Point(panel1.Location.X, panel1.Location.Y - 12);
            blog_scrollbar1.Control_move = true;
        }

当鼠标点击按钮4 的时候 效果如下

在这里插入图片描述

再添加鼠标滚轮事件 实现滚轮控制滑块的运动
步骤如下
先在InitializeComponent();这句代码下面添加下面这句代码

            MouseWheel += new MouseEventHandler(Form1_MouseWheel);

再在控件类中添加下面函数

        private void Form1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta != 0)
            {
                if (e.Delta > 0)
                {
                    blog_scrollbar1.Moveway = "up";
                    blog_scrollbar1.Wheel_move = true;
                }
                else
                {
                    blog_scrollbar1.Moveway = "down";
                    blog_scrollbar1.Wheel_move = true;

                }
            }
        }

然后运行
效果如下

在这里插入图片描述
滚动的幅度可以在控件项目那里的代码修改

附上窗口中的所有代码

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

namespace text_blog_scrollbar
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            MouseWheel += new MouseEventHandler(Form1_MouseWheel);
        }
        private void Form1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta != 0)
            {
                if (e.Delta > 0)
                {
                    blog_scrollbar1.Moveway = "up";
                    blog_scrollbar1.Wheel_move = true;
                }
                else
                {
                    blog_scrollbar1.Moveway = "down";
                    blog_scrollbar1.Wheel_move = true;

                }
            }
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            blog_scrollbar1.WinH = this.Height;
            blog_scrollbar1.control = panel1;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            panel1.Location = new Point(panel1.Location.X, panel1.Location.Y - 12);
            blog_scrollbar1.Control_move = true;
        }

    }
}

  • 9
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
C#自定义控件滚动条实现方法有多种。根据提供的引用内容,我可以为您提供以下方法和步骤来实现滚动条功能: 方法一: 1. 创建一个控件类,可以继承自Panel或者UserControl。该类将作为滚动条的容器。 2. 在该控件类中添加需要滚动的控件作为子控件。 3. 为该控件类添加滚动条控件,可以使用VScrollBar(竖向滚动条)或HScrollBar(横向滚动条控件。 4. 设置滚动条控件的属性,如Maximum(可滚动范围的上限值)、SmallChange(小距离移动值)、LargeChange(大距离移动值)和Value(滚动条的当前位置)。 5. 给滚动条控件的Scroll事件添加处理方法,以便在滚动时对子控件进行相应操作。 方法二: 1. 创建一个视图类,为自定义控件动态添加滚动条,并处理滚动条的显示、隐藏和滚动事件。 2. 在该视图类的构造函数中传入自定义控件实例。 3. 在视图类中创建VScrollBar(竖向滚动条)和HScrollBar(横向滚动条控件,并将其添加到自定义控件中。 4. 设置滚动条控件的属性,如Dock(使滚动条固定在底部或右侧)、Maximum(可滚动范围的上限值)和LargeChange(大距离移动值)。 5. 订阅滚动条控件的事件,如Scroll(滚动条发生滚动时触发事件)和MouseWheel(根据滚轮滚动方向滚动滚动条)。 6. 在事件处理方法中,根据滚动条的值和滚动方向,对自定义控件进行滚动操作。 以上是两种常见的实现滚动条功能的方法。您可以根据自己的需求选择其中一种或根据具体情况进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值