使用C#创建自定义背景色/形状的菜单栏与工具栏

来源:互联网 发布:linux压缩成tar.gz 编辑:程序博客网 时间:2024/06/07 08:10

Lassewang (2011) http://blog.csdn.net/lassewang/article/details/6244718 (available at 2013/11/16)

C#对于菜单栏与工具栏都提供了统一的背景色,形状的渲染类,即ToolStripRenderer类,同时根据不同的情形,提供了多个继承类,分别是ToolStripProfessionalRender,ToolStripSystemRenderer,本片文章将通过继承ToolStripProfessionalRender来实现菜单与工具栏的自定义

 

1.通过VS2008创建一个C#类,并命名为CustomProfessionalRenderer.cs

2.在CustomProfessionalRenderer.cs文件中加入以下引用

  

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Windows.Forms;  
  6. using System.Drawing;  
  7. using System.Drawing.Drawing2D;  

3.定义CustomProfessionalRenderer类的控件颜色的全局变量

  

[c-sharp] view plaincopy
  1. //默认的绘制背景色的颜色  
  2. private Color menu_color = Color.Red;      //菜单的背景色  
  3. private Color toolbar_color = Color.Red;   //工具栏的背景色  
  4. private Color image_color = Color.Red;     //菜单图片栏的背景色  
  5. private Color separator_color = Color.Red; //菜单分割条的背景色  

4.定义CustomProfessionalRenderer类的构造函数

  

[c-sharp] view plaincopy
  1. public CustomProfessionalRenderer()  
  2.             : base()  
  3. {  
  4. }  
  5.   
  6. public CustomProfessionalRenderer(Color mColor, Color iColor, Color sColor)  
  7.             : base()  
  8. {  
  9.     menu_color = mColor;  
  10.     image_color = iColor;  
  11.     separator_color = sColor;  
  12. }  
  13.   
  14. public CustomProfessionalRenderer(Color tColor)  
  15.             :base()  
  16. {  
  17.     toolbar_color = tColor;  
  18. }  

5.重写绘制菜单栏和工具栏背景色的函数,如下所示

  

[c-sharp] view plaincopy
  1. protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)  
  2.         {  
  3.             //判断ToolStrip的类型  
  4.             ToolStrip tsType = e.ToolStrip;  
  5.             Graphics g = e.Graphics;  
  6.             //抗锯齿  
  7.             g.SmoothingMode = SmoothingMode.HighQuality;              
  8.   
  9.             if (tsType is MenuStrip ||                  
  10.                 tsType is ToolStripDropDown)  
  11.             {  
  12.                 //指定填充Menu栏与ToolBar栏的背景色的画刷,使用线性渐变画刷  
  13.                 LinearGradientBrush lgBursh = new LinearGradientBrush(new Point(0, 0),  
  14.                                                                       new Point(0, tsType.Height),  
  15.                                                                       Color.FromArgb(255, Color.White),  
  16.                                                                       Color.FromArgb(150, menu_color));  
  17.                 GraphicsPath path = new GraphicsPath(FillMode.Winding);  
  18.                 int diameter = 10;//直径                  
  19.                 Rectangle rect = new Rectangle(Point.Empty, tsType.Size);  
  20.                 Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));  
  21.   
  22.                 path.AddLine(0, 0, 10, 0);  
  23.                 // 右上角  
  24.                 arcRect.X = rect.Right - diameter;  
  25.                 path.AddArc(arcRect, 270, 90);  
  26.   
  27.                 // 右下角  
  28.                 arcRect.Y = rect.Bottom - diameter;  
  29.                 path.AddArc(arcRect, 0, 90);  
  30.   
  31.                 // 左下角  
  32.                 arcRect.X = rect.Left;  
  33.                 path.AddArc(arcRect, 90, 90);  
  34.                 path.CloseFigure();  
  35.   
  36.                 //设置控件的窗口区域  
  37.                 tsType.Region = new Region(path);  
  38.   
  39.                 //填充窗口区域  
  40.                 g.FillPath(lgBursh, path);  
  41.             }  
  42.             else if (tsType is ToolStrip)  
  43.             {  
  44.                 //指定填充Menu栏与ToolBar栏的背景色的画刷,使用线性渐变画刷  
  45.                 LinearGradientBrush lgBursh = new LinearGradientBrush(new Point(0, 0),  
  46.                                                                       new Point(0, tsType.Height),  
  47.                                                                       Color.FromArgb(255, Color.White),  
  48.                                                                       Color.FromArgb(150, toolbar_color));  
  49.                 GraphicsPath path = new GraphicsPath(FillMode.Winding);  
  50.                 int diameter = 10;//直径                  
  51.                 Rectangle rect = new Rectangle(Point.Empty, tsType.Size);  
  52.                 Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));  
  53.   
  54.                 path.AddLine(0, 0, 10, 0);  
  55.                 // 右上角  
  56.                 arcRect.X = rect.Right - diameter;  
  57.                 path.AddArc(arcRect, 270, 90);  
  58.   
  59.                 // 右下角  
  60.                 arcRect.Y = rect.Bottom - diameter;  
  61.                 path.AddArc(arcRect, 0, 90);  
  62.   
  63.                 // 左下角  
  64.                 arcRect.X = rect.Left;  
  65.                 path.AddArc(arcRect, 90, 90);  
  66.                 path.CloseFigure();  
  67.   
  68.                 //设置控件的窗口区域  
  69.                 tsType.Region = new Region(path);  
  70.   
  71.                 //填充窗口区域  
  72.                 g.FillPath(lgBursh, path);  
  73.             }  
  74.             else  
  75.             {  
  76.                 base.OnRenderToolStripBackground(e);  
  77.             }  
  78.         }  

6.重写绘制菜单栏和工具栏边框的函数,如下所示

  

[c-sharp] view plaincopy
  1. protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)  
  2.         {  
  3.             //判断ToolStrip的类型  
  4.             ToolStrip tsType = e.ToolStrip;  
  5.             Graphics g = e.Graphics;  
  6.             //抗锯齿  
  7.             g.SmoothingMode = SmoothingMode.HighQuality;                          
  8.   
  9.             if (tsType is MenuStrip ||  
  10.                 tsType is ToolStripDropDown)  
  11.             {  
  12.                 //设置画笔  
  13.                 Pen LinePen = new Pen(menu_color);  
  14.                 GraphicsPath path = new GraphicsPath(FillMode.Winding);  
  15.                 int diameter = 10;//直径                  
  16.                 Rectangle rect = new Rectangle(Point.Empty, tsType.Size);  
  17.                 Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));  
  18.   
  19.                 path.AddLine(0, 0, 10, 0);  
  20.                 // 右上角  
  21.                 arcRect.X = rect.Right - diameter;  
  22.                 path.AddArc(arcRect, 270, 90);  
  23.   
  24.                 // 右下角  
  25.                 arcRect.Y = rect.Bottom - diameter;  
  26.                 path.AddArc(arcRect, 0, 90);  
  27.   
  28.                 // 左下角  
  29.                 arcRect.X = rect.Left;  
  30.                 path.AddArc(arcRect, 90, 90);  
  31.                 path.CloseFigure();  
  32.   
  33.                 //画边框  
  34.                 g.DrawPath(LinePen, path);  
  35.             }  
  36.             else if (tsType is ToolStrip)  
  37.             {  
  38.                 //设置画笔  
  39.                 Pen LinePen = new Pen(toolbar_color);  
  40.                 GraphicsPath path = new GraphicsPath(FillMode.Winding);  
  41.                 int diameter = 10;//直径                  
  42.                 Rectangle rect = new Rectangle(Point.Empty, tsType.Size);  
  43.                 Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));  
  44.   
  45.                 path.AddLine(0, 0, 10, 0);  
  46.                 // 右上角  
  47.                 arcRect.X = rect.Right - diameter;  
  48.                 path.AddArc(arcRect, 270, 90);  
  49.   
  50.                 // 右下角  
  51.                 arcRect.Y = rect.Bottom - diameter;  
  52.                 path.AddArc(arcRect, 0, 90);  
  53.   
  54.                 // 左下角  
  55.                 arcRect.X = rect.Left;  
  56.                 path.AddArc(arcRect, 90, 90);  
  57.                 path.CloseFigure();  
  58.   
  59.                 //画边框  
  60.                 g.DrawPath(LinePen, path);  
  61.             }  
  62.             else  
  63.             {  
  64.                 base.OnRenderToolStripBorder(e);  
  65.             }  
  66.         }  

