(三十四)c#Winform自定義控制項-Tab頁

来源:https://www.cnblogs.com/bfyx/archive/2019/08/17/11367803.html
-Advertisement-
Play Games

前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 如果覺得寫的還行,請點個 star 支持一下吧 歡迎前來交流探討: 企鵝群568015492 目錄 ...


前提

入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。

開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control

如果覺得寫的還行,請點個 star 支持一下吧

歡迎前來交流探討: 企鵝群568015492 企鵝群568015492

目錄

https://www.cnblogs.com/bfyx/p/11364884.html

準備工作

此控制項在https://www.cnblogs.com/belx/articles/9188577.html基礎上調整修改,特此感謝

開始

添加一個用戶組件,命名TabControlExt,繼承自TabControl

幾個重寫屬性

 1  private Color _backColor = Color.White;
 2         [Browsable(true)]
 3         [EditorBrowsable(EditorBrowsableState.Always)]
 4         [DefaultValue(typeof(Color), "White")]
 5         public override Color BackColor
 6         {
 7             get { return _backColor; }
 8             set
 9             {
10                 _backColor = value;
11                 base.Invalidate(true);
12             }
13         }
14 
15         private Color _borderColor = Color.FromArgb(232, 232, 232);
16         [DefaultValue(typeof(Color), "232, 232, 232")]
17         [Description("TabContorl邊框色")]
18         public Color BorderColor
19         {
20             get { return _borderColor; }
21             set
22             {
23                 _borderColor = value;
24                 base.Invalidate(true);
25             }
26         }
27 
28         private Color _headSelectedBackColor = Color.FromArgb(255, 85, 51);
29         [DefaultValue(typeof(Color), "255, 85, 51")]
30         [Description("TabPage頭部選中後的背景顏色")]
31         public Color HeadSelectedBackColor
32         {
33             get { return _headSelectedBackColor; }
34             set { _headSelectedBackColor = value; }
35         }
36 
37         private Color _headSelectedBorderColor = Color.FromArgb(232, 232, 232);
38         [DefaultValue(typeof(Color), "232, 232, 232")]
39         [Description("TabPage頭部選中後的邊框顏色")]
40         public Color HeadSelectedBorderColor
41         {
42             get { return _headSelectedBorderColor; }
43             set { _headSelectedBorderColor = value; }
44         }
45 
46         private Color _headerBackColor = Color.White;
47         [DefaultValue(typeof(Color), "White")]
48         [Description("TabPage頭部預設背景顏色")]
49         public Color HeaderBackColor
50         {
51             get { return _headerBackColor; }
52             set { _headerBackColor = value; }
53         }

重寫背景

 1 protected override void OnPaintBackground(PaintEventArgs pevent)
 2         {
 3             if (this.DesignMode == true)
 4             {
 5                 LinearGradientBrush backBrush = new LinearGradientBrush(
 6                             this.Bounds,
 7                             SystemColors.ControlLightLight,
 8                             SystemColors.ControlLight,
 9                             LinearGradientMode.Vertical);
10                 pevent.Graphics.FillRectangle(backBrush, this.Bounds);
11                 backBrush.Dispose();
12             }
13             else
14             {
15                 this.PaintTransparentBackground(pevent.Graphics, this.ClientRectangle);
16             }
17         }
18  /// <summary>
19         ///  TabContorl 背景色設置
20         /// </summary>
21         /// <param name="g"></param>
22         /// <param name="clipRect"></param>
23         protected void PaintTransparentBackground(Graphics g, Rectangle clipRect)
24         {
25             if ((this.Parent != null))
26             {
27                 clipRect.Offset(this.Location);
28                 PaintEventArgs e = new PaintEventArgs(g, clipRect);
29                 GraphicsState state = g.Save();
30                 g.SmoothingMode = SmoothingMode.HighSpeed;
31                 try
32                 {
33                     g.TranslateTransform((float)-this.Location.X, (float)-this.Location.Y);
34                     this.InvokePaintBackground(this.Parent, e);
35                     this.InvokePaint(this.Parent, e);
36                 }
37                 finally
38                 {
39                     g.Restore(state);
40                     clipRect.Offset(-this.Location.X, -this.Location.Y);
41                     //新加片段,待測試
42                     using (SolidBrush brush = new SolidBrush(_backColor))
43                     {
44                         clipRect.Inflate(1, 1);
45                         g.FillRectangle(brush, clipRect);
46                     }
47                 }
48             }
49             else
50             {
51                 System.Drawing.Drawing2D.LinearGradientBrush backBrush = new System.Drawing.Drawing2D.LinearGradientBrush(this.Bounds, SystemColors.ControlLightLight, SystemColors.ControlLight, System.Drawing.Drawing2D.LinearGradientMode.Vertical);
52                 g.FillRectangle(backBrush, this.Bounds);
53                 backBrush.Dispose();
54             }
55         }

