C# 对菜单进行自定义样式

Windows一成不变的菜单样式,让很多开发者,在追求视觉效果时,感到很纠结,可能最常用的方法就是贴图,或者自己自定义组件来实现。在C#中,微软提供了Render来对菜单和工具栏进行美化,正好工作中用到了这个,写出来共享。

新建一个类,定义一个颜色配置类,目前这里只是罗列了各个部分的颜色,大家可以进行保存读取等操作,来实现换肤的效果。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace WindowsApplication1
{
    public class ColorConfig
    {
        private Color _fontcolor = Color.White;
        /// <summary>
        /// 菜单字体颜色
        /// </summary>
        public Color FontColor
        {
            get { return this._fontcolor; }
            set { this._fontcolor = value; }
        }
        private Color _marginstartcolor = Color.FromArgb(113, 113, 113);
        /// <summary>
        /// 下拉菜单坐标图标区域开始颜色
        /// </summary>
        public Color MarginStartColor
        {
            get { return this._marginstartcolor; }
            set { this._marginstartcolor = value; }
        }
        private Color _marginendcolor = Color.FromArgb(58, 58, 58);
        /// <summary>
        /// 下拉菜单坐标图标区域结束颜色
        /// </summary>
        public Color MarginEndColor
        {
            get { return this._marginendcolor; }
            set { this._marginendcolor = value; }
        }
        private Color _dropdownitembackcolor = Color.FromArgb(34, 34, 34);
        /// <summary>
        /// 下拉项背景颜色
        /// </summary>
        public Color DropDownItemBackColor
        {
            get { return this._dropdownitembackcolor; }
            set { this._dropdownitembackcolor = value; }
        }
        private Color _dropdownitemstartcolor = Color.Orange;
        /// <summary>
        /// 下拉项选中时开始颜色
        /// </summary>
        public Color DropDownItemStartColor
        {
            get { return this._dropdownitemstartcolor; }
            set { this._dropdownitemstartcolor = value; }
        }
        private Color _dorpdownitemendcolor = Color.FromArgb(160,100,20);
        /// <summary>
        /// 下拉项选中时结束颜色
        /// </summary>
        public Color DropDownItemEndColor
        {
            get { return this._dorpdownitemendcolor; }
            set { this._dorpdownitemendcolor = value; }
        }
        private Color _menuitemstartcolor = Color.FromArgb(52, 106, 159);
        /// <summary>
        /// 主菜单项选中时的开始颜色
        /// </summary>
        public Color MenuItemStartColor
        {
            get { return this._menuitemstartcolor; }
            set { this._menuitemstartcolor = value; }
        }
        private Color _menuitemendcolor = Color.FromArgb(73, 124, 174);
        /// <summary>
        /// 主菜单项选中时的结束颜色
        /// </summary>
        public Color MenuItemEndColor
        {
            get { return this._menuitemendcolor; }
            set { this._menuitemendcolor = value; }
        }
        private Color _separatorcolor = Color.Gray;
        /// <summary>
        /// 分割线颜色
        /// </summary>
        public Color SeparatorColor
        {
            get { return this._separatorcolor; }
            set { this._separatorcolor = value; }
        }
        private Color _mainmenubackcolor = Color.Black;
        /// <summary>
        /// 主菜单背景色
        /// </summary>
        public Color MainMenuBackColor
        {
            get { return this._mainmenubackcolor; }
            set { this._mainmenubackcolor = value; }
        }
        private Color _mainmenustartcolor = Color.FromArgb(93, 93, 93);
        /// <summary>
        /// 主菜单背景开始颜色
        /// </summary>
        public Color MainMenuStartColor
        {
            get { return this._mainmenustartcolor; }
            set { this._mainmenustartcolor = value; }
        }
        private Color _mainmenuendcolor = Color.FromArgb(34, 34, 34);
        /// <summary>
        /// 主菜单背景结束颜色
        /// </summary>
        public Color MainMenuEndColor
        {
            get { return this._mainmenuendcolor; }
            set { this._mainmenuendcolor = value; }
        }
        private Color _dropdownborder = Color.FromArgb(40, 96, 151);
        /// <summary>
        /// 下拉区域边框颜色
        /// </summary>
        public Color DropDownBorder
        {
            get { return this._dropdownborder; }
            set { this._dropdownborder = value; }
        }
    }
}

新建一个类,我们从 ToolStripProfessionalRenderer继承一个Render

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace WindowsApplication1
{
    public class MyMenuRender : ToolStripProfessionalRenderer
    {
        ColorConfig colorconfig = new ColorConfig();//创建颜色配置类
        /// <summary>
        /// 渲染整个背景
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
        {
            e.ToolStrip.ForeColor = colorconfig.FontColor;
            //如果是下拉
            if (e.ToolStrip is ToolStripDropDown)
            {
                e.Graphics.FillRectangle(new SolidBrush(colorconfig.DropDownItemBackColor), e.AffectedBounds);
            }
            //如果是菜单项
            else if (e.ToolStrip is MenuStrip)
            {
                Blend blend = new Blend();
                float[] fs = new float[5] { 0f, 0.3f, 0.5f, 0.8f, 1f };
                float[] f = new float[5] { 0f, 0.5f, 0.9f, 0.5f, 0f };
                blend.Positions = fs;
                blend.Factors = f;
                FillLineGradient(e.Graphics, e.AffectedBounds, colorconfig.MainMenuStartColor, colorconfig.MainMenuEndColor, 90f, blend);
            }
            else
            {
                base.OnRenderToolStripBackground(e);
            }
        }
        /// <summary>
        /// 渲染下拉左侧图标区域
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)
        {
            FillLineGradient(e.Graphics, e.AffectedBounds, colorconfig.MarginStartColor, colorconfig.MarginEndColor, 0f, null);
        }
        /// <summary>
        /// 渲染菜单项的背景
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
        {
            if (e.ToolStrip is MenuStrip)
            {
                //如果被选中或被按下
                if (e.Item.Selected || e.Item.Pressed)
                {
                    Blend blend = new Blend();
                    float[] fs = new float[5] { 0f, 0.3f, 0.5f, 0.8f, 1f };
                    float[] f = new float[5] { 0f, 0.5f, 1f, 0.5f, 0f };
                    blend.Positions = fs;
                    blend.Factors = f;
                    FillLineGradient(e.Graphics, new Rectangle(0, 0, e.Item.Size.Width, e.Item.Size.Height), colorconfig.MenuItemStartColor, colorconfig.MenuItemEndColor, 90f, blend);
                }
                else
                    base.OnRenderMenuItemBackground(e);
            }
            else if (e.ToolStrip is ToolStripDropDown)
            {
                if (e.Item.Selected)
                {
                    FillLineGradient(e.Graphics, new Rectangle(0, 0, e.Item.Size.Width, e.Item.Size.Height), colorconfig.DropDownItemStartColor, colorconfig.DropDownItemEndColor, 90f, null);
                }
            }
            else
            {
                base.OnRenderMenuItemBackground(e);
            }
        }
        /// <summary>
        /// 渲染菜单项的分隔线
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
        {
            e.Graphics.DrawLine(new Pen(colorconfig.SeparatorColor), 0, 2, e.Item.Width, 2);
        }
        /// <summary>
        /// 渲染边框
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
        {
            if (e.ToolStrip is ToolStripDropDown)
            {
                e.Graphics.DrawRectangle(new Pen(colorconfig.DropDownBorder), new Rectangle(0,0,e.AffectedBounds.Width-1,e.AffectedBounds.Height-1));
            }
            else
            {
                base.OnRenderToolStripBorder(e);
            }
        }
        /// <summary>
        /// 渲染箭头
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
        {
            e.ArrowColor = Color.Red;//设置为红色,当然还可以 画出各种形状
            base.OnRenderArrow(e);
        }
        /// <summary>
        /// 填充线性渐变
        /// </summary>
        /// <param name="g">画布</param>
        /// <param name="rect">填充区域</param>
        /// <param name="startcolor">开始颜色</param>
        /// <param name="endcolor">结束颜色</param>
        /// <param name="angle">角度</param>
        /// <param name="blend">对象的混合图案</param>
        private void FillLineGradient(Graphics g, Rectangle rect, Color startcolor, Color endcolor, float angle, Blend blend)
        {
            LinearGradientBrush linebrush = new LinearGradientBrush(rect, startcolor, endcolor, angle);
            if (blend != null)
            {
                linebrush.Blend = blend;
            }
            GraphicsPath path = new GraphicsPath();
            path.AddRectangle(rect);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.FillPath(linebrush, path);
        }
    }
}

新建一个组件,继承自MenuStrip,作为我们的自定义菜单

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class MyMenu : MenuStrip
    {
        public MyMenu()
        {
            InitializeComponent();
            this.Renderer = new MyMenuRender();//设置渲染
        }

        public MyMenu(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
            this.Renderer = new MyMenuRender();//设置渲染
        }
    }
}

好了,编译项目,你会在左侧工具栏中看到MyMenu的组件,拖一个上去就可以使用了,其实直接设置自带的MenuStrip的Render属性也可以,比如设置弹出菜单的渲染

contextMenuStrip1.Renderer = new JRJMenuRender();


  • 9
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论
### 回答1: Unity自带的菜单选项可以为开发人员提供快捷的功能,但是当我们需要一个更加专业化的菜单时,Unity的默认菜单选项可能无法满足需求。此时,自定义树形菜单就应运而生。 Unity的自定义树形菜单是基于EditorGUILayout的GUI实现的。首先,我们需要扩展Editor类并使用MenuCommand属性,以及EditorGUI类,来为自定义菜单添加菜单项和功能选项。然后,我们可以使用GUILayout实现垂直排列的树形菜单,在每个菜单项的后面添加子菜单。 接下来,我们应该为自定义菜单添加相应的功能。在每个菜单项中,我们可以通过EditorGUILayout实现按钮、文本框、下拉菜单等等,为每个功能选项设计对应的功能。比如,我们可以在菜单项中添加新的对象、展开/折叠所有对象、删除特定的对象等功能。 最后,我们需要重写OnGUI方法,在其中调用自己的菜单绘制函数。这样,在编辑器中打开自定义窗口时,我们就可以看到新的树形菜单和功能选项了。另外,我们要记得在Menu选项中添加自定义的扩展菜单,这样才能在编辑器菜单中添加自己的菜单项。 总而言之,Unity的自定义树形菜单功能可以让开发人员更加简便地实现自己的的菜单和功能选项。如果你想为Unity添加一些自定义的、专业化的菜单和功能选项,自定义树形菜单将是一个十分有效的解决方案。 ### 回答2: Unity是一款非常强大的游戏引擎,在其中可以进行大量的开发工作。其中,Unity提供了很多的功能和工具,其中就包括了自定义树形菜单。 在Unity中,树形菜单是一种非常方便的工具,可以让用户轻松地查看所有的功能和对象,并且方便进行管理。如果用户想要自定义树形菜单,可以按照以下的步骤进行操作: 1. 创建一个新的编辑器窗口,负责显示自定义树形菜单。 2. 在这个编辑器窗口中,可以使用GUILayout或者IMGUI等工具来自定义绘制。 3. 使用EditorApplication.hierarchyWindowChanged事件去监听当场景objectId的集合发生了改变时触发。 4. 使用UnityEditor.GUILayout.Popup方法样式,用户可以为每个节点添加下拉箭头。 5. 使用自定义GUILayout.Button方法样式,用户可以为每个节点添加列表中的按钮。 上述步骤是在Unity中自定义树形菜单的基本过程,用户可以根据自己的需求进行更改和调整。自定义树形菜单可以大大提高工作效率,让开发者更加方便地管理和操作游戏中的场景、对象和功能。 ### 回答3: Unity是一款十分强大的游戏引擎,是许多游戏制作人员所钟爱的工具。Unity自带的菜单栏虽然已经很强大,但是我们还是有时候需要自定义树形菜单,来更好的实现游戏中的各种功能。这里我们将介绍如何使用Unity自定义树形菜单。 首先,打开Unity的编辑器并打开项目。然后在项目中新建一个C#脚本,并将其命名为“CustomMenu.cs”。我们将在这个脚本中编写我们的树形菜单。 接下来,我们需要为我们的树形菜单设置一个名称。在“CustomMenu.cs”中,使用“[MenuItem(“Custom/MyMenu”)]”,产生一个名为“MyMenu”的菜单。 接下来,我们可以在Unity的编辑器中创建一个新的文件夹,将其命名为“Custom”,这个文件夹将成为我们创建的菜单的父级。 接下来,在“CustomMenu.cs”中,我们可以使用“[MenuItem(“Custom/MyMenu/Do Something”)]”创建菜单的子项,并添加相应的函数来实现这个子项的功能。 最后,在Unity中运行我们的项目,并点击菜单栏“Custom”选项,我们就可以看到我们刚刚创建的树形菜单了。当我们点击“MyMenu”时,会显示“Do Something”子项。当我们点击“Do Something”时,它将调用相应的函数并执行相应的操作。 综上所述,Unity自定义树形菜单的实现方法是很简单的。我们只需要编写一个包含菜单名称和相应函数的脚本即可。可以根据需要创建任意多的子项,并为它们添加相应的功能。自定义菜单能够帮助我们更好地实现游戏中的各种功能,提高我们的工作效率,让我们更加专注于游戏的创作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bdmh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值