新建一个控件项目 取名叫blog_scrollbar
同时cs文件也改名叫blog_scrollbar
添加一个事时间控件 并配置好相关属性 将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;
}
}
}