[轉]C# 美化MenuStrip 自定義MenuStrip控件


(轉載請刪除括號里的內容)

更改MenuStrip的外觀 讓它不再是系統默認的外觀  美觀的界面總是讓人賞心悅目的 文章都比較簡單 但是效果很好 很適合像我這樣的初學者

我在程序員之窗看到過這樣的文章 但自己水平有限 沒能實現像他所說的那樣的美化 不能完全實現.NET類庫提供的渲染菜單外觀的抽象類,所以集成了一個專用類 並重寫其中一些方法,實現的外觀的更改,看看效果:

 

 

這里 我們自定義一個控件 繼承自系統的MenuStrip MenuStrip具有一個Renderer屬性 此屬性接受一個 System.Windows.Forms.ToolStripRenderer類的對象 這個類定義了菜單 工具欄的外觀 此類是一個抽象類 系統菜單外觀是由ToolStripProfessionalRenderer類定義的 ToolStripProfessionalRenderer類就繼承自System.Windows.Forms.ToolStripRenderer

我們為了減少工作量不用去繼承ToolStripRenderer這個抽象類 ToolStripProfessionalRenderer定義了菜單欄 工具欄的外觀 我們繼承這個專業類 重寫它一些方法來自定義外觀。所以主要就是實現定義外觀的類

先建立一個類CustomProfessionalRenderer繼承自System.Windows.Forms.ToolStripProfessionalRenderer

public   class  CustomProfessionalRenderer:ToolStripProfessionalRenderer

 

給這個類添加主題顏色的字段 重載其構造函數給字段賦值 以便創建不同色調的渲染對象

 

1           private  Color _color  =  Color.Red;
2           public  CustomProfessionalRenderer(): base ()
3          {
4          }
5           public  CustomProfessionalRenderer(Color color): base ()
6          {
7              _color  =  color;
8          }

 

添加一個輔助函數 用來獲取圓角矩形區域

 1           // 獲取圓角矩形區域  radius=直徑
 2           public   static  GraphicsPath GetRoundedRectPath(Rectangle rect,  int  radius)
 3          {
 4               int  diameter  =  radius;
 5              Rectangle arcRect  =   new  Rectangle(rect.Location,  new  Size(diameter, diameter));
 6              GraphicsPath path  =   new  GraphicsPath();
 7 
 8               //  左上角
 9              path.AddArc(arcRect,  180 90 );
10 
11               //  右上角
12              arcRect.X  =  rect.Right  -  diameter;
13              path.AddArc(arcRect,  270 90 );
14 
15               //  右下角
16              arcRect.Y  =  rect.Bottom  -  diameter;
17              path.AddArc(arcRect,  0 90 );
18 
19               //  左下角
20              arcRect.X  =  rect.Left;
21              path.AddArc(arcRect,  90 90 );
22              path.CloseFigure();
23               return  path;
24          }

 

然后重寫基類的一些方法 更改外觀

渲染背景

 

 1           // 渲染背景 包括menustrip背景 toolstripDropDown背景
 2           protected   override   void  OnRenderToolStripBackground(ToolStripRenderEventArgs e)
 3          {
 4              ToolStrip toolStrip  =  e.ToolStrip;
 5              Graphics g  =  e.Graphics;
 6              g.SmoothingMode  =  SmoothingMode.HighQuality; // 抗鋸齒
 7              Rectangle bounds  =  e.AffectedBounds;
 8              LinearGradientBrush lgbrush  =   new  LinearGradientBrush( new  Point( 0 0 ),  new  Point( 0 , toolStrip.Height), Color.FromArgb( 255 ,Color.White), Color.FromArgb( 150 ,_color));
 9               if  (toolStrip  is  MenuStrip)
10              {
11                   // 由menuStrip的Paint方法定義 這里不做操作
12              }
13               else   if  (toolStrip  is  ToolStripDropDown)
14              {
15                   int  diameter  =   10 ; // 直徑
16                  GraphicsPath path  =   new  GraphicsPath();
17                  Rectangle rect  =   new  Rectangle(Point.Empty, toolStrip.Size);
18                  Rectangle arcRect  =   new  Rectangle(rect.Location,  new  Size(diameter, diameter));
19                  
20                  path.AddLine( 0 0 10 0 );
21                   //  右上角
22                  arcRect.X  =  rect.Right  -  diameter;
23                  path.AddArc(arcRect,  270 90 );
24 
25                   //  右下角
26                  arcRect.Y  =  rect.Bottom  -  diameter;
27                  path.AddArc(arcRect,  0 90 );
28 
29                   //  左下角
30                  arcRect.X  =  rect.Left;
31                  path.AddArc(arcRect,  90 90 );
32                  path.CloseFigure();
33                  toolStrip.Region  =   new  Region(path);
34                  g.FillPath(lgbrush, path);
35              }
36               else
37              {
38                   base .OnRenderToolStripBackground(e);
39              }
40          }

 

渲染邊框

        // 渲染邊框 不繪制邊框
         protected   override   void  OnRenderToolStripBorder(ToolStripRenderEventArgs e)
        {
            
// 不調用基類的方法 屏蔽掉該方法 去掉邊框
        }

 

渲染箭頭顏色