7.当菜单上存在多级目录时,会显示相应的小箭头,想修改,请重写如下函数

  

[c-sharp] view plaincopy
  1. protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)  
  2.         {  
  3.             e.ArrowColor = menu_color;  
  4.             base.OnRenderArrow(e);  
  5.         }  

8.重写子菜单的渲染函数,如下所示

  

[c-sharp] view plaincopy
  1. protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)  
  2.         {  
  3.             Graphics g = e.Graphics;  
  4.             ToolStripItem item = e.Item;  
  5.             ToolStrip tsType = e.ToolStrip;  
  6.   
  7.             g.SmoothingMode = SmoothingMode.HighQuality;  
  8.   
  9.             //渲染顶级项  
  10.             if (tsType is MenuStrip)  
  11.             {                  
  12.                 if (e.Item.Selected)  
  13.                 {  
  14.                     Pen LinesPen = new Pen(Color.FromArgb(205, 226, 252));  
  15.                     Point[] LinePoint = { new Point(0, 2),  
  16.                                            new Point(item.Size.Width - 1, 2),  
  17.                                            new Point(item.Size.Width - 1, item.Size.Height - 3),  
  18.                                            new Point(0, item.Size.Height - 3),  
  19.                                            new Point(0, 2)};  
  20.                     g.DrawLines(LinesPen, LinePoint);  
  21.   
  22.                     SolidBrush brush = new SolidBrush(Color.FromArgb(197, 228, 253));  
  23.                     Rectangle rect = new Rectangle(0, 2, item.Size.Width - 1, item.Size.Height - 5);  
  24.                     g.FillRectangle(brush, rect);  
  25.                 }  
  26.                 if (item.Pressed)  
  27.                 {  
  28.                     Pen LinesPen = new Pen(Color.FromArgb(197, 228, 253));  
  29.                     Point[] LinePoint = { new Point(0, 2),  
  30.                                            new Point(item.Size.Width - 1, 2),  
  31.                                            new Point(item.Size.Width - 1, item.Size.Height - 3),  
  32.                                            new Point(0, item.Size.Height - 3),  
  33.                                            new Point(0, 2)};  
  34.                     g.DrawLines(LinesPen, LinePoint);  
  35.                 }  
  36.             }  
  37.             //渲染下拉项  
  38.             else if (tsType is ToolStripDropDown)  
  39.             {  
  40.                 g.SmoothingMode = SmoothingMode.HighQuality;  
  41.                 LinearGradientBrush lgbrush = new LinearGradientBrush(new Point(0, 0), new Point(item.Width, 0), Color.FromArgb(200, menu_color), Color.FromArgb(0, Color.White));  
  42.                 if (item.Selected)  
  43.                 {  
  44.                     GraphicsPath gp = GetRoundedRectPath(new Rectangle(0, 0, item.Width, item.Height), 10);  
  45.                     g.FillPath(lgbrush, gp);  
  46.                 }  
  47.             }  
  48.             else  
  49.             {  
  50.                 base.OnRenderMenuItemBackground(e);  
  51.             }  
  52.         }  

9.重写菜单上分割线的函数,如下所示

  

[c-sharp] view plaincopy
  1. protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)  
  2.         {  
  3.             Graphics g = e.Graphics;  
  4.   
  5.             ToolStrip tsType = e.ToolStrip;  
  6.   
  7.             if ( tsType is ToolStripDropDown)  
  8.             {  
  9.                 LinearGradientBrush lgbrush = new LinearGradientBrush(new Point(0, 0),  
  10.                                                                   new Point(e.Item.Width, 0),  
  11.                                                                   separator_color,  
  12.                                                                   Color.FromArgb(0, separator_color));  
  13.                 g.FillRectangle(lgbrush, new Rectangle(33, e.Item.Height / 2, e.Item.Width / 4 * 3, 1));  
  14.             }                                                  
  15.         }  

