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); } } }
按照上述方式使用之后,大家可以看到如下的菜单/工具栏界面