1           // 渲染箭頭 更改箭頭顏色
2           protected   override   void  OnRenderArrow(ToolStripArrowRenderEventArgs e)
3          {
4              e.ArrowColor  =  _color;
5               base .OnRenderArrow(e);
6          }

 

渲染菜單項

 1           // 渲染項 不調用基類同名方法
 2           protected   override   void  OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
 3          {
 4              Graphics g  =  e.Graphics;
 5              ToolStripItem item  =  e.Item;
 6              ToolStrip toolstrip  =  e.ToolStrip;
 7              
 8              
 9               // 渲染頂級項
10               if  (toolstrip  is  MenuStrip)
11              {
12                  LinearGradientBrush lgbrush  =   new  LinearGradientBrush( new  Point( 0 0 ),  new  Point( 0 , item.Height), Color.FromArgb( 100 , Color.White), Color.FromArgb( 0 , Color.White));
13                  SolidBrush brush = new  SolidBrush(Color.FromArgb( 255 ,Color.White));
14                   if  (e.Item.Selected)
15                  {
16                      GraphicsPath gp  =  GetRoundedRectPath( new  Rectangle( new  Point( 0 0 ), item.Size),  5 );
17                      g.FillPath(lgbrush, gp);
18                  }
19                   if  (item.Pressed)
20                  {
21                       /// /創建上面左右2圓角的矩形路徑
22                       // GraphicsPath path = new GraphicsPath();
23                       // int diameter = 8;
24                       // Rectangle rect = new Rectangle(Point.Empty, item.Size);
25                       // Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
26                       /// / 左上角
27                       // path.AddArc(arcRect, 180, 90);
28                       /// / 右上角
29                       // arcRect.X = rect.Right - diameter;
30                       // path.AddArc(arcRect, 270, 90);
31                       // path.AddLine(new Point(rect.Width, rect.Height), new Point(0, rect.Height));
32                       // path.CloseFigure();
33                       /// /填充路徑
34                       // g.FillPath(brush, path);
35                      g.FillRectangle(Brushes.White, new  Rectangle(Point.Empty,item.Size));
36                  }
37              }
38               // 渲染下拉項
39               else   if  (toolstrip  is  ToolStripDropDown)
40              {
41                  g.SmoothingMode  =  SmoothingMode.HighQuality;
42                  LinearGradientBrush lgbrush  =   new  LinearGradientBrush( new  Point( 0 0 ),  new  Point(item.Width,  0 ), Color.FromArgb( 200 , _color), Color.FromArgb( 0 , Color.White));
43                   if  (item.Selected)
44                  {
45                      GraphicsPath gp  =  GetRoundedRectPath( new  Rectangle( 0 0 , item.Width, item.Height),  10 );
46                      g.FillPath(lgbrush, gp);
47                  }
48              }
49               else
50              {
51                   base .OnRenderMenuItemBackground(e);
52              }
53          }

 

渲染分界線

1           protected   override   void  OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
2          {
3              Graphics g  =  e.Graphics;
4 
5              LinearGradientBrush lgbrush  =   new  LinearGradientBrush( new  Point( 0 0 ),  new  Point(e.Item.Width,  0 ), _color, Color.FromArgb( 0 , _color));
6              g.FillRectangle(lgbrush,  new  Rectangle( 3 ,e.Item.Height / 2 ,e.Item.Width, 1 ));
7               // base.OnRenderSeparator(e);
8          }

 

渲染下拉菜單的左邊圖片區域

1           // 渲染圖片區域 下拉菜單左邊的圖片區域
2           protected   override   void  OnRenderImageMargin(ToolStripRenderEventArgs e)
3          {
4               // base.OnRenderImageMargin(e);
5               // 屏蔽掉左邊圖片豎條
6          }

 

到此 主要方法重寫得差不多了 重寫其它的方法 還可以控制其它的外觀 比如選中狀態下的項左邊的小鈎等等

 

接下來創建控件 繼承自MenuStrip 並設計一個themeColor屬性 對外提高更改主題顏色的API

 

 1  public   partial   class  CustomContrls_MenuStrip : MenuStrip
 2  {
 3       private  Color _themeColor  =  Color.Gray;
 4       public  CustomContrls_MenuStrip()
 5      {
 6          InitializeComponent();
 7           this .Renderer  =   new  CustomProfessionalRenderer(_themeColor);
 8      }
 9       public  Color ThemeColor
10      {
11           get  {  return  _themeColor; }
12           set
13          {
14              _themeColor  =  value;
15               this .Renderer  =   new  CustomProfessionalRenderer(_themeColor);
16          }
17      }
18  }

 

這樣就制作好了我們自定義的MenuStrip控件,該控件保留了系統菜單控件的所有功能並增加了一個屬性 用於更換菜單風格 把CustomContrls_MenuStrip拖到IDE中的窗體上開始使用了

 

通過少量的修改 實現比較美觀的外觀 是最明智的選擇 不必把過多的精力放到界面上

 


---------------------
作者:狐狸狡猾不
來源:CNBLOGS
原文:https://www.cnblogs.com/yuanfan/archive/2010/12/03/1895878.html
版權聲明:本文為作者原創文章,轉載請附上博文鏈接!
內容解析By:CSDN,CNBLOG博客文章一鍵轉載插件


免責聲明!

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



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