重繪

1  protected override void OnPaint(PaintEventArgs e)
2         {
3             // Paint the Background 
4             base.OnPaint(e);
5             this.PaintTransparentBackground(e.Graphics, this.ClientRectangle);
6             this.PaintAllTheTabs(e);
7             this.PaintTheTabPageBorder(e);
8             this.PaintTheSelectedTab(e);
9         }

輔助函數

  1 private void PaintAllTheTabs(System.Windows.Forms.PaintEventArgs e)
  2         {
  3             if (this.TabCount > 0)
  4             {
  5                 for (int index = 0; index < this.TabCount; index++)
  6                 {
  7                     this.PaintTab(e, index);
  8                 }
  9             }
 10         }
 11 
 12         private void PaintTab(System.Windows.Forms.PaintEventArgs e, int index)
 13         {
 14             GraphicsPath path = this.GetTabPath(index);
 15             this.PaintTabBackground(e.Graphics, index, path);
 16             this.PaintTabBorder(e.Graphics, index, path);
 17             this.PaintTabText(e.Graphics, index);
 18             this.PaintTabImage(e.Graphics, index);
 19         }
 20 
 21         /// <summary>
 22         /// 設置選項卡頭部顏色
 23         /// </summary>
 24         /// <param name="graph"></param>
 25         /// <param name="index"></param>
 26         /// <param name="path"></param>
 27         private void PaintTabBackground(System.Drawing.Graphics graph, int index, System.Drawing.Drawing2D.GraphicsPath path)
 28         {
 29             Rectangle rect = this.GetTabRect(index);
 30             System.Drawing.Brush buttonBrush = new System.Drawing.Drawing2D.LinearGradientBrush(rect, _headerBackColor, _headerBackColor, LinearGradientMode.Vertical);  //非選中時候的 TabPage 頁頭部背景色
 31             graph.FillPath(buttonBrush, path);
 32             //if (index == this.SelectedIndex)
 33             //{
 34             //    //buttonBrush = new System.Drawing.SolidBrush(_headSelectedBackColor);
 35             //    graph.DrawLine(new Pen(_headerBackColor), rect.Right+2, rect.Bottom, rect.Left + 1, rect.Bottom);
 36             //}
 37             buttonBrush.Dispose();
 38         }
 39 
 40         /// <summary>
 41         /// 設置選項卡頭部邊框色
 42         /// </summary>
 43         /// <param name="graph"></param>
 44         /// <param name="index"></param>
 45         /// <param name="path"></param>
 46         private void PaintTabBorder(System.Drawing.Graphics graph, int index, System.Drawing.Drawing2D.GraphicsPath path)
 47         {
 48             Pen borderPen = new Pen(_borderColor);// TabPage 非選中時候的 TabPage 頭部邊框色
 49             if (index == this.SelectedIndex)
 50             {
 51                 borderPen = new Pen(_headSelectedBorderColor); // TabPage 選中後的 TabPage 頭部邊框色
 52             }
 53             graph.DrawPath(borderPen, path);
 54             borderPen.Dispose();
 55         }
 56 
 57         private void PaintTabImage(System.Drawing.Graphics g, int index)
 58         {
 59             Image tabImage = null;
 60             if (this.TabPages[index].ImageIndex > -1 && this.ImageList != null)
 61             {
 62                 tabImage = this.ImageList.Images[this.TabPages[index].ImageIndex];
 63             }
 64             else if (this.TabPages[index].ImageKey.Trim().Length > 0 && this.ImageList != null)
 65             {
 66                 tabImage = this.ImageList.Images[this.TabPages[index].ImageKey];
 67             }
 68             if (tabImage != null)
 69             {
 70                 Rectangle rect = this.GetTabRect(index);
 71                 g.DrawImage(tabImage, rect.Right - rect.Height - 4, 4, rect.Height - 2, rect.Height - 2);
 72             }
 73         }
 74 
 75         private void PaintTabText(System.Drawing.Graphics graph, int index)
 76         {
 77             string tabtext = this.TabPages[index].Text;
 78 
 79             System.Drawing.StringFormat format = new System.Drawing.StringFormat();
 80             format.Alignment = StringAlignment.Near;
 81             format.LineAlignment = StringAlignment.Center;
 82             format.Trimming = StringTrimming.EllipsisCharacter;
 83 
 84             Brush forebrush = null;
 85 
 86             if (this.TabPages[index].Enabled == false)
 87             {
 88                 forebrush = SystemBrushes.ControlDark;
 89             }
 90             else
 91             {
 92                 forebrush = SystemBrushes.ControlText;
 93             }
 94 
 95             Font tabFont = this.Font;
 96             if (index == this.SelectedIndex)
 97             {
 98                 if (this.TabPages[index].Enabled != false)
 99                 {
100                     forebrush = new SolidBrush(_headSelectedBackColor);
101                 }
102             }
103 
104             Rectangle rect = this.GetTabRect(index);
105 
106             var txtSize = ControlHelper.GetStringWidth(tabtext, graph, tabFont);
107             Rectangle rect2 = new Rectangle(rect.Left + (rect.Width - txtSize) / 2 - 1, rect.Top, rect.Width, rect.Height);
108 
109             graph.DrawString(tabtext, tabFont, forebrush, rect2, format);
110         }
111 
112         /// <summary>
113         /// 設置 TabPage 內容頁邊框色
114         /// </summary>
115         /// <param name="e"></param>
116         private void PaintTheTabPageBorder(System.Windows.Forms.PaintEventArgs e)
117         {
118             if (this.TabCount > 0)
119             {
120                 Rectangle borderRect = this.TabPages[0].Bounds;
121                 //borderRect.Inflate(1, 1);
122                 Rectangle rect = new Rectangle(borderRect.X - 2, borderRect.Y-1, borderRect.Width + 5, borderRect.Height+2);
123                 ControlPaint.DrawBorder(e.Graphics, rect, this.BorderColor, ButtonBorderStyle.Solid);
124             }
125         }
126 
127         /// <summary>
128         /// // TabPage 頁頭部間隔色
129         /// </summary>
130         /// <param name="e"></param>
131         private void PaintTheSelectedTab(System.Windows.Forms.PaintEventArgs e)
132         {
133             if (this.SelectedIndex == -1)
134                 return;
135             Rectangle selrect;
136             int selrectRight = 0;
137             selrect = this.GetTabRect(this.SelectedIndex);
138             selrectRight = selrect.Right;
139             e.Graphics.DrawLine(new Pen(_headSelectedBackColor), selrect.Left, selrect.Bottom + 1, selrectRight, selrect.Bottom + 1);
140         }
141 
142         private GraphicsPath GetTabPath(int index)
143         {
144             System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
145             path.Reset();
146 
147             Rectangle rect = this.GetTabRect(index);
148 
149             switch (Alignment)
150             {
151                 case TabAlignment.Top:
152 
153                     break;
154                 case TabAlignment.Bottom:
155 
156                     break;
157                 case TabAlignment.Left:
158 
159                     break;
160                 case TabAlignment.Right:
161 
162                     break;
163             }
164 
165             path.AddLine(rect.Left, rect.Top, rect.Left, rect.Bottom + 1);
166             path.AddLine(rect.Left, rect.Top, rect.Right , rect.Top);
167             path.AddLine(rect.Right , rect.Top, rect.Right , rect.Bottom + 1);
168             path.AddLine(rect.Right , rect.Bottom + 1, rect.Left, rect.Bottom + 1);
169 
170             return path;
171         }

