• C# 美化MenuStrip 自定义MenuStrip控件


    更改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中的窗体上开始使用了

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

  • 相关阅读:
    海选女主角
    发工资咯:)
    绝对值排序
    数列有序!
    母牛的故事
    一文看懂外汇风险准备金率调整为 20%的含义
    1080i减少带宽
    为什么要采用隔行扫描?
    720P、1080P、4K是什么意思?
    VBR一次編碼 v.s 二次編碼(VBR 1-pass vs 2-pass)
  • 原文地址:https://www.cnblogs.com/bingyun84/p/1897207.html
Copyright © 2020-2023  润新知