查了很多资料,都找不到直接重写ListBox滚动条的方法,只能曲线救国,先自己重绘一个带皮肤的滚动条,然后让它取代ListBox现有的滚动条.
老习惯,先传个效果图,你觉得感兴趣就继续看下去,不喜欢的话就此打住,懒得耽误你宝贵的时间,嘿嘿
注意,此图中的滚动条宽度明显小于ListBox本身滚动条的宽度,我目前只顾着实现功能了,毕竟,宽度调整相当简单哈。
下面简单介绍下重绘系统滚动条的详细步骤:
1.在项目中添加新项--用户控件,我们命名为CustomScrollbar.cs
2.准备几张图片添加进项目资源作为滚动条重绘时要用的背景,我用的图片如下:
uparrow.png资源名称为uparrow ,滚动条的上箭头
ThumbBottom.png资源名称为ThumbBottom ,滚动条中间滑道的背景
ThumbMiddle.png资源名称为ThumbMiddle ,滚动条的中间的拖动块
downarrow.png资源名称为downarrow ,滚动条的下箭头
3.然后就是利用上面图片做背景重画滚动条背景了,直接给出CustomScrollbar.cs的代码吧
Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Diagnostics;
namespace Winamp
{
[Designer(typeof(ScrollbarControlDesigner))]
public partial class CustomScrollbar : UserControl
{
protected Color moChannelColor = Color.Empty;
protected Image moUpArrowImage = null;//上箭头
//protected Image moUpArrowImage_Over = null;
//protected Image moUpArrowImage_Down = null;
protected Image moDownArrowImage = null;//下箭头
//protected Image moDownArrowImage_Over = null;
//protected Image moDownArrowImage_Down = null;
protected Image moThumbArrowImage = null;
protected Image moThumbTopImage = null;
protected Image moThumbTopSpanImage = null;
protected Image moThumbBottomImage = null;
protected Image moThumbBottomSpanImage = null;
protected Image moThumbMiddleImage = null;
protected int moLargeChange = 10;
protected int moSmallChange = 1;
protected int moMinimum = 0;
protected int moMaximum = 100;
protected int moValue = 0;
private int nClickPoint;
protected int moThumbTop = 0;
protected bool moAutoSize = false;
private bool moThumbDown = false;
private bool moThumbDragging = false;
public new event EventHandler Scroll = null;
public event EventHandler ValueChanged = null;
private int GetThumbHeight()
{
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
int nThumbHeight = (int)fThumbHeight;
if (nThumbHeight > nTrackHeight)
{
nThumbHeight = nTrackHeight;
fThumbHeight = nTrackHeight;
}
if (nThumbHeight < 56)
{
nThumbHeight = 56;
fThumbHeight = 56;
}
return nThumbHeight;
}
public CustomScrollbar()
{
InitializeComponent();
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
moChannelColor = Color.FromArgb(51, 166, 3);
UpArrowImage = BASSSkin.uparrow;//上箭头
DownArrowImage = BASSSkin.downarrow;//下肩头
ThumbBottomImage = BASSSkin.ThumbBottom;
ThumbMiddleImage = BASSSkin.ThumbMiddle;
this.Width = UpArrowImage.Width;//18px
base.MinimumSize = new Size(UpArrowImage.Width, UpArrowImage.Height + DownArrowImage.Height + GetThumbHeight());
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("LargeChange")]
public int LargeChange
{
get { return moLargeChange; }
set
{
moLargeChange = value;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("SmallChange")]
public int SmallChange
{
get { return moSmallChange; }
set
{
moSmallChange = value;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("Minimum")]
public int Minimum
{
get { return moMinimum; }
set
{
moMinimum = value;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("Maximum")]
public int Maximum
{
get { return moMaximum; }
set
{
moMaximum = value;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("Value")]
public int Value
{
get { return moValue; }
set
{
moValue = value;
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
int nThumbHeight = (int)fThumbHeight;
if (nThumbHeight > nTrackHeight)
{
nThumbHeight = nTrackHeight;
fThumbHeight = nTrackHeight;
}
if (nThumbHeight < 56)
{
nThumbHeight = 56;
fThumbHeight = 56;
}
//figure out value
int nPixelRange = nTrackHeight - nThumbHeight;
int nRealRange = (Maximum - Minimum) - LargeChange;
float fPerc = 0.0f;
if (nRealRange != 0)
{
fPerc = (float)moValue / (float)nRealRange;
}
float fTop = fPerc * nPixelRange;
moThumbTop = (int)fTop;
Invalidate();
}
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Channel Color")]
public Color ChannelColor
{
get { return moChannelColor; }
set { moChannelColor = value; }
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]
public Image UpArrowImage
{
get { return moUpArrowImage; }
set { moUpArrowImage = value; }
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]
public Image DownArrowImage
{
get { return moDownArrowImage; }
set { moDownArrowImage = value; }
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]
public Image ThumbBottomImage
{
get { return moThumbBottomImage; }
set { moThumbBottomImage = value; }
}
[EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]
public Image ThumbMiddleImage
{
get { return moThumbMiddleImage; }
set { moThumbMiddleImage = value; }
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
if (UpArrowImage != null)
{
e.Graphics.DrawImage(UpArrowImage, new Rectangle(new Point(0, 0), new Size(this.Width, UpArrowImage.Height)));
}
Brush oBrush = new SolidBrush(moChannelColor);
Brush oWhiteBrush = new SolidBrush(Color.FromArgb(255, 255, 255));
// 函数名: rectangle
//功 能: 画一个矩形
//用 法: void far rectangle(int left, int top, int right, int bottom);
//draw channel left and right border colors
e.Graphics.FillRectangle(oWhiteBrush, new Rectangle(0, UpArrowImage.Height, 1, (this.Height - DownArrowImage.Height)));
e.Graphics.FillRectangle(oWhiteBrush, new Rectangle(this.Width - 1, UpArrowImage.Height, 1, (this.Height - DownArrowImage.Height)));
//draw channel
//e.Graphics.FillRectangle(oBrush, new Rectangle(1, UpArrowImage.Height, this.Width-2, (this.Height-DownArrowImage.Height)));
e.Graphics.DrawImage(ThumbBottomImage, new Rectangle(0, UpArrowImage.Height, this.Width, (this.Height - DownArrowImage.Height)));
//draw thumb
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
int nThumbHeight = (int)fThumbHeight;
if (nThumbHeight > nTrackHeight)
{
nThumbHeight = nTrackHeight;
fThumbHeight = nTrackHeight;
}
//MessageBox.Show(nThumbHeight.ToString());
if (nThumbHeight < 56)
{
nThumbHeight = 56;
fThumbHeight = 56;
}
//Debug.WriteLine(nThumbHeight.ToString());
//float fSpanHeight = (fThumbHeight - (ThumbMiddleImage.Height + ThumbTopImage.Height + ThumbBottomImage.Height)) / 2.0f;
//int nSpanHeight = (int)fSpanHeight;
int nTop = moThumbTop;//0
nTop += UpArrowImage.Height;//9px
//draw top画上面的按钮
//e.Graphics.DrawImage(ThumbTopImage, new Rectangle(0, nTop, this.Width, ThumbTopImage.Height));
//nTop += ThumbTopImage.Height;//10px
//draw top span
//Rectangle rect = new Rectangle(1, nTop, this.Width - 2, nSpanHeight);
//e.Graphics.DrawImage(ThumbTopSpanImage, 1.0f,(float)nTop, (float)this.Width-2.0f, (float) fSpanHeight*2);
// nTop += nSpanHeight;//11px
//draw middle
e.Graphics.DrawImage(ThumbMiddleImage, new Rectangle(0, nTop, this.Width, ThumbMiddleImage.Height));
//nTop += ThumbMiddleImage.Height;
//draw top span
//rect = new Rectangle(1, nTop, this.Width - 2, nSpanHeight*2);
//e.Graphics.DrawImage(ThumbBottomSpanImage, rect);
//nTop += nSpanHeight;
//draw bottom
//e.Graphics.DrawImage(ThumbBottomImage, new Rectangle(1, nTop, this.Width - 2, nSpanHeight));
if (DownArrowImage != null)
{
e.Graphics.DrawImage(DownArrowImage, new Rectangle(new Point(0, (this.Height - DownArrowImage.Height)), new Size(this.Width, DownArrowImage.Height)));
}
}
public override bool AutoSize
{
get
{
return base.AutoSize;
}
set
{
base.AutoSize = value;
if (base.AutoSize)
{
this.Width = moUpArrowImage.Width;
}
}
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// CustomScrollbar
//
this.Name = "CustomScrollbar";
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.CustomScrollbar_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.CustomScrollbar_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.CustomScrollbar_MouseUp);
this.ResumeLayout(false);
}
private void CustomScrollbar_MouseDown(object sender, MouseEventArgs e)
{
Point ptPoint = this.PointToClient(Cursor.Position);
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
int nThumbHeight = (int)fThumbHeight;
if (nThumbHeight > nTrackHeight)
{
nThumbHeight = nTrackHeight;
fThumbHeight = nTrackHeight;
}
if (nThumbHeight < 56)
{
nThumbHeight = 56;
fThumbHeight = 56;
}
int nTop = moThumbTop;
nTop += UpArrowImage.Height;
Rectangle thumbrect = new Rectangle(new Point(1, nTop), new Size(ThumbMiddleImage.Width, nThumbHeight));
if (thumbrect.Contains(ptPoint))
{
//hit the thumb
nClickPoint = (ptPoint.Y - nTop);
//MessageBox.Show(Convert.ToString((ptPoint.Y - nTop)));
this.moThumbDown = true;
}
Rectangle uparrowrect = new Rectangle(new Point(1, 0), new Size(UpArrowImage.Width, UpArrowImage.Height));
if (uparrowrect.Contains(ptPoint))
{
int nRealRange = (Maximum - Minimum) - LargeChange;
int nPixelRange = (nTrackHeight - nThumbHeight);
if (nRealRange > 0)
{
if (nPixelRange > 0)
{
if ((moThumbTop - SmallChange) < 0)
moThumbTop = 0;
else
moThumbTop -= SmallChange;
//figure out value
float fPerc = (float)moThumbTop / (float)nPixelRange;
float fValue = fPerc * (Maximum - LargeChange);
moValue = (int)fValue;
Debug.WriteLine(moValue.ToString());
if (ValueChanged != null)
ValueChanged(this, new EventArgs());
if (Scroll != null)
Scroll(this, new EventArgs());
Invalidate();
}
}
}
Rectangle downarrowrect = new Rectangle(new Point(1, UpArrowImage.Height + nTrackHeight), new Size(UpArrowImage.Width, UpArrowImage.Height));
if (downarrowrect.Contains(ptPoint))
{
int nRealRange = (Maximum - Minimum) - LargeChange;
int nPixelRange = (nTrackHeight - nThumbHeight);
if (nRealRange > 0)
{
if (nPixelRange > 0)
{
if ((moThumbTop + SmallChange) > nPixelRange)
moThumbTop = nPixelRange;
else
moThumbTop += SmallChange;
//figure out value
float fPerc = (float)moThumbTop / (float)nPixelRange;
float fValue = fPerc * (Maximum - LargeChange);
moValue = (int)fValue;
Debug.WriteLine(moValue.ToString());
if (ValueChanged != null)
ValueChanged(this, new EventArgs());
if (Scroll != null)
Scroll(this, new EventArgs());
Invalidate();
}
}
}
}
private void CustomScrollbar_MouseUp(object sender, MouseEventArgs e)
{
this.moThumbDown = false;
this.moThumbDragging = false;
}
private void MoveThumb(int y)
{
int nRealRange = Maximum - Minimum;
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
int nThumbHeight = (int)fThumbHeight;
if (nThumbHeight > nTrackHeight)
{
nThumbHeight = nTrackHeight;
fThumbHeight = nTrackHeight;
}
if (nThumbHeight < 56)
{
nThumbHeight = 56;
fThumbHeight = 56;
}
int nSpot = nClickPoint;
int nPixelRange = (nTrackHeight - nThumbHeight);
if (moThumbDown && nRealRange > 0)
{
if (nPixelRange > 0)
{
int nNewThumbTop = y - (UpArrowImage.Height + nSpot);
if (nNewThumbTop < 0)
{
moThumbTop = nNewThumbTop = 0;
}
else if (nNewThumbTop > nPixelRange)
{
moThumbTop = nNewThumbTop = nPixelRange;
}
else
{
moThumbTop = y - (UpArrowImage.Height + nSpot);
}
//figure out value
float fPerc = (float)moThumbTop / (float)nPixelRange;
float fValue = fPerc * (Maximum - LargeChange);
moValue = (int)fValue;
Debug.WriteLine(moValue.ToString());
Application.DoEvents();
Invalidate();
}
}
}
private void CustomScrollbar_MouseMove(object sender,