(轉載請刪除括號里的內容)
更改MenuStrip的外觀 讓它不再是系統默認的外觀 美觀的界面總是讓人賞心悅目的 文章都比較簡單 但是效果很好 很適合像我這樣的初學者
我在程序員之窗看到過這樣的文章 但自己水平有限 沒能實現像他所說的那樣的美化 不能完全實現.NET類庫提供的渲染菜單外觀的抽象類,所以集成了一個專用類 並重寫其中一些方法,實現的外觀的更改,看看效果:
這里 我們自定義一個控件 繼承自系統的MenuStrip MenuStrip具有一個Renderer屬性 此屬性接受一個 System.Windows.Forms.ToolStripRenderer類的對象 這個類定義了菜單 工具欄的外觀 此類是一個抽象類 系統菜單外觀是由ToolStripProfessionalRenderer類定義的 ToolStripProfessionalRenderer類就繼承自System.Windows.Forms.ToolStripRenderer
我們為了減少工作量不用去繼承ToolStripRenderer這個抽象類 ToolStripProfessionalRenderer定義了菜單欄 工具欄的外觀 我們繼承這個專業類 重寫它一些方法來自定義外觀。所以主要就是實現定義外觀的類
先建立一個類CustomProfessionalRenderer繼承自System.Windows.Forms.ToolStripProfessionalRenderer
給這個類添加主題顏色的字段 重載其構造函數給字段賦值 以便創建不同色調的渲染對象

2 public CustomProfessionalRenderer(): base ()
3 {
4 }
5 public CustomProfessionalRenderer(Color color): base ()
6 {
7 _color = color;
8 }
添加一個輔助函數 用來獲取圓角矩形區域

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 }
然后重寫基類的一些方法 更改外觀
渲染背景

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)
{
// 不調用基類的方法 屏蔽掉該方法 去掉邊框
}
渲染箭頭顏色
2 protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
3 {
4 e.ArrowColor = _color;
5 base .OnRenderArrow(e);
6 }
渲染菜單項

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 }
渲染分界線

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 }
渲染下拉菜單的左邊圖片區域

2 protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)
3 {
4 // base.OnRenderImageMargin(e);
5 // 屏蔽掉左邊圖片豎條
6 }
到此 主要方法重寫得差不多了 重寫其它的方法 還可以控制其它的外觀 比如選中狀態下的項左邊的小鈎等等
接下來創建控件 繼承自MenuStrip 並設計一個themeColor屬性 對外提高更改主題顏色的API

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博客文章一鍵轉載插件