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 = ; /// <summary>
/// 内容面板高度
/// </summary>
private int ContentPanelHeight = ; /// <summary>
/// 滚动条滑块鼠标左键是否按下
/// </summary>
private bool IsLeftKeyDown_ScrollBar = false; /// <summary>
/// 滚动条背景板鼠标左键是否按下
/// </summary>
private bool IsLeftKeyDown_ScrollBg = false; /// <summary>
/// 鼠标相对有屏幕的Y坐标
/// </summary>
private int MouseYToScreen = ; #endregion public ScrollBarBg()
{
InitializeComponent();
this.ScrollBar.Top = ;
this.MouseWheel += ScrollBar_MouseWheel;
ScrollBar.MouseWheel += ScrollBar_MouseWheel;
ScrollTimer = new Timer();
ScrollTimer.Interval = ;
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 = ;
public int MouseWheelUnitHeight
{
set { mouseWheelUnitHeight = value; }
get { return mouseWheelUnitHeight; }
} /// <summary>
/// 长按滚动条背景框滑块滚动的单位高度,影响滚动速度
/// </summary>
private int timerScrollUnitHeight = ;
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 > ? 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 / ;
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 / > 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 <= )
this.ScrollBar.Top = ;
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
}
(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 = ;
} private void PnContent_MouseWheel(object sender, MouseEventArgs e)
{
scrollBarBg1.ContentPanelMouseWheel(sender, e);
} private void ScrollBarScroll(int y)
{
this.pnContent.Top = y;
}
C#winform自定义滚动条的更多相关文章
- (八十九)c#Winform自定义控件-自定义滚动条(treeview、panel、datagridview、listbox、listview、textbox)
官网 http://www.hzhcontrols.com/ 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kw ...
- 自定义滚动条(Custom ScrollBar)
时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...
- CSS3自定义滚动条样式 -webkit-scrollbar(转)
有没有觉得浏览器自带的原始滚动条很不美观,同时也有看到很多网站的自定义滚动条显得高端,就连chrome32.0开发板都抛弃了原始的滚动条,美观多了.那webkit浏览器是如何自定义滚动条的呢? 前言 ...
- jquery自定义滚动条 鼠标移入或滚轮时显示 鼠标离开或悬停超时时隐藏
一.需求: 我需要做一个多媒体播放页面,左侧为播放列表,右侧为播放器.为了避免系统滚动条把列表和播放器隔断开,左侧列表的滚动条需要自定义,并且滚动停止和鼠标离开时要隐藏掉. 二.他山之石: 案例来自h ...
- 利用JS实现自定义滚动条
一般默认的滚动条会比较丑,我们可以用简单的js实现自定义滚动条的功能: 代码如下: <!doctype html> <html> <head> <meta c ...
- javascript 学习之自定义滚动条加滚轮事件
要自己写一个自定义滚动条加上滚轮事件,之前的没有滚轮事件不完整,今天整理了一个. 1.滚轮事件是不兼容的,firefox中是必需要用事件绑定的添加,用的DOMMouseScroll,当滚动鼠标的时候, ...
- 自定义滚动条 - mCustomScrollbar
项目中需要使用自定义滚动条,但是试用了很多都功能不够全,今天发现一个比较全而且用法很简单的 -- mCustomScrollbar http://manos.malihu.gr/jquery-cust ...
- Flex:自定义滚动条样式/隐藏上下箭头
Flex组件自定义滚动条的实现 .scrollBar{ downArrowUpSkin:Embed(source="img/mainLeftScrollBar/bar_bottom.png& ...
- javascript自定义滚动条插件,几行代码的事儿
在实际项目中,经常由于浏览器自带的滚动条样式太戳,而且在各个浏览器中显示不一样,所以我们不得不去实现自定义的滚动条,今天我就用最少的代码实现了一个自定义滚动条,代码量区区只有几十行,使用起来也非常方便 ...
随机推荐
- 【MATLAB】读取和写入文本文件
在MATLAB中,来读取和写入文本文件是很简单的事.下面,就来简单介绍下.如果有其他问题,请留言. 一.读取文本文件 思路: 1.用fopen来打开一个文件句柄 2.用fgetl来获得文件中的一行,如 ...
- Redis实战——安装
借鉴来源:https://www.cnblogs.com/codersay/p/4301677.html redis官网地址:http://www.redis.io/ 最新版本: redis-4.0. ...
- UGUI 自动布局的重叠BUG
1,父级使用了verticalLayout(注意没有ContentSizeFilter),子级使用了ContentSizeFilter时,点击Apply常常发现,本来布局好的UI突然重叠到了一起,或位 ...
- MantisBT 缺陷管理系统
简介: 公司需要一套缺陷管理系统,这种系统比较热门的有 Jira.Redmine.MantisBT 等. 这次来整理一下 MantisBT,正好公司需要,以前的文档又丢失了. 下载地址:http:// ...
- 花了好几个小时的奇葩Mat为0问题
问题 1. Mat mserMat = adaptive_image_from_points(contour, rect); CCharacter character; character.setCh ...
- 智能合约调用另一合约中的payable方法
参考链接: https://ethereum.stackexchange.com/questions/9705/how-can-you-call-a-payable-function-in-anoth ...
- code1744 方格染色
稍微复杂一点的划分dp 设f[i][j][k]为第i行前j个k次粉刷正确的最大值 由于每行循环使用,可以去掉第一维,但每次不要忘了清零(卡了好久) f[j][k]=max{ f[u][j-1] + m ...
- Fix “Could Not Find This Item” When Deleting in Windows 7
If you’ve been using Windows for as long as I have, you have probably run into your share of weird e ...
- LWIP数据包管理
- 4.4.4 无锁的对象引用:AtomicReference和AtomicStampedReference
AtomicReference 这个类和AtomicInteger非常类似,只是AtomicReference对应普通的对象引用,而AtomicInteger 它是对整数的封装,它的方法如下 对wea ...