博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C# 美化MenuStrip 自定义MenuStrip控件

Posted on 2011-06-24 14:29  gczhao  阅读(4471)  评论(0编辑  收藏  举报

本文转自:http://www.cnblogs.com/yuanfan/archive/2010/12/03/1895878.html

 

 

更改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, 18090);
10 
11             // 右上角
12             arcRect.X = rect.Right - diameter;
13             path.AddArc(arcRect, 27090);
14 
15             // 右下角
16             arcRect.Y = rect.Bottom - diameter;
17             path.AddArc(arcRect, 090);
18 
19             // 左下角
20             arcRect.X = rect.Left;
21             path.AddArc(arcRect, 9090);
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(00), 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(00100);
21                 // 右上角
22                 arcRect.X = rect.Right - diameter;
23                 path.AddArc(arcRect, 27090);
24 
25                 // 右下角
26                 arcRect.Y = rect.Bottom - diameter;
27                 path.AddArc(arcRect, 090);
28 
29                 // 左下角
30                 arcRect.X = rect.Left;
31                 path.AddArc(arcRect, 9090);
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(00), 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(00), 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(00), 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(00, 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(00), 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中的窗体上开始使用了

 

通过少量的修改 实现比较美观的外观 是最明智的选择 不必把过多的精力放到界面上