c#控件編寫 (2)重寫一個TabControl


在重寫TabControl的時候我們最先想到的是設置

this.DrawMode = TabDrawMode.OwnerDrawFixed;

然后重寫

protected override void OnDrawItem(DrawItemEventArgs e)
{
     base.OnDrawItem(e);
}

這樣重寫后只是重寫選項卡上的區域,這個區域並不包括邊框,這樣我們所重寫的和邊框不搭調,也無法達到我們想要的功能 。

        而更好的方法是重寫整個控件

設置控件由用戶繪制

private void SetStyles()
        {
            base.SetStyle(
                ControlStyles.UserPaint |
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.SupportsTransparentBackColor, true);
            base.UpdateStyles();
        }

關鍵的地方在 ControlStyles.UserPaint 設置為true

重寫OnPaint

  protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);

            pe.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            pe.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
           // pe.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
            //繪制背景

            Rectangle rect = this.ClientRectangle; 
            pe.Graphics.FillRectangle(new TextureBrush(Properties.Resources.bg), rect); 

            //繪制邊線 
            int height = this.ItemSize.Height+3;
            Rectangle r = new Rectangle(DisplayRectangle.X - 1, DisplayRectangle.Y - 1, DisplayRectangle.Width + 1, DisplayRectangle.Height + 1);

            // pe.Graphics.DrawLine(new Pen(Color.FromArgb(157, 162, 168)), new Point(rect.X, rect.Y + height), new Point(rect.Right, rect.Y + height));
            pe.Graphics.DrawRectangle(new Pen(_lineColor), r);
            //繪制邊框  

            //繪制標頭

            foreach (TabPage tp in this.TabPages)
            {
                DrawTabPage(pe.Graphics, this.GetTabRect(this.TabPages.IndexOf(tp)),tp);
            } 
        }

this.GetTabRect函數可以獲取的標簽的位置,這個為我們重繪標簽提供了很好的幫助

重繪標簽 

  private void DrawTabPage(Graphics graphics, Rectangle rectangle, TabPage tp)
        {
            //繪制底紋  

            StringFormat sf = new StringFormat();
            
            sf.Trimming = StringTrimming.EllipsisCharacter;
            sf.FormatFlags = StringFormatFlags.NoWrap;
            Rectangle rect = new Rectangle (rectangle.X ,rectangle .Y +2,rectangle .Width ,rectangle .Height -2); //標准區域
            Rectangle fontRect = new Rectangle(rectangle.X + 5, rectangle.Y+5, rectangle.Width - 10, tp .Font .Height);//文字區域
           
            if (this.SelectedTab.Equals(tp))
            {
                rect = new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
                fontRect = new Rectangle(rectangle.X + 5, rectangle.Y + 5, rectangle.Width - 25, rectangle.Height - 7);
           
                //繪制邊框   
                graphics.FillPath(new LinearGradientBrush(new Point(rect.X, rect.Y), new Point(rect.X, rect.Y + rect.Height), _ColorActivateA, _ColorActivateB), CreateTabPath(rect)); //填充顏色
                graphics.DrawString(tp.Text, tp.Font, new SolidBrush(tp.ForeColor), fontRect, sf); //文字繪制
 
                graphics.DrawPath(new Pen(_lineColor), CreateTabPath(rect));//繪制實邊線  

                //掩蓋下部的繪制 
                graphics.DrawLine(new Pen(_ColorActivateB, 3), rect.X, rect.Bottom + 1, rect.X + rect.Width, rect.Bottom + 1);

                //繪制圖片
                Rectangle rectClose = GetCloseRect(rectangle);
            }
            else
            {
                //繪制邊框   
                graphics.FillPath(new LinearGradientBrush (new Point (rect .X,rect .Y ),new Point (rect .X,rect .Y +rect .Height ),_ColorDefaultA,_ColorDefaultB), CreateTabPath(rect)); //填充顏色
                graphics.DrawString(tp.Text, tp.Font, new SolidBrush(tp.ForeColor), fontRect, sf); //文字繪制
               // graphics.DrawPath(new Pen(Color.Wheat, 2), CreateTabPath(rect));//繪制高光邊線
                graphics.DrawPath(new Pen(_lineColor), CreateTabPath(rect));//繪制實邊線  
            }
         

繪制關閉標簽按鈕

        我們給標簽加上了一個鼠標移上去顯示關閉按鈕的功能   重寫OnMouseMove的功能

    bool CloseEX = false;
        protected override void OnMouseMove(MouseEventArgs e)
        {

            if (TabPageMouseClose(e.Location) != CloseEX)
            {
                CloseEX = !CloseEX;
                this.Invalidate();
            }
 
            base.OnMouseMove(e);
        }

  在鼠標移動過快的時候,會導致關閉按鈕沒有刷新,所有我們要在鼠標離開控件的時候讓CloseEx=False並重繪制。

 

好到這一步我們就完成我我們的繪制工作 。我在繪制的時候使用了漸變畫刷用了5個參數來標識每個指定的顏色

private Color _lineColor = Color.FromArgb(157, 162, 168); //邊線顏色 
private Color _ColorDefaultA = Color.FromArgb(231, 231, 231);//默認標簽漸變 a
private Color _ColorDefaultB = Color.FromArgb(255, 255, 255);//默認標簽漸變 b
private Color _ColorActivateA = Color.FromArgb(184, 203, 217);//點擊漸變a
private Color _ColorActivateB = Color.FromArgb(255, 255, 255);//點擊漸變a


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM