zoukankan      html  css  js  c++  java
  • 使用C#创建自定义背景色/形状的菜单栏与工具栏

    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);
            }
        }
    }

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

      

  • 相关阅读:
    使用c#读取/解析二维码
    MVVM中的RelayCommand与AsyncCommand
    MVVM模式下的OpenFileDialog
    集成Source Monitor至VS中
    [转]异步command的实现
    使用Messenger实现MVVM的对话框弹出
    使用NPOI访问、控制Excel
    win11更新
    Codeforces Round #749 总结
    Codeforces Round #697 (Div. 3)
  • 原文地址:https://www.cnblogs.com/lijiu/p/3832165.html
Copyright © 2011-2022 走看看