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 }
(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; }