TabPanel美化控件----------WinForm控件开发系列

Posted tlmbem

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TabPanel美化控件----------WinForm控件开发系列相关的知识,希望对你有一定的参考价值。

技术图片

 /// <summary>
  /// TabControl
  /// </summary>
  [ToolboxItem(true)]
  [Description("TabControl")]
  public partial class TabControlExt : TabControl
  

    #region

    private AnimationTimer animation;
    /// <summary>
    /// 动画组件对象
    /// </summary>
    [Description("动画组件对象")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public AnimationTimer Animation
    
      get  return this.animation; 
      set  this.animation = value; 
    

    private Size leftTopRadius = new Size(0, 0);
    /// <summary>
    /// 左上角圆角
    /// </summary>
    [Description("左上角圆角")]
    [DefaultValue(typeof(Size), "0,0")]
    public Size LeftTopRadius
    
      get  return this.leftTopRadius; 
      set
      
        if (this.leftTopRadius == value)
          return;
        this.leftTopRadius = value;
        this.Invalidate();
      
    

    private Size rightTopRadius = new Size(0, 0);
    /// <summary>
    /// 右上角圆角
    /// </summary>
    [Description("右上角圆角")]
    [DefaultValue(typeof(Size), "0,0")]
    public Size RightTopRadius
    
      get  return this.rightTopRadius; 
      set
      
        if (this.rightTopRadius == value)
          return;
        this.rightTopRadius = value;
        this.Invalidate();
      
    

    private Size rightBottomRadius = new Size(0, 0);
    /// <summary>
    /// 右下角圆角
    /// </summary>
    [Description("右下角圆角")]
    [DefaultValue(typeof(Size), "0,0")]
    public Size RightBottomRadius
    
      get  return this.rightBottomRadius; 
      set
      
        if (this.rightBottomRadius == value)
          return;
        this.rightBottomRadius = value;
        this.Invalidate();
      
    

    private Size leftBottomRadius = new Size(0, 0);
    /// <summary>
    /// 左下角圆角
    /// </summary>
    [Description("左下角圆角")]
    [DefaultValue(typeof(Size), "0,0")]
    public Size LeftBottomRadius
    
      get  return this.leftBottomRadius; 
      set
      
        if (this.leftBottomRadius == value)
          return;
        this.leftBottomRadius = value;
        this.Invalidate();
      
    

    private Size tabImageSize = new Size(20, 20);
    /// <summary>
    /// tab选项图标大小
    /// </summary>
    [Description("左下角圆角")]
    [DefaultValue(typeof(Size), "20,20")]
    public Size TabImageSize
    
      get  return this.tabImageSize; 
      set
      
        if (this.tabImageSize == value)
          return;
        this.tabImageSize = value;
        this.Invalidate();
      
    

    private Color backColor = Color.White;
    /// <summary>
    /// TabContorl背景颜色
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Always)]
    [Description("TabContorl背景颜色")]
    [DefaultValue(typeof(Color), "White")]
    public override Color BackColor
    
      get  return this.backColor; 
      set
      
        if (this.backColor == value)
          return;
        this.backColor = value;
        base.Invalidate(true);
      
    

    private Color borderColor = Color.FromArgb(128, 170, 42);
    /// <summary>
    /// TabContorl边框色
    /// </summary>
    [DefaultValue(typeof(Color), "128, 170, 42")]
    [Description("TabContorl边框色")]
    public Color BorderColor
    
      get  return this.borderColor; 
      set
      
        if (this.borderColor == value)
          return;
        this.borderColor = value;
        base.Invalidate(true);
      
    

    private Color tabBackColor = Color.OliveDrab;
    /// <summary>
    /// Tab背景颜色
    /// </summary>
    [DefaultValue(typeof(Color), "OliveDrab")]
    [Description("Tab背景颜色")]
    public Color TabBackColor
    
      get  return this.tabBackColor; 
      set
      
        if (this.tabBackColor == value)
          return;
        this.tabBackColor = value;
        base.Invalidate();
      
    

    private Color tabSelectedBackColor = Color.FromArgb(128, 170, 42);
    /// <summary>
    /// Tab选中背景颜色
    /// </summary>
    [DefaultValue(typeof(Color), "128, 170, 42")]
    [Description("Tab选中背景颜色")]
    public Color TabSelectedBackColor
    
      get  return this.tabSelectedBackColor; 
      set
      
        if (this.tabSelectedBackColor == value)
          return;
        this.tabSelectedBackColor = value;
        base.Invalidate();
      
    

    private Color tabTextColor = Color.White;
    /// <summary>
    /// Tab文本颜色
    /// </summary>
    [DefaultValue(typeof(Color), "White")]
    [Description("Tab文本颜色")]
    public Color TabTextColor
    
      get  return this.tabTextColor; 
      set
      
        if (this.tabTextColor == value)
          return;
        this.tabTextColor = value;
        base.Invalidate();
      
    

    private StringAlignment tabTextAlignment = StringAlignment.Near;
    /// <summary>
    /// Tab选中文本对齐方式
    /// </summary>
    [DefaultValue(StringAlignment.Near)]
    [Description("Tab选中文本对齐方式")]
    public StringAlignment TabTextAlignment
    
      get  return this.tabTextAlignment; 
      set
      
        if (this.tabTextAlignment == value)
          return;
        this.tabTextAlignment = value;
        base.Invalidate();
      
    

    private Color tabSelectedTextColor = Color.White;
    /// <summary>
    /// Tab选中文本颜色
    /// </summary>
    [DefaultValue(typeof(Color), "White")]
    [Description("Tab选中文本颜色")]
    public Color TabSelectedTextColor
    
      get  return this.tabSelectedTextColor; 
      set
      
        if (this.tabSelectedTextColor == value)
          return;
        this.tabSelectedTextColor = value;
        base.Invalidate();
      
    

    private int mouseEnterTabIndex = -1;
    /// <summary>
    /// 鼠标是否进入Tab选项
    /// </summary>
    [Description("鼠标是否进入Tab选项")]
    [DefaultValue(-1)]
    [Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Always)]
    public int MouseEnterTabIndex
    
      get  return this.mouseEnterTabIndex; 
      set
      
        if (this.mouseEnterTabIndex == value)
          return;
        this.mouseEnterTabIndex = value;
        if (value != -1)
        
          this.MouseEnterTabRect = this.GetTabRect(value);
          this.animation.AT = AnimationType.ElasticOut;
          this.animation.Start(true, 0.0);
        
      
    

    /// <summary>
    /// 要变换的Tab原始值
    /// </summary>
    private Rectangle MouseEnterTabRect;
    /// <summary>
    /// 要变换的Tab
    /// </summary>
    private Rectangle transformTabRect = new Rectangle();
    private int tabImageMarginLeft = 4;

    #endregion

    #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);

    

    /// <summary>
    /// Tab变换动画
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    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();
    

    /// <summary>
    /// 鼠标进入Tab选项
    /// </summary>
    /// <param name="e"></param>
    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;
    

    /// <summary>
    /// 鼠标离开控件可视区
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseLeave(EventArgs e)
    
      base.OnMouseLeave(e);
      this.MouseEnterTabIndex = -1;
      this.Invalidate();
    

    /// <summary>
    /// 
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPaint(PaintEventArgs e)
    
      base.OnPaint(e);
      this.PaintAllTheTabs(e);
      this.PaintTheTabPageBorder(e);
    

    /// <summary>
    /// 绘制所有Tab选项
    /// </summary>
    /// <param name="e"></param>
    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);
        
      
    

    /// <summary>
    /// 绘制Tab选项背景颜色
    /// </summary>
    /// <param name="g"></param>
    /// <param name="index"></param>
    /// <param name="path"></param>
    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();
    

    /// <summary>
    /// 绘制Tab选项图片
    /// </summary>
    /// <param name="g"></param>
    /// <param name="index"></param>
    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);
      
    

    /// <summary>
    /// 绘制Tab选项文本
    /// </summary>
    /// <param name="g"></param>
    /// <param name="index"></param>
    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();
    

    /// <summary>
    /// 设置 TabPage 内容页边框色
    /// </summary>
    /// <param name="e"></param>
    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();
    

    /// <summary>
    /// Rectangle圆角处理
    /// </summary>
    /// <param name="_rect">要处理Rectangle</param>
    /// <param name="_leftTopRadius">左上圆角Rectangle</param>
    /// <param name="_rightTopRadius">右上圆角Rectangle</param>
    /// <param name="_rightBottomRadius">右下圆角Rectangle</param>
    /// <param name="_leftBottomRadius">右下圆角Rectangle</param>
    /// <returns></returns>
    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;
    

    /// <summary>
    /// size是否设置圆角
    /// </summary>
    /// <param name="size"></param>
    /// <returns></returns>
    private bool isRadius(Size size)
    
      return (size.Width != 0 && size.Height != 0) ? true : false;
    

    /// <summary> 
    /// 清理所有正在使用的资源。
    /// </summary>
    /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
    protected override void Dispose(bool disposing)
    
      if (disposing && (components != null))
      
        components.Dispose();
        if (this.animation != null)
          this.animation.Dispose();
      
      base.Dispose(disposing);
    
  

 

 源码下载:TabPanel美化控件.zip

以上是关于TabPanel美化控件----------WinForm控件开发系列的主要内容,如果未能解决你的问题,请参考以下文章

颜色选择美化控件----------WinForm控件开发系列

Javascript 在 ASCX 中不起作用 – ASP NET 用户控件

界面美化.CStatic控件的美化(好多系列文章)

Qt 常用控件美化

右下角弹窗美化控件----------WinForm控件开发系列

Qt 常用控件美化