2個重寫函數處理字體相關

 1  [DllImport("user32.dll")]
 2         private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
 3 
 4         private const int WM_SETFONT = 0x30;
 5         private const int WM_FONTCHANGE = 0x1d;
 6 
 7         protected override void OnCreateControl()
 8         {
 9             base.OnCreateControl();
10             this.OnFontChanged(EventArgs.Empty);
11         }
12 
13         protected override void OnFontChanged(EventArgs e)
14         {
15             base.OnFontChanged(e);
16             IntPtr hFont = this.Font.ToHfont();
17             SendMessage(this.Handle, WM_SETFONT, hFont, (IntPtr)(-1));
18             SendMessage(this.Handle, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
19             this.UpdateStyles();
20         }

 完整代碼

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Diagnostics;
  5 using System.Drawing;
  6 using System.Drawing.Drawing2D;
  7 using System.Linq;
  8 using System.Runtime.InteropServices;
  9 using System.Text;
 10 using System.Windows.Forms;
 11 
 12 namespace HZH_Controls.Controls
 13 {
 14     public class TabControlExt : TabControl
 15     {
 16         public TabControlExt()
 17             : base()
 18         {
 19             SetStyles();
 20             this.Multiline = true;
 21             this.ItemSize = new Size(this.ItemSize.Width, 50);
 22         }
 23 
 24         private void SetStyles()
 25         {
 26             base.SetStyle(
 27                 ControlStyles.UserPaint |
 28                 ControlStyles.DoubleBuffer |
 29                 ControlStyles.OptimizedDoubleBuffer |
 30                 ControlStyles.AllPaintingInWmPaint |
 31                 ControlStyles.ResizeRedraw |
 32                 ControlStyles.SupportsTransparentBackColor, true);
 33             base.UpdateStyles();
 34         }
 35 
 36         private Color _backColor = Color.White;
 37         [Browsable(true)]
 38         [EditorBrowsable(EditorBrowsableState.Always)]
 39         [DefaultValue(typeof(Color), "White")]
 40         public override Color BackColor
 41         {
 42             get { return _backColor; }
 43             set
 44             {
 45                 _backColor = value;
 46                 base.Invalidate(true);
 47             }
 48         }
 49 
 50         private Color _borderColor = Color.FromArgb(232, 232, 232);
 51         [DefaultValue(typeof(Color), "232, 232, 232")]
 52         [Description("TabContorl邊框色")]
 53         public Color BorderColor
 54         {
 55             get { return _borderColor; }
 56             set
 57             {
 58                 _borderColor = value;
 59                 base.Invalidate(true);
 60             }
 61         }
 62 
 63         private Color _headSelectedBackColor = Color.FromArgb(255, 85, 51);
 64         [DefaultValue(typeof(Color), "255, 85, 51")]
 65         [Description("TabPage頭部選中後的背景顏色")]
 66         public Color HeadSelectedBackColor
 67         {
 68             get { return _headSelectedBackColor; }
 69             set { _headSelectedBackColor = value; }
 70         }
 71 
 72         private Color _headSelectedBorderColor = Color.FromArgb(232, 232, 232);
 73         [DefaultValue(typeof(Color), "232, 232, 232")]
 74         [Description("TabPage頭部選中後的邊框顏色")]
 75         public Color HeadSelectedBorderColor
 76         {
 77             get { return _headSelectedBorderColor; }
 78             set { _headSelectedBorderColor = value; }
 79         }
 80 
 81         private Color _headerBackColor = Color.White;
 82         [DefaultValue(typeof(Color), "White")]
 83         [Description("TabPage頭部預設背景顏色")]
 84         public Color HeaderBackColor
 85         {
 86             get { return _headerBackColor; }
 87             set { _headerBackColor = value; }
 88         }
 89 
 90         protected override void OnPaintBackground(PaintEventArgs pevent)
 91         {
 92             if (this.DesignMode == true)
 93             {
 94                 LinearGradientBrush backBrush = new LinearGradientBrush(
 95                             this.Bounds,
 96                             SystemColors.ControlLightLight,
 97                             SystemColors.ControlLight,
 98                             LinearGradientMode.Vertical);
 99                 pevent.Graphics.FillRectangle(backBrush, this.Bounds);
100                 backBrush.Dispose();
101             }
102             else
103             {
104                 this.PaintTransparentBackground(pevent.Graphics, this.ClientRectangle);
105             }
106         }
107 
108         /// <summary>
109         ///  TabContorl 背景色設置
110         /// </summary>
111         /// <param name="g"></param>
112         /// <param name="clipRect"></param>
113         protected void PaintTransparentBackground(Graphics g, Rectangle clipRect)
114         {
115             if ((this.Parent != null))
116             {
117                 clipRect.Offset(this.Location);
118                 PaintEventArgs e = new PaintEventArgs(g, clipRect);
119                 GraphicsState state = g.Save();
120                 g.SmoothingMode = Smoot

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • https://www.cnblogs.com/PurpleTide/archive/2010/11/25/1887506.html CLR via C# 讀書筆記 2-3 Cache Lines and False Sharing(高速緩衝區和錯誤共用???)關於CPU中緩存行的問題。 volat ...
  • 1、要在一般處理程式中獲取其他頁面的session值,需要引用名空間: using System.Web.SessionState; 2、然後繼承一個介面:IRequiresSessionState IRequiresSessionState 使用: context.Session["key"]; ...
  • 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 如果覺得寫的還行,請點個 star 支持一下吧 歡迎前來交流探討: 企鵝群568015492 目錄 ...
  • 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 如果覺得寫的還行,請點個 star 支持一下吧 歡迎前來交流探討: 企鵝群568015492 目錄 ...
  • 一、什麼是MVC? MVC 是一種使用 MVC(Model View Controller 模型-視圖-控制器)設計創建 Web 應用程式的模式。 MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫, 一種軟體設計典範 ...
  • 前言 功能:調用web api 介面 1.獲取 jpeg 格式的二維碼 2.獲取中間帶有logo 的二維碼 3. 下載 jpeg,svg 格式的二維碼 需要的NuGet 包: > QRCoder(v1.3.6) > System.Drawing.Common(v4.5.1) 正文 1. 準備項目 創 ...
  • 優點: 1.跨平臺,高性能,開源,運行在.Net Core 或.Net Framework框架上(asp.net core 3.0及以後只支持.Net Core)。 2.各平臺上開發工具支持,能夠開發web應用,webapi,移動端後臺,IoT應用等多種應用程式,功能強大。 3.強大的開發測試功能, ...
  • 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 開源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 如果覺得寫的還行,請點個 star 支持一下吧 歡迎前來交流探討: 企鵝群568015492 目錄 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...