最近做了一个可自定义皮肤的滚动条,
直接上效果图:
其中ScrollStyle属性中内置了3中样式和可自定义皮肤的样式(Custom):
下面为三种内置样式的效果图:
下面是选择Custom样式后自定义皮肤:
只要有漂亮的素材,就可以通过属性加进来,迅速自定义出一套好看的皮肤。
实现思路:
继承Control,写好基本的功能后,把所有涉及到样式的属性全部外放出来。
以下是部分代码:
public class MyScrollBar : Control
OnPaint绘图:DrawThumb绘制滑块,DrawArrowButton绘制箭头
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
Rectangle rect = ClientRectangle;
DrawThumb(e.Graphics, this.thumbState, this.orientation);
DrawArrowButton(e.Graphics, this.topButtonState, this.orientation);
if (this.topBarClicked)
{
if (this.orientation == ScrollBarOrientation.Vertical)
{
this.clickedBarRectangle.Y = this.thumbTopLimit;
this.clickedBarRectangle.Height =
this.thumbRectangle.Y - this.thumbTopLimit;
}
else
{
this.clickedBarRectangle.X = this.thumbTopLimit;
this.clickedBarRectangle.Width =
this.thumbRectangle.X - this.thumbTopLimit;
}
else if (this.bottomBarClicked)
{
if (this.orientation == ScrollBarOrientation.Vertical)
{
this.clickedBarRectangle.Y = this.thumbRectangle.Bottom + 1;
this.clickedBarRectangle.Height =
this.thumbBottomLimitBottom - this.clickedBarRectangle.Y + 1;
}
else
{
this.clickedBarRectangle.X = this.thumbRectangle.Right + 1;
this.clickedBarRectangle.Width =
this.thumbBottomLimitBottom - this.clickedBarRectangle.X + 1;
}
}
}
DrawThumb绘制滑块,_arrowbtns中存储了上下左右以及hover的图片,共8张,通过对给定的一张箭头图片和一张箭头hover进行旋转得到的。
/// <summary>
/// 初始化箭头图标
/// </summary>
/// <returns></returns>
private Bitmap[] InitArrawBtns()
{
if (ArrowImage == null || ArrowHoverImage == null || ArrowHeight == 0 || ArrowWidth == 0) return null;
Bitmap[] result = new Bitmap[8];
for (int i = 0; i < result.Length; i++)
{
result[i] = new Bitmap(ArrowWidth, ArrowHeight);
}
result[0] = new Bitmap(ArrowImage);
result[1] = new Bitmap(ArrowHoverImage);
Graphics g1 = Graphics.FromImage(result[2]);
g1.DrawImage(ArrowImage, Point.Empty);
result[2].RotateFlip(RotateFlipType.Rotate180FlipNone);
Graphics g2 = Graphics.FromImage(result[3]);
g2.DrawImage(ArrowHoverImage, Point.Empty);
result[3].RotateFlip(RotateFlipType.Rotate180FlipNone);
Graphics g3 = Graphics.FromImage(result[4]);
g3.DrawImage(ArrowImage, Point.Empty);
result[4].RotateFlip(RotateFlipType.Rotate90FlipNone);
Graphics g4 = Graphics.FromImage(result[5]);
g4.DrawImage(ArrowHoverImage, Point.Empty);
result[5].RotateFlip(RotateFlipType.Rotate90FlipNone);
Graphics g5 = Graphics.FromImage(result[6]);
g5.DrawImage(ArrowImage, Point.Empty);
result[6].RotateFlip(RotateFlipType.Rotate270FlipNone);
Graphics g6 = Graphics.FromImage(result[7]);
g6.DrawImage(ArrowHoverImage, Point.Empty);
result[7].RotateFlip(RotateFlipType.Rotate270FlipNone);
g1.Dispose();
g2.Dispose();
g3.Dispose();
g4.Dispose();
g5.Dispose();
g6.Dispose();
return result;
}
private void DrawArrowButton(Graphics g, ScrollBarState state, ScrollBarOrientation orientation)
{
if (_arrowbtns == null) return;
int index = 0;
if (state == ScrollBarState.Pressed | state == ScrollBarState.Hot | state == ScrollBarState.Active)
{
index = 1;
}
if (orientation == ScrollBarOrientation.Vertical)
{
g.DrawImage(_arrowbtns[0 + index], this.topArrowRectangle);
g.DrawImage(_arrowbtns[2 + index], this.bottomArrowRectangle);
}
else
{
g.DrawImage(_arrowbtns[4 + index], this.bottomArrowRectangle);
g.DrawImage(_arrowbtns[6 + index], this.topArrowRectangle);
}
}
DrawThumb绘制滑块,里面内置了3种样式的绘制,绘制时分上中下3部分绘制,因为滑块需要拉升,那么就只对中间部分拉升,绘制中间部分时就对其进行动态控制。
private void DrawThumb(Graphics g, ScrollBarState state, ScrollBarOrientation orientation)
{
Image thumbImg;
if (state == ScrollBarState.Pressed | state == ScrollBarState.Hot | state == ScrollBarState.Active)
{
if (this.ScrollStyle == ScrollExStyle.thickSlideway)
{
thumbImg = thumbMid2;
}
else if (ScrollStyle == ScrollExStyle.noSlideway || ScrollStyle == ScrollExStyle.thinSlideway)
{
thumbImg = thumbMid_hover;
}
else
{
thumbImg = thumbHoverImage;
}
}
else
{
if (this.ScrollStyle == ScrollExStyle.thickSlideway)
{
thumbImg = thumbMid2;
}
else if (ScrollStyle == ScrollExStyle.noSlideway || ScrollStyle == ScrollExStyle.thinSlideway)
{
thumbImg = thumbMid1;
}
else
{
thumbImg = ThumbImage;
}
}
int x = this.thumbRectangle.X;
int y = this.thumbRectangle.Y;
using (ImageAttributes ImgAtt = new ImageAttributes())
{
ImgAtt.SetWrapMode(System.Drawing.Drawing2D.WrapMode.Tile);
if (orientation == ScrollBarOrientation.Vertical)
{
if (thumbImg == null) return;
if (thumbImg.Width > thumbImg.Height) thumbImg.RotateFlip(RotateFlipType.Rotate270FlipNone);
//画中间部分
g.DrawImage(thumbImg, new Rectangle(x, y + 3, thumbRectangle.Width, this.thumbRectangle.Height - 6),
0, 3, thumbImg.Width, thumbImg.Height - 6, GraphicsUnit.Pixel, ImgAtt);
//画上部分
g.DrawImage(thumbImg, new Rectangle(x, y, thumbRectangle.Width, 3),
0, 0, thumbImg.Width, 3, GraphicsUnit.Pixel, ImgAtt);
//画下部分
g.DrawImage(thumbImg, new Rectangle(x, thumbRectangle.Bottom - 3, ThumbWidth, 3),
0, thumbImg.Height - 3, thumbImg.Width, 3, GraphicsUnit.Pixel, ImgAtt);
}
else
{
if (thumbImg == null) return;
///画中间部分
if (thumbImg.Width < thumbImg.Height) thumbImg.RotateFlip(RotateFlipType.Rotate270FlipNone);
g.DrawImage(thumbImg, new Rectangle(x + 3, y, this.thumbRectangle.Width - 6, this.thumbRectangle.Height),
3, 0, thumbImg.Width - 6, thumbImg.Height, GraphicsUnit.Pixel, ImgAtt);
///画上部分
g.DrawImage(thumbImg, new Rectangle(x, y, 3, thumbRectangle.Height),
0, 0, 3, thumbImg.Height, GraphicsUnit.Pixel, ImgAtt);
///画下部分
g.DrawImage(thumbImg, new Rectangle(thumbRectangle.Right - 3, y, 3, thumbRectangle.Height),
thumbImg.Width - 3, 0, 3, thumbImg.Height, GraphicsUnit.Pixel, ImgAtt);
}
}
}
然后将所有属性加到属性控制面板上去:
[Category("自定义属性")]
[Description("滚动条方向")]
[DefaultValue(ScrollBarOrientation.Vertical)]
public ScrollBarOrientation Orientation
{
get
{
return this.orientation;
}
set
{
if (value == this.orientation)
{
return;
}
this.orientation = value;
this.scrollOrientation = value == ScrollBarOrientation.Vertical ?
ScrollOrientation.VerticalScroll : ScrollOrientation.HorizontalScroll;
this.Size = new Size(this.Height, this.Width);
this.SetUpScrollBar();
}
}
[Category("自定义属性")]
[Description("滚动条样式")]
public ScrollExStyle ScrollStyle
{
get { return scrollStyle; }
set
{
if (scrollStyle != value)
{
scrollStyle = value;
SetBackImage();
}
}
}
[Category("自定义属性")]
[Description("滚动条背景图片")]
public Image BackImage
{
get { return backImage; }
set
{
if (backImage != value)
{
backImage = value;
Invalidate();
}
}
}
[Category("自定义属性")]
[Description("滑块背景图片")]
public Image ThumbImage
{
get
{
return thumbImage;
}
set
{
if (thumbImage != value)
{
thumbImage = value;
_arrowbtns = InitArrawBtns();
Invalidate();
}
}
}
[Category("自定义属性")]
[Description("滑块经过图片")]
public Image ThumbHoverImage
{
get { return thumbHoverImage; }
set
{
if (thumbHoverImage != value)
{
thumbHoverImage = value;
_arrowbtns = InitArrawBtns();
Invalidate();
}
}
}
[Category("自定义属性")]
[Description("箭头图标")]
public Image ArrowImage
{
get { return arrowImage; }
set
{
if (arrowImage != value)
{
arrowImage = value;
_arrowbtns = InitArrawBtns();
Invalidate();
}
}
}
[Category("自定义属性")]
[Description("箭头鼠标悬停图标")]
public Image ArrowHoverImage
{
get { return arrowHoverImage; }
set
{
if (arrowHoverImage != value)
{
arrowHoverImage = value;
_arrowbtns = InitArrawBtns();
Invalidate();
}
}
}
[Category("自定义属性")]
[Description("滑块宽度")]
[DefaultValue(11)]
public int ThumbWidth
{
get { return thumbWidth; }
set
{
if (thumbWidth != value)
{
thumbWidth = value;
this.SetUpScrollBar();
}
}
}
[Category("自定义属性")]
[Description("滑块高度")]
[DefaultValue(11)]
public int ThumbHeight
{
get { return thumbHeight; }
set
{
if (thumbHeight != value)
{
thumbHeight = value;
this.SetUpScrollBar();
this.Invalidate();
}
}
}
[Category("自定义属性")]
[Description("箭头宽度")]
[DefaultValue(0)]
public int ArrowWidth
{
get { return arrowWidth; }
set
{
if (arrowWidth != value)
{
arrowWidth = value;
//SetUpScrollBar();
//Invalidate();
}
}
}
[Category("自定义属性")]
[Description("箭头高度")]
[DefaultValue(0)]
public int ArrowHeight
{
get { return arrowHeight; }
set
{
if (arrowHeight != value)
{
arrowHeight = value;
//SetUpScrollBar();
// Invalidate();
}
}
}