10.重写菜单上左边放置图片的区域,如下所示

  

[c-sharp] view plaincopy
  1. protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)  
  2.         {  
  3.             //base.OnRenderImageMargin(e);  
  4.             //屏蔽掉左边图片竖条  
  5.   
  6.             Graphics g = e.Graphics;  
  7.             g.SmoothingMode = SmoothingMode.HighQuality;  
  8.             Rectangle image_rect = e.AffectedBounds;  
  9.   
  10.             //SolidBrush brush = new SolidBrush(image_color);  
  11.             LinearGradientBrush lgbrush = new LinearGradientBrush(new Point(0, 0),   
  12.                                                                   new Point(image_rect.Width, 0),  
  13.                                                                   Color.FromArgb(200, image_color),   
  14.                                                                   Color.FromArgb(0, Color.White));  
  15.             Rectangle rect = new Rectangle(0, 0, image_rect.Width, image_rect.Height);  
  16.             g.FillRectangle(lgbrush, rect);  
  17.         }  

11.重写绘制工具栏上BUTTON按钮背景色的函数,如下所示

  

[c-sharp] view plaincopy
  1. protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e)  
  2.         {  
  3.             Graphics g = e.Graphics;  
  4.             g.SmoothingMode = SmoothingMode.HighQuality;  
  5.             ToolStripItem item = e.Item;  
  6.   
  7.             if (item.Selected)  
  8.             {  
  9.                 Pen LinesPen = new Pen(Color.FromArgb(205, 226, 252));  
  10.                 Point[] LinePoint = { new Point(0, 2),  
  11.                                            new Point(item.Size.Width - 1, 2),  
  12.                                            new Point(item.Size.Width - 1, item.Size.Height - 3),  
  13.                                            new Point(0, item.Size.Height - 3),  
  14.                                            new Point(0, 2)};  
  15.                 g.DrawLines(LinesPen, LinePoint);  
  16.   
  17.                 SolidBrush brush = new SolidBrush(Color.FromArgb(197, 228, 253));  
  18.                 Rectangle rect = new Rectangle(0, 2, item.Size.Width - 1, item.Size.Height - 5);  
  19.                 g.FillRectangle(brush, rect);  
  20.             }  
  21.             else  
  22.             {  
  23.                 base.OnRenderMenuItemBackground(e);  
  24.             }  
  25.         }  

12.另在代码上加入以下函数

  

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

 

到此为止,已经写好了菜单与工具栏的渲染类,下面就是如何调用了

1.菜单栏的调用

  

[c-sharp] view plaincopy
  1. class CustomMenuStrip : MenuStrip  
  2. {  
  3.     private Color menu_Color = Color.Gray;  
  4.     private Color image_Color = Color.Gray;  
  5.     private Color separator_color = Color.Gray;  
  6.   
  7.     public CustomMenuStrip()  
  8.     {  
  9.         this.Renderer = new CustomProfessionalRenderer(menu_Color, image_Color, separator_color);  
  10.     }  
  11.   
  12.     public void SetColor(Color mColor, Color iColor, Color sColor)  
  13.     {  
  14.         menu_Color = mColor;  
  15.         image_Color = iColor;  
  16.         separator_color = sColor;  
  17.         this.Renderer = new CustomProfessionalRenderer(menu_Color, image_Color, separator_color);  
  18.     }  
  19. }  

2.工具栏的调用

  

[c-sharp] view plaincopy
  1. class CunstomToolStrip : ToolStrip  
  2. {  
  3.     private Color _themeColor = Color.Gray;  
  4.   
  5.     public CunstomToolStrip()  
  6.     {              
  7.         this.Renderer = new CustomProfessionalRenderer(_themeColor);  
  8.     }  
  9.   
  10.     public Color ThemeColor  
  11.     {  
  12.         get { return _themeColor; }  
  13.         set  
  14.         {  
  15.             _themeColor = value;  
  16.             this.Renderer = new CustomProfessionalRenderer(_themeColor);  
  17.         }  
  18.     }  
  19. }  

 

 按照上述方式使用之后,大家可以看到如下的菜单/工具栏界面

怎么样,效果还不错吧?


【正文结束】