C#自定义控件之竖滚动条
参考自定义控件滚动条 自:http://www.cnblogs.com/top5/archive/2010/04/29/1724039.html
上面只有水平滚动条,感觉效果不错, 在此基础上修改。 代码bug, 规范请自行处理。
效果一:
说明:
滚动条
Minimun
Maximun
Value
滚动块
SteepDistance 滚动块间隔,设置为0为连续滚动条
SteepHeight 滚动块高度
GradientStyle 滚动块渐变方式
源代码:
View Code
using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Text; using System.Windows.Forms; // Copyright 2004-2005 Marcos Meli - www.MarcosMeli.com.ar namespace FounderUI.UIProgressBar { /// <summary> /// Text 设置文字 /// ColorText 文字颜色 /// GradientStyle 设置滚动条颜色渐变路径 /// SteepDistance 滚动条间距 /// SteepHeight 滚动条宽度 /// </summary> public class XpVerticalProgressBar : Control { #region " Gradient Mode " public enum GradientMode { Vertical, VerticalCenter, Horizontal, HorizontalCenter, Diagonal } ; #endregion #region " Constructor " private const string CategoryName = "Xp Vertical ProgressBar"; public XpVerticalProgressBar() { } #endregion #region " Private Fields " private Color mColor1 = Color.FromArgb(170, 240, 170); private Color mColor2 = Color.FromArgb(10, 150, 10); private Color mColorBackGround = Color.White; private Color mColorText = Color.Black; private Image mDobleBack = null; private GradientMode mGradientStyle = GradientMode.VerticalCenter; private int mMax = 100; private int mMin = 0; private int mValue = 50; private byte mSteepDistance = 2; private byte mSteepHeight = 6; #endregion #region " Dispose " protected override void Dispose(bool disposing) { if (!this.IsDisposed) { if (mDobleBack != null) { mDobleBack.Dispose(); } if (mBrush1 != null) { mBrush1.Dispose(); } if (mBrush2 != null) { mBrush2.Dispose(); } base.Dispose(disposing); } } #endregion #region " Colors " [Category(CategoryName)] [Description("The Back Color of the Progress Bar")] public Color ColorBackGround { get { return mColorBackGround; } set { mColorBackGround = value; this.InvalidateBuffer(true); } } [Category(CategoryName)] [Description("The Border Color of the gradient in the Progress Bar")] public Color ColorBarBorder { get { return mColor1; } set { mColor1 = value; this.InvalidateBuffer(true); } } [Category(CategoryName)] [Description("The Center Color of the gradient in the Progress Bar")] public Color ColorBarCenter { get { return mColor2; } set { mColor2 = value; this.InvalidateBuffer(true); } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [RefreshProperties(RefreshProperties.Repaint)] [Description("Set to TRUE to reset all colors like the Windows XP Progress Bar?")] [Category(CategoryName)] [DefaultValue(false)] public bool ColorsXP { get { return false; } set { ColorBarBorder = Color.FromArgb(170, 240, 170); ColorBarCenter = Color.FromArgb(10, 150, 10); ColorBackGround = Color.White; } } [Category(CategoryName)] [Description("The Color of the text displayed in the Progress Bar")] public Color ColorText { get { return mColorText; } set { mColorText = value; if (this.Text != String.Empty) { this.Invalidate(); } } } #endregion #region " Value " [RefreshProperties(RefreshProperties.Repaint)] [Category(CategoryName)] [Description("The Current Value of the Progress Bar")] public int Value { get { return mValue; } set { if (value > mMax) { mValue = mMax; } else if (value < mMin) { mValue = mMin; } else { mValue = value; } this.Invalidate(); } } [RefreshProperties(RefreshProperties.Repaint)] [Category(CategoryName)] [Description("The Max Value of the Progress Bar")] public int Maximum { get { return mMax; } set { if (value > mMin) { mMax = value; if (mValue > mMax) { Value = mMax; } this.InvalidateBuffer(true); } } } [RefreshProperties(RefreshProperties.Repaint)] [Category(CategoryName)] [Description("The Min Value of the Progress Bar")] public int Minimum { get { return mMin; } set { if (value < mMax) { mMin = value; if (mValue < mMin) { Value = mMin; } this.InvalidateBuffer(true); } } } [Category(CategoryName)] [Description("The number of Pixels between two Steeps in Progress Bar")] [DefaultValue((byte)2)] public byte SteepDistance { get { return mSteepDistance; } set { if (value >= 0) { mSteepDistance = value; this.InvalidateBuffer(true); } } } #endregion #region " Progress Style " [Category(CategoryName)] [Description("The Style of the gradient bar in Progress Bar")] [DefaultValue(GradientMode.VerticalCenter)] public GradientMode GradientStyle { get { return mGradientStyle; } set { if (mGradientStyle != value) { mGradientStyle = value; CreatePaintElements(); this.Invalidate(); } } } [Category(CategoryName)] [Description("The number of Pixels of the Steeps in Progress Bar")] [DefaultValue((byte)6)] public byte SteepHeight { get { return mSteepHeight; } set { if (value > 0) { mSteepHeight = value; this.InvalidateBuffer(true); } } } #endregion #region " BackImage " [RefreshProperties(RefreshProperties.Repaint)] [Category(CategoryName)] public override Image BackgroundImage { get { return base.BackgroundImage; } set { base.BackgroundImage = value; InvalidateBuffer(); } } #endregion #region " Text Override " [Category(CategoryName)] [Description("The Text displayed in the Progress Bar")] [DefaultValue("")] public override string Text { get { return base.Text; } set { if (base.Text != value) { base.Text = value; this.Invalidate(); } } } #endregion #region " Text Shadow " private bool mTextShadow = true; [Category(CategoryName)] [Description("Set the Text shadow in the Progress Bar")] [DefaultValue(false)] public bool TextShadow { get { return mTextShadow; } set { mTextShadow = value; this.Invalidate(); } } #endregion #region " Text Shadow Alpha " private byte mTextShadowAlpha = 150; [Category(CategoryName)] [Description("Set the Alpha Channel of the Text shadow in the Progress Bar")] [DefaultValue((byte)150)] public byte TextShadowAlpha { get { return mTextShadowAlpha; } set { if (mTextShadowAlpha != value) { mTextShadowAlpha = value; this.TextShadow = true; } } } #endregion #region " Paint Methods " #region " OnPaint " protected override void OnPaint(PaintEventArgs e) { //System.Diagnostics.Debug.WriteLine("Paint " + this.Name + " Pos: "+this.Value.ToString()); if (!this.IsDisposed) { //滚动条height int mSteepTotal = mSteepHeight + mSteepDistance; // float mUtilHeight = this.Height - 6 + mSteepDistance; if (mDobleBack == null) { mUtilHeight = this.Height - 6 + mSteepDistance; int mMaxSteeps = (int)(mUtilHeight / mSteepTotal); this.Height = 6 + mSteepTotal * mMaxSteeps; mDobleBack = new Bitmap(this.Width, this.Height); Graphics g2 = Graphics.FromImage(mDobleBack); CreatePaintElements(); g2.Clear(mColorBackGround); if (this.BackgroundImage != null) { TextureBrush textuBrush = new TextureBrush(this.BackgroundImage, WrapMode.Tile); g2.FillRectangle(textuBrush, 0, 0, this.Width, this.Height); textuBrush.Dispose(); } g2.DrawRectangle(mPenOut2, outnnerRect2); g2.DrawRectangle(mPenOut, outnnerRect); g2.DrawRectangle(mPenIn, innerRect); g2.Dispose(); } Image ima = new Bitmap(mDobleBack); Graphics gtemp = Graphics.FromImage(ima); int mCantSteeps = (int)((((float)mValue - mMin) / (mMax - mMin)) * mUtilHeight / mSteepTotal); for (int i = 0; i < mCantSteeps; i++) { DrawSteep(gtemp, i); } if (this.Text != String.Empty) { gtemp.TextRenderingHint = TextRenderingHint.AntiAlias; DrawCenterString(gtemp, this.ClientRectangle); } e.Graphics.DrawImage(ima, e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle, GraphicsUnit.Pixel); ima.Dispose(); gtemp.Dispose(); } } protected override void OnPaintBackground(PaintEventArgs e) { } #endregion #region " OnSizeChange " protected override void OnSizeChanged(EventArgs e) { if (!this.IsDisposed) { if (this.Width < 12) { this.Width = 12; } base.OnSizeChanged(e); this.InvalidateBuffer(true); } } protected override Size DefaultSize { get { return new Size(29, 100); } } #endregion #region " More Draw Methods " private void DrawSteep(Graphics g, int number) { number++; g.FillRectangle(mBrush1, mSteepRect1.X + 1,this.Height - (2 + number * (mSteepDistance + mSteepHeight)), mSteepRect1.Width, mSteepHeight); g.FillRectangle(mBrush2, mSteepRect2.X + 1,this.Height - (2 + number * (mSteepDistance + mSteepHeight)), mSteepRect2.Width - 1, mSteepHeight); } private void InvalidateBuffer() { InvalidateBuffer(false); } private void InvalidateBuffer(bool InvalidateControl) { if (mDobleBack != null) { mDobleBack.Dispose(); mDobleBack = null; } if (InvalidateControl) { this.Invalidate(); } } private void DisposeBrushes() { if (mBrush1 != null) { mBrush1.Dispose(); mBrush1 = null; } if (mBrush2 != null) { mBrush2.Dispose(); mBrush2 = null; } } private void DrawCenterString(Graphics gfx, Rectangle box) { float left = 0; float top = 0; SizeF ss = gfx.MeasureString(this.Text, this.Font); top = box.Height - (box.Height - ss.Width) / 2; left = ((box.Width - ss.Height) / 2); gfx.TranslateTransform(left, top); gfx.RotateTransform(270); //gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; if (mTextShadow) { SolidBrush mShadowBrush = new SolidBrush(Color.FromArgb(mTextShadowAlpha, Color.Black)); gfx.DrawString(this.Text, this.Font, mShadowBrush, -1, -1); mShadowBrush.Dispose(); } SolidBrush mTextBrush = new SolidBrush(mColorText); gfx.DrawString(this.Text, this.Font, mTextBrush, 0, 0); mTextBrush.Dispose(); /* float vlblControlWidth; float vlblControlHeight; float vlblTransformX; float vlblTransformY; SolidBrush labelForeColorBrush = new SolidBrush(base.ForeColor); vlblControlWidth = this.Size.Width; vlblControlHeight = this.Size.Height; //gfx.TextRenderingHint = this._renderMode; gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; vlblTransformX = 0; vlblTransformY = vlblControlHeight; gfx.TranslateTransform(vlblTransformX, vlblTransformY); gfx.RotateTransform(270); gfx.DrawString(this.Text, Font, labelForeColorBrush, 0, 0); labelForeColorBrush.Dispose(); */ } #endregion #region " CreatePaintElements " private Rectangle innerRect; private LinearGradientBrush mBrush1; private LinearGradientBrush mBrush2; private Pen mPenIn = new Pen(Color.FromArgb(239, 239, 239)); private Pen mPenOut = new Pen(Color.FromArgb(104, 104, 104)); private Pen mPenOut2 = new Pen(Color.FromArgb(190, 190, 190)); private Rectangle mSteepRect1; private Rectangle mSteepRect2; private Rectangle outnnerRect; private Rectangle outnnerRect2; private void CreatePaintElements() { DisposeBrushes(); switch (mGradientStyle) { case GradientMode.HorizontalCenter: //中间渐变 mSteepRect1 = new Rectangle( 3, 0, this.Width / 2 + (int)(this.Width * 0.05), mSteepHeight); mBrush1 = new LinearGradientBrush(mSteepRect1, mColor1, mColor2, LinearGradientMode.Horizontal); mSteepRect2 = new Rectangle( mSteepRect1.Right - 1, 0, this.Width - mSteepRect1.Width - 4, mSteepHeight); mBrush2 = new LinearGradientBrush(mSteepRect2, mColor2, mColor1, LinearGradientMode.Horizontal); break; case GradientMode.Horizontal: //左渐变右 mSteepRect1 = new Rectangle( 3, 0, this.Width - 7, mSteepHeight); mBrush1 = new LinearGradientBrush(mSteepRect1, mColor1, mColor2, LinearGradientMode.Horizontal); mSteepRect2 = new Rectangle( -100, -100, 1, 1); mBrush2 = new LinearGradientBrush(mSteepRect2, mColor2, mColor1, LinearGradientMode.Horizontal); break; case GradientMode.Vertical: //下渐变上 mSteepRect1 = new Rectangle( 3, 0, this.Width-7, mSteepHeight); // mBrush1 = new LinearGradientBrush(rTemp, mColor1, mColor2, LinearGradientMode.Horizontal); mBrush1 = new LinearGradientBrush(this.ClientRectangle, mColor1, mColor2, LinearGradientMode.Vertical); mSteepRect2 = new Rectangle( -100, -100, 1, 1); mBrush2 = new LinearGradientBrush(mSteepRect2, Color.Red, Color.Red, LinearGradientMode.Vertical); break; case GradientMode.VerticalCenter: //中间渐变 mSteepRect1 = new Rectangle( 3, 0, this.Width - 7, mSteepHeight); // mBrush1 = new LinearGradientBrush(rTemp, mColor1, mColor2, LinearGradientMode.Horizontal); mBrush1 = new LinearGradientBrush(this.ClientRectangle, mColor1, mColor2, LinearGradientMode.Vertical); mBrush1.SetBlendTriangularShape(0.5f); mSteepRect2 = new Rectangle( -100, -100, 1, 1); mBrush2 = new LinearGradientBrush(mSteepRect2, Color.Red, Color.Red, LinearGradientMode.Vertical); break; case GradientMode.Diagonal: //对角渐变 mSteepRect1 = new Rectangle( 3, 0, this.Width - 7, mSteepHeight); // mBrush1 = new LinearGradientBrush(rTemp, mColor1, mColor2, LinearGradientMode.ForwardDiagonal); mBrush1 = new LinearGradientBrush(this.ClientRectangle, mColor1, mColor2, LinearGradientMode.ForwardDiagonal); // ((LinearGradientBrush) mBrush1).SetBlendTriangularShape(0.5f); mSteepRect2 = new Rectangle( -100, -100, 1, 1); mBrush2 = new LinearGradientBrush(mSteepRect2, Color.Red, Color.Red, LinearGradientMode.Horizontal); break; default: mBrush1 = new LinearGradientBrush(mSteepRect1, mColor1, mColor2, LinearGradientMode.Vertical); mBrush2 = new LinearGradientBrush(mSteepRect2, mColor2, mColor1, LinearGradientMode.Vertical); break; } innerRect = new Rectangle( this.ClientRectangle.X + 2, this.ClientRectangle.Y + 2, this.ClientRectangle.Width - 4, this.ClientRectangle.Height - 4); outnnerRect = new Rectangle( this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1); outnnerRect2 = new Rectangle( this.ClientRectangle.X + 1, this.ClientRectangle.Y + 1, this.ClientRectangle.Width, this.ClientRectangle.Height); } #endregion #endregion } }