public partial class TabControlExt : TabControl { private AnimationTimer animation; ////// 动画组件对象 /// [Description("动画组件对象")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public AnimationTimer Animation { get { return this.animation; } set { this.animation = value; } } private Size leftTopRadius = new Size(0, 0); /// /// 左上角圆角 /// [Description("左上角圆角")] [DefaultValue(typeof(Size), "0,0")] public Size LeftTopRadius { get { return this.leftTopRadius; } set { this.leftTopRadius = value; this.Invalidate(); } } private Size rightTopRadius = new Size(0, 0); /// /// 右上角圆角 /// [Description("右上角圆角")] [DefaultValue(typeof(Size), "0,0")] public Size RightTopRadius { get { return this.rightTopRadius; } set { this.rightTopRadius = value; this.Invalidate(); } } private Size rightBottomRadius = new Size(0, 0); /// /// 右下角圆角 /// [Description("右下角圆角")] [DefaultValue(typeof(Size), "0,0")] public Size RightBottomRadius { get { return this.rightBottomRadius; } set { this.rightBottomRadius = value; this.Invalidate(); } } private Size leftBottomRadius = new Size(0, 0); /// /// 左下角圆角 /// [Description("左下角圆角")] [DefaultValue(typeof(Size), "0,0")] public Size LeftBottomRadius { get { return this.leftBottomRadius; } set { this.leftBottomRadius = value; this.Invalidate(); } } private Size tabImageSize = new Size(20, 20); /// /// tab选项图标大小 /// [Description("左下角圆角")] [DefaultValue(typeof(Size), "20,20")] public Size TabImageSize { get { return this.tabImageSize; } set { this.tabImageSize = value; this.Invalidate(); } } private Color backColor = Color.White; /// /// TabContorl背景颜色 /// [EditorBrowsable(EditorBrowsableState.Always)] [Description("TabContorl背景颜色")] [DefaultValue(typeof(Color), "White")] public override Color BackColor { get { return this.backColor; } set { this.backColor = value; base.Invalidate(true); } } private Color borderColor = Color.FromArgb(128, 170, 42); /// /// TabContorl边框色 /// [DefaultValue(typeof(Color), "128, 170, 42")] [Description("TabContorl边框色")] public Color BorderColor { get { return this.borderColor; } set { this.borderColor = value; base.Invalidate(true); } } private Color tabBackColor = Color.OliveDrab; /// /// Tab背景颜色 /// [DefaultValue(typeof(Color), "OliveDrab")] [Description("Tab背景颜色")] public Color TabBackColor { get { return this.tabBackColor; } set { this.tabBackColor = value; base.Invalidate(); } } private Color tabSelectedBackColor = Color.FromArgb(128, 170, 42); /// /// Tab选中背景颜色 /// [DefaultValue(typeof(Color), "128, 170, 42")] [Description("Tab选中背景颜色")] public Color TabSelectedBackColor { get { return this.tabSelectedBackColor; } set { this.tabSelectedBackColor = value; base.Invalidate(); } } private Color tabTextColor = Color.White; /// /// Tab文本颜色 /// [DefaultValue(typeof(Color), "White")] [Description("Tab文本颜色")] public Color TabTextColor { get { return this.tabTextColor; } set { this.tabTextColor = value; base.Invalidate(); } } private StringAlignment tabTextAlignment = StringAlignment.Near; /// /// Tab选中文本对齐方式 /// [DefaultValue(StringAlignment.Near)] [Description("Tab选中文本对齐方式")] public StringAlignment TabTextAlignment { get { return tabTextAlignment; } set { tabTextAlignment = value; base.Invalidate(); } } private Color tabSelectedTextColor = Color.White; /// /// Tab选中文本颜色 /// [DefaultValue(typeof(Color), "White")] [Description("Tab选中文本颜色")] public Color TabSelectedTextColor { get { return this.tabSelectedTextColor; } set { this.tabSelectedTextColor = value; base.Invalidate(); } } private int mouseEnterTabIndex = -1; /// /// 鼠标是否进入Tab选项 /// [Description("鼠标是否进入Tab选项")] [DefaultValue(-1)] [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Always)] public int MouseEnterTabIndex { get { return this.mouseEnterTabIndex; } set { if (this.mouseEnterTabIndex != value) { this.mouseEnterTabIndex = value; if (value != -1) { this.MouseEnterTabRect = this.GetTabRect(this.mouseEnterTabIndex); this.animation.AT = AnimationType.ElasticOut; this.animation.Start(true, 0.0); } } } } /// /// 要变换的Tab原始值 /// private Rectangle MouseEnterTabRect; /// /// 要变换的Tab /// private Rectangle transformTabRect = new Rectangle(); private int tabImageMarginLeft = 4; #region private const int WM_SETFONT = 0x30; private const int WM_FONTCHANGE = 0x1d; [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); #endregion public TabControlExt() : base() { base.SetStyle( ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); base.UpdateStyles(); this.animation = new AnimationTimer(this, new AnimationOptions()); this.Animation.AnimationIng += new AnimationTimer.AnimationHandel(this.Animation_AnimationIng); } /// /// Tab变换动画 /// /// /// protected void Animation_AnimationIng(object sender, AnimationEventArgs e) { this.transformTabRect.Width = (int)((double)this.MouseEnterTabRect.Width + e.Transform * e.progressTime); this.transformTabRect.Height = (int)((double)this.MouseEnterTabRect.Height + e.Transform * e.progressTime); this.transformTabRect.X = this.MouseEnterTabRect.X + (int)((this.MouseEnterTabRect.Width - this.transformTabRect.Width) / 2.0); this.transformTabRect.Y = this.MouseEnterTabRect.Y + (int)((this.MouseEnterTabRect.Height - this.transformTabRect.Height) / 2.0); this.Invalidate(); } /// /// 鼠标进入Tab选项 /// /// protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); for (int i = 0; i < this.TabCount; i++) { if (this.GetTabRect(i).Contains(e.Location)) { this.MouseEnterTabIndex = i; return; } } this.MouseEnterTabIndex = -1; } /// /// 鼠标离开控件可视区 /// /// protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); this.MouseEnterTabIndex = -1; this.Invalidate(); } /// /// /// /// protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); this.PaintAllTheTabs(e); this.PaintTheTabPageBorder(e); } /// /// 绘制所有Tab选项 /// /// protected void PaintAllTheTabs(PaintEventArgs e) { if (this.TabCount > 0) { e.Graphics.CompositingQuality = CompositingQuality.HighQuality; e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; e.Graphics.SmoothingMode = SmoothingMode.HighQuality; e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; for (int i = 0; i < this.TabCount; i++) { if (this.mouseEnterTabIndex != i) { GraphicsPath path = this.CreateRoundedRectanglePath(this.GetTabRect(i), this.leftTopRadius, this.rightTopRadius, this.rightBottomRadius, this.leftBottomRadius); this.PaintTabBackground(e.Graphics, i, path); this.PaintTabImage(e.Graphics, i); this.PaintTabText(e.Graphics, i); } } if (this.mouseEnterTabIndex != -1) { GraphicsPath path = this.CreateRoundedRectanglePath(this.transformTabRect, this.leftTopRadius, this.rightTopRadius, this.rightBottomRadius, this.leftBottomRadius); this.PaintTabBackground(e.Graphics, this.mouseEnterTabIndex, path); this.PaintTabImage(e.Graphics, this.mouseEnterTabIndex); this.PaintTabText(e.Graphics, this.mouseEnterTabIndex); } } } /// /// 绘制Tab选项背景颜色 /// /// /// /// private void PaintTabBackground(Graphics g, int index, GraphicsPath path) { SolidBrush sb = new SolidBrush((index == this.SelectedIndex) ? this.tabSelectedBackColor : this.tabBackColor); g.FillPath(sb, path); sb.Dispose(); } /// /// 绘制Tab选项图片 /// /// /// private void PaintTabImage(Graphics g, int index) { if (this.ImageList == null || this.ImageList.Images.Count < 1) return; Image img = null; if (this.TabPages[index].ImageIndex > -1) { img = this.ImageList.Images[this.TabPages[index].ImageIndex]; } else if (this.TabPages[index].ImageKey.Trim().Length > 0) { img = this.ImageList.Images[this.TabPages[index].ImageKey]; } if (img != null) { Rectangle rect = this.GetTabRect(index); g.DrawImage(img, rect.X + this.tabImageMarginLeft, rect.Y + (rect.Height - this.tabImageSize.Height) / 2, this.tabImageSize.Width, this.tabImageSize.Height); } } /// /// 绘制Tab选项文本 /// /// /// private void PaintTabText(Graphics g, int index) { Rectangle rect = this.GetTabRect(index); if (this.ImageList != null && ((this.TabPages[index].ImageIndex > -1) || (this.TabPages[index].ImageKey.Trim().Length > 0))) { rect = new Rectangle(rect.Left + this.tabImageSize.Width + this.tabImageMarginLeft * 2, rect.Top, rect.Width - this.tabImageSize.Width - this.tabImageMarginLeft * 2, rect.Height); } SolidBrush sb = new SolidBrush((this.SelectedIndex == index) ? this.tabSelectedTextColor : this.tabTextColor); StringFormat sf = new StringFormat(); sf.Alignment = this.TabTextAlignment; sf.LineAlignment = StringAlignment.Center; sf.Trimming = StringTrimming.EllipsisCharacter; g.DrawString(this.TabPages[index].Text, this.Font, sb, rect, sf); sb.Dispose(); sf.Dispose(); } /// /// 设置 TabPage 内容页边框色 /// /// private void PaintTheTabPageBorder(PaintEventArgs e) { if (this.TabCount > 0) { Rectangle borderRect = this.TabPages[0].Bounds; borderRect.Inflate(1, 1); ControlPaint.DrawBorder(e.Graphics, borderRect, this.BorderColor, ButtonBorderStyle.Solid); } } protected override void OnCreateControl() { base.OnCreateControl(); this.OnFontChanged(EventArgs.Empty); } protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); IntPtr hFont = this.Font.ToHfont(); SendMessage(this.Handle, WM_SETFONT, hFont, (IntPtr)(-1)); SendMessage(this.Handle, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero); this.UpdateStyles(); } /// /// Rectangle圆角处理 /// /// 要处理Rectangle /// 左上圆角Rectangle /// 右上圆角Rectangle /// 右下圆角Rectangle /// 右下圆角Rectangle /// private GraphicsPath CreateRoundedRectanglePath(Rectangle _rect, Size _leftTopRadius, Size _rightTopRadius, Size _rightBottomRadius, Size _leftBottomRadius) { GraphicsPath radiusRect = new GraphicsPath(); //左上 if (this.isRadius(_leftTopRadius)) { radiusRect.AddArc(_rect.X, _rect.Y, _leftTopRadius.Width, _leftTopRadius.Height, 180, 90); } //上 { int x_s = this.isRadius(_leftTopRadius) ? _rect.X + _leftTopRadius.Width / 2 : _rect.X; int x_e = this.isRadius(_rightTopRadius) ? _rect.Right - _rightTopRadius.Width / 2 : _rect.Right; radiusRect.AddLine(x_s, _rect.Y, x_e, _rect.Y); } //右上 if (this.isRadius(_rightTopRadius)) { radiusRect.AddArc(_rect.Right - _rightTopRadius.Width, _rect.Y, _rightTopRadius.Width, _rightTopRadius.Height, 270, 90); } //右 { int y_s = this.isRadius(_rightTopRadius) ? _rect.Right : _rect.Y + _rightTopRadius.Height / 2; int y_e = this.isRadius(_rightBottomRadius) ? _rect.Right : _rect.Bottom - _rightBottomRadius.Height / 2; radiusRect.AddLine(_rect.Right, y_s, _rect.Right, y_e); } //右下 if (this.isRadius(_rightBottomRadius)) { radiusRect.AddArc(_rect.Right - _rightBottomRadius.Width, _rect.Bottom - _rightBottomRadius.Height, _rightBottomRadius.Width, _rightBottomRadius.Height, 0, 90); } //下 { int x_s = this.isRadius(_rightBottomRadius) ? _rect.Right - _rightBottomRadius.Width / 2 : _rect.Right; int x_e = this.isRadius(_leftBottomRadius) ? _rect.X + _leftBottomRadius.Width / 2 : _rect.X; radiusRect.AddLine(x_s, _rect.Bottom, x_e, _rect.Bottom); } //左下 if (this.isRadius(_leftBottomRadius)) { radiusRect.AddArc(_rect.X, _rect.Bottom - _leftBottomRadius.Height, _leftBottomRadius.Width, _leftBottomRadius.Height, 90, 90); } //左 { int y_s = this.isRadius(_leftBottomRadius) ? _rect.Bottom - _leftBottomRadius.Height / 2 : _rect.Bottom; int y_e = this.isRadius(_leftTopRadius) ? _rect.X + _leftTopRadius.Height / 2 : _rect.X; radiusRect.AddLine(_rect.X, y_s, _rect.X, y_e); } radiusRect.CloseFigure(); return radiusRect; } /// /// size是否设置圆角 /// /// /// private bool isRadius(Size size) { return (size.Width != 0 && size.Height != 0) ? true : false; } /// /// 清理所有正在使用的资源。 /// /// 如果应释放托管资源,为 true;否则为 false。 protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); if (this.animation != null) this.animation.Dispose(); } base.Dispose(disposing); } }