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文件中加入以下引用
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Drawing;
- using System.Drawing.Drawing2D;
3.定义CustomProfessionalRenderer类的控件颜色的全局变量
- //默认的绘制背景色的颜色
- private Color menu_color = Color.Red; //菜单的背景色
- private Color toolbar_color = Color.Red; //工具栏的背景色
- private Color image_color = Color.Red; //菜单图片栏的背景色
- private Color separator_color = Color.Red; //菜单分割条的背景色
4.定义CustomProfessionalRenderer类的构造函数
- public CustomProfessionalRenderer()
- : base()
- {
- }
- public CustomProfessionalRenderer(Color mColor, Color iColor, Color sColor)
- : base()
- {
- menu_color = mColor;
- image_color = iColor;
- separator_color = sColor;
- }
- public CustomProfessionalRenderer(Color tColor)
- :base()
- {
- toolbar_color = tColor;
- }
5.重写绘制菜单栏和工具栏背景色的函数,如下所示
- protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
- {
- //判断ToolStrip的类型
- ToolStrip tsType = e.ToolStrip;
- Graphics g = e.Graphics;
- //抗锯齿
- g.SmoothingMode = SmoothingMode.HighQuality;
- if (tsType is MenuStrip ||
- tsType is ToolStripDropDown)
- {
- //指定填充Menu栏与ToolBar栏的背景色的画刷,使用线性渐变画刷
- LinearGradientBrush lgBursh = new LinearGradientBrush(new Point(0, 0),
- new Point(0, tsType.Height),
- Color.FromArgb(255, Color.White),
- Color.FromArgb(150, menu_color));
- GraphicsPath path = new GraphicsPath(FillMode.Winding);
- int diameter = 10;//直径
- Rectangle rect = new Rectangle(Point.Empty, tsType.Size);
- Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
- path.AddLine(0, 0, 10, 0);
- // 右上角
- arcRect.X = rect.Right - diameter;
- path.AddArc(arcRect, 270, 90);
- // 右下角
- arcRect.Y = rect.Bottom - diameter;
- path.AddArc(arcRect, 0, 90);
- // 左下角
- arcRect.X = rect.Left;
- path.AddArc(arcRect, 90, 90);
- path.CloseFigure();
- //设置控件的窗口区域
- tsType.Region = new Region(path);
- //填充窗口区域
- g.FillPath(lgBursh, path);
- }
- else if (tsType is ToolStrip)
- {
- //指定填充Menu栏与ToolBar栏的背景色的画刷,使用线性渐变画刷
- LinearGradientBrush lgBursh = new LinearGradientBrush(new Point(0, 0),
- new Point(0, tsType.Height),
- Color.FromArgb(255, Color.White),
- Color.FromArgb(150, toolbar_color));
- GraphicsPath path = new GraphicsPath(FillMode.Winding);
- int diameter = 10;//直径
- Rectangle rect = new Rectangle(Point.Empty, tsType.Size);
- Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
- path.AddLine(0, 0, 10, 0);
- // 右上角
- arcRect.X = rect.Right - diameter;
- path.AddArc(arcRect, 270, 90);
- // 右下角
- arcRect.Y = rect.Bottom - diameter;
- path.AddArc(arcRect, 0, 90);
- // 左下角
- arcRect.X = rect.Left;
- path.AddArc(arcRect, 90, 90);
- path.CloseFigure();
- //设置控件的窗口区域
- tsType.Region = new Region(path);
- //填充窗口区域
- g.FillPath(lgBursh, path);
- }
- else
- {
- base.OnRenderToolStripBackground(e);
- }
- }
6.重写绘制菜单栏和工具栏边框的函数,如下所示
- protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
- {
- //判断ToolStrip的类型
- ToolStrip tsType = e.ToolStrip;
- Graphics g = e.Graphics;
- //抗锯齿
- g.SmoothingMode = SmoothingMode.HighQuality;
- if (tsType is MenuStrip ||
- tsType is ToolStripDropDown)
- {
- //设置画笔
- Pen LinePen = new Pen(menu_color);
- GraphicsPath path = new GraphicsPath(FillMode.Winding);
- int diameter = 10;//直径
- Rectangle rect = new Rectangle(Point.Empty, tsType.Size);
- Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
- path.AddLine(0, 0, 10, 0);
- // 右上角
- arcRect.X = rect.Right - diameter;
- path.AddArc(arcRect, 270, 90);
- // 右下角
- arcRect.Y = rect.Bottom - diameter;
- path.AddArc(arcRect, 0, 90);
- // 左下角
- arcRect.X = rect.Left;
- path.AddArc(arcRect, 90, 90);
- path.CloseFigure();
- //画边框
- g.DrawPath(LinePen, path);
- }
- else if (tsType is ToolStrip)
- {
- //设置画笔
- Pen LinePen = new Pen(toolbar_color);
- GraphicsPath path = new GraphicsPath(FillMode.Winding);
- int diameter = 10;//直径
- Rectangle rect = new Rectangle(Point.Empty, tsType.Size);
- Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
- path.AddLine(0, 0, 10, 0);
- // 右上角
- arcRect.X = rect.Right - diameter;
- path.AddArc(arcRect, 270, 90);
- // 右下角
- arcRect.Y = rect.Bottom - diameter;
- path.AddArc(arcRect, 0, 90);
- // 左下角
- arcRect.X = rect.Left;
- path.AddArc(arcRect, 90, 90);
- path.CloseFigure();
- //画边框
- g.DrawPath(LinePen, path);
- }
- else
- {
- base.OnRenderToolStripBorder(e);
- }
- }
7.当菜单上存在多级目录时,会显示相应的小箭头,想修改,请重写如下函数
- protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
- {
- e.ArrowColor = menu_color;
- base.OnRenderArrow(e);
- }
8.重写子菜单的渲染函数,如下所示
- protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
- {
- Graphics g = e.Graphics;
- ToolStripItem item = e.Item;
- ToolStrip tsType = e.ToolStrip;
- g.SmoothingMode = SmoothingMode.HighQuality;
- //渲染顶级项
- if (tsType is MenuStrip)
- {
- if (e.Item.Selected)
- {
- Pen LinesPen = new Pen(Color.FromArgb(205, 226, 252));
- Point[] LinePoint = { new Point(0, 2),
- new Point(item.Size.Width - 1, 2),
- new Point(item.Size.Width - 1, item.Size.Height - 3),
- new Point(0, item.Size.Height - 3),
- new Point(0, 2)};
- g.DrawLines(LinesPen, LinePoint);
- SolidBrush brush = new SolidBrush(Color.FromArgb(197, 228, 253));
- Rectangle rect = new Rectangle(0, 2, item.Size.Width - 1, item.Size.Height - 5);
- g.FillRectangle(brush, rect);
- }
- if (item.Pressed)
- {
- Pen LinesPen = new Pen(Color.FromArgb(197, 228, 253));
- Point[] LinePoint = { new Point(0, 2),
- new Point(item.Size.Width - 1, 2),
- new Point(item.Size.Width - 1, item.Size.Height - 3),
- new Point(0, item.Size.Height - 3),
- new Point(0, 2)};
- g.DrawLines(LinesPen, LinePoint);
- }
- }
- //渲染下拉项
- else if (tsType is ToolStripDropDown)
- {
- g.SmoothingMode = SmoothingMode.HighQuality;
- LinearGradientBrush lgbrush = new LinearGradientBrush(new Point(0, 0), new Point(item.Width, 0), Color.FromArgb(200, menu_color), Color.FromArgb(0, Color.White));
- if (item.Selected)
- {
- GraphicsPath gp = GetRoundedRectPath(new Rectangle(0, 0, item.Width, item.Height), 10);
- g.FillPath(lgbrush, gp);
- }
- }
- else
- {
- base.OnRenderMenuItemBackground(e);
- }
- }
9.重写菜单上分割线的函数,如下所示
- protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
- {
- Graphics g = e.Graphics;
- ToolStrip tsType = e.ToolStrip;
- if ( tsType is ToolStripDropDown)
- {
- LinearGradientBrush lgbrush = new LinearGradientBrush(new Point(0, 0),
- new Point(e.Item.Width, 0),
- separator_color,
- Color.FromArgb(0, separator_color));
- g.FillRectangle(lgbrush, new Rectangle(33, e.Item.Height / 2, e.Item.Width / 4 * 3, 1));
- }
- }
10.重写菜单上左边放置图片的区域,如下所示
- protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)
- {
- //base.OnRenderImageMargin(e);
- //屏蔽掉左边图片竖条
- Graphics g = e.Graphics;
- g.SmoothingMode = SmoothingMode.HighQuality;
- Rectangle image_rect = e.AffectedBounds;
- //SolidBrush brush = new SolidBrush(image_color);
- LinearGradientBrush lgbrush = new LinearGradientBrush(new Point(0, 0),
- new Point(image_rect.Width, 0),
- Color.FromArgb(200, image_color),
- Color.FromArgb(0, Color.White));
- Rectangle rect = new Rectangle(0, 0, image_rect.Width, image_rect.Height);
- g.FillRectangle(lgbrush, rect);
- }
11.重写绘制工具栏上BUTTON按钮背景色的函数,如下所示
- protected override void OnRenderButtonBackground(ToolStripItemRenderEventArgs e)
- {
- Graphics g = e.Graphics;
- g.SmoothingMode = SmoothingMode.HighQuality;
- ToolStripItem item = e.Item;
- if (item.Selected)
- {
- Pen LinesPen = new Pen(Color.FromArgb(205, 226, 252));
- Point[] LinePoint = { new Point(0, 2),
- new Point(item.Size.Width - 1, 2),
- new Point(item.Size.Width - 1, item.Size.Height - 3),
- new Point(0, item.Size.Height - 3),
- new Point(0, 2)};
- g.DrawLines(LinesPen, LinePoint);
- SolidBrush brush = new SolidBrush(Color.FromArgb(197, 228, 253));
- Rectangle rect = new Rectangle(0, 2, item.Size.Width - 1, item.Size.Height - 5);
- g.FillRectangle(brush, rect);
- }
- else
- {
- base.OnRenderMenuItemBackground(e);
- }
- }
12.另在代码上加入以下函数
- public static GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
- {
- int diameter = radius;
- Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
- GraphicsPath path = new GraphicsPath();
- // 左上角
- path.AddArc(arcRect, 180, 90);
- // 右上角
- arcRect.X = rect.Right - diameter;
- path.AddArc(arcRect, 270, 90);
- // 右下角
- arcRect.Y = rect.Bottom - diameter;
- path.AddArc(arcRect, 0, 90);
- // 左下角
- arcRect.X = rect.Left;
- path.AddArc(arcRect, 90, 90);
- path.CloseFigure();
- return path;
- }
到此为止,已经写好了菜单与工具栏的渲染类,下面就是如何调用了
1.菜单栏的调用
- class CustomMenuStrip : MenuStrip
- {
- private Color menu_Color = Color.Gray;
- private Color image_Color = Color.Gray;
- private Color separator_color = Color.Gray;
- public CustomMenuStrip()
- {
- this.Renderer = new CustomProfessionalRenderer(menu_Color, image_Color, separator_color);
- }
- public void SetColor(Color mColor, Color iColor, Color sColor)
- {
- menu_Color = mColor;
- image_Color = iColor;
- separator_color = sColor;
- this.Renderer = new CustomProfessionalRenderer(menu_Color, image_Color, separator_color);
- }
- }
2.工具栏的调用
- class CunstomToolStrip : ToolStrip
- {
- private Color _themeColor = Color.Gray;
- public CunstomToolStrip()
- {
- this.Renderer = new CustomProfessionalRenderer(_themeColor);
- }
- public Color ThemeColor
- {
- get { return _themeColor; }
- set
- {
- _themeColor = value;
- this.Renderer = new CustomProfessionalRenderer(_themeColor);
- }
- }
- }
按照上述方式使用之后,大家可以看到如下的菜单/工具栏界面
怎么样,效果还不错吧?
【正文结束】