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(, ),
new Point(, tsType.Height),
Color.FromArgb(, Color.White),
Color.FromArgb(, menu_color));
GraphicsPath path = new GraphicsPath(FillMode.Winding);
int diameter = ;//直径
Rectangle rect = new Rectangle(Point.Empty, tsType.Size);
Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter)); path.AddLine(, , , );
// 右上角
arcRect.X = rect.Right - diameter;
path.AddArc(arcRect, , ); // 右下角
arcRect.Y = rect.Bottom - diameter;
path.AddArc(arcRect, , ); // 左下角
arcRect.X = rect.Left;
path.AddArc(arcRect, , );
path.CloseFigure(); //设置控件的窗口区域
tsType.Region = new Region(path); //填充窗口区域
g.FillPath(lgBursh, path);
}
else if (tsType is ToolStrip)
{
//指定填充Menu栏与ToolBar栏的背景色的画刷,使用线性渐变画刷
LinearGradientBrush lgBursh = new LinearGradientBrush(new Point(, ),
new Point(, tsType.Height),
Color.FromArgb(, Color.White),
Color.FromArgb(, toolbar_color));
GraphicsPath path = new GraphicsPath(FillMode.Winding);
int diameter = ;//直径
Rectangle rect = new Rectangle(Point.Empty, tsType.Size);
Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter)); path.AddLine(, , , );
// 右上角
arcRect.X = rect.Right - diameter;
path.AddArc(arcRect, , ); // 右下角
arcRect.Y = rect.Bottom - diameter;
path.AddArc(arcRect, , ); // 左下角
arcRect.X = rect.Left;
path.AddArc(arcRect, , );
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 = ;//直径
Rectangle rect = new Rectangle(Point.Empty, tsType.Size);
Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter)); path.AddLine(, , , );
// 右上角
arcRect.X = rect.Right - diameter;
path.AddArc(arcRect, , ); // 右下角
arcRect.Y = rect.Bottom - diameter;
path.AddArc(arcRect, , ); // 左下角
arcRect.X = rect.Left;
path.AddArc(arcRect, , );
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 = ;//直径
Rectangle rect = new Rectangle(Point.Empty, tsType.Size);
Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter)); path.AddLine(, , , );
// 右上角
arcRect.X = rect.Right - diameter;
path.AddArc(arcRect, , ); // 右下角
arcRect.Y = rect.Bottom - diameter;
path.AddArc(arcRect, , ); // 左下角
arcRect.X = rect.Left;
path.AddArc(arcRect, , );
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(, , ));
Point[] LinePoint = { new Point(, ),
new Point(item.Size.Width - , ),
new Point(item.Size.Width - , item.Size.Height - ),
new Point(, item.Size.Height - ),
new Point(, )};
g.DrawLines(LinesPen, LinePoint); SolidBrush brush = new SolidBrush(Color.FromArgb(, , ));
Rectangle rect = new Rectangle(, , item.Size.Width - , item.Size.Height - );
g.FillRectangle(brush, rect);
}
if (item.Pressed)
{
Pen LinesPen = new Pen(Color.FromArgb(, , ));
Point[] LinePoint = { new Point(, ),
new Point(item.Size.Width - , ),
new Point(item.Size.Width - , item.Size.Height - ),
new Point(, item.Size.Height - ),
new Point(, )};
g.DrawLines(LinesPen, LinePoint);
}
}
//渲染下拉项
else if (tsType is ToolStripDropDown)
{
g.SmoothingMode = SmoothingMode.HighQuality;
LinearGradientBrush lgbrush = new LinearGradientBrush(new Point(, ), new Point(item.Width, ), Color.FromArgb(, menu_color), Color.FromArgb(, Color.White));
if (item.Selected)
{
GraphicsPath gp = GetRoundedRectPath(new Rectangle(, , item.Width, item.Height), );
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(, ),
new Point(e.Item.Width, ),
separator_color,
Color.FromArgb(, separator_color));
g.FillRectangle(lgbrush, new Rectangle(, e.Item.Height / , e.Item.Width / * , ));
}
}

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(, ),
new Point(image_rect.Width, ),
Color.FromArgb(, image_color),
Color.FromArgb(, Color.White));
Rectangle rect = new Rectangle(, , 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(, , ));
Point[] LinePoint = { new Point(, ),
new Point(item.Size.Width - , ),
new Point(item.Size.Width - , item.Size.Height - ),
new Point(, item.Size.Height - ),
new Point(, )};
g.DrawLines(LinesPen, LinePoint); SolidBrush brush = new SolidBrush(Color.FromArgb(, , ));
Rectangle rect = new Rectangle(, , item.Size.Width - , item.Size.Height - );
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, , ); // 右上角
arcRect.X = rect.Right - diameter;
path.AddArc(arcRect, , ); // 右下角
arcRect.Y = rect.Bottom - diameter;
path.AddArc(arcRect, , ); // 左下角
arcRect.X = rect.Left;
path.AddArc(arcRect, , );
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#创建自定义背景色/形状的菜单栏与工具栏的更多相关文章

  1. AutoCAD.NET二次开发:创建自定义菜单(AcCui)

    从CAD2007之后,Autodesk提供了一个新的程序集AcCui.dll,使用这个程序集,我们可以方便地做一些界面方面的操作,比如创建自定义菜单. 下面介绍一下菜单的创建过程: 1.在项目中添加引 ...

  2. tensorflow创建自定义 Estimator

    https://www.tensorflow.org/guide/custom_estimators?hl=zh-cn 创建自定义 Estimator 本文档介绍了自定义 Estimator.具体而言 ...

  3. UniGUI的TUniLoginForm窗口自定义背景色和背景图片

    雨田家园 UniGUI的TUniLoginForm窗口自定义背景色 uniGUI的TUniLoginForm类创建的登录窗口默认是不带颜色,可以自定义css风格来改变背景颜色. 一般是通过在UniSe ...

  4. 创建自定义view(翻译 androidtraining)

    创建自定义view 一个设计良好的的自定义view应该是一个设计良好的class,它包含了很多实用的功能,让人们更加容易使用接口.它充分利用GPU与内存的性能等等. 另外作为一个设计良好的类,一个自定 ...

  5. 创建自定义 Estimator

    ref 本文档介绍了自定义 Estimator.具体而言,本文档介绍了如何创建自定义 Estimator 来模拟预创建的 Estimator DNNClassifier 在解决鸢尾花问题时的行为.要详 ...

  6. C++ GUI Qt4编程-创建自定义窗口部件

    C++ GUI Qt4编程-创建自定义窗口部件   Qtqt4 通过Qt窗口部件进行子类化或者直接对QWidget进行子类化,就可以创建自定义窗口部件,下面示范两种方式,并且也会说明如何把自定义窗口部 ...

  7. ASP.NET MVC随想录——创建自定义的Middleware中间件

    经过前2篇文章的介绍,相信大家已经对OWIN和Katana有了基本的了解,那么这篇文章我将继续OWIN和Katana之旅——创建自定义的Middleware中间件. 何为Middleware中间件 M ...

  8. 带你走近AngularJS - 创建自定义指令

    带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...

  9. [转]maven创建自定义的archetype

    创建自己的archetype一般有两种方式,比较简单的就是create from project 1.首先使用eclipse创建一个新的maven project,然后把配置好的一些公用的东西放到相应 ...

随机推荐

  1. arc engine - IName

    IName对象是一个代表性对象.通过使用IName对象,可以访问它所代表的对象的一些基本属性,而不用将整个对象调入内存.我们用IWorkspace 获得一个Workspace,那可是会调入内存的,而I ...

  2. 再入门JavaScript

    从去年毕业到现今,工作不到一年.接触了3个实际项目,一个实训项目.却反而只有实训项目做的比较像样子. 重新又回到写脚本的岗位上,第一次真正意义上接触脚本应该是在达内培训时候李大神所引进,大神各种技术, ...

  3. 【译】神经网络与深度学习 Ch1-Section0

    用神经网络识别手写数字 人类的视觉系统是是大自然的奇迹.考虑下面手写数字序列: 大多数人能够轻易地是识别出是504192.在我们大脑的每个半球都有一个基础的皮质,这就是我们熟知的V1区,它包含了14亿 ...

  4. mac qq截图功能失效后,如何重启截图功能?

    在finder中打开应用程序目录,找到QQ,右键单击QQ,选择显示包内容,此时会打开一个文件夹. 进入以下路径Library/LoginItems然后双击ScreenCapture这个进程,截图功能即 ...

  5. php的一些小笔记-文件函数(3)

    文件的写入和读取 1 . 文件的读取 1, file_get_contents 函数是用来将文件的内容读入到一个字符串中的首选方法    结果

  6. WordPress插件制作教程(七): 插件函数之过滤器(Filter)函数

    上一篇对插件函数之动作(Action)函数做了下介绍,这篇在介绍下过滤器(Filters). 过滤器是一类函数,WordPress执行传递和处理数据的过程中,在针对这些数据做出某些动作之前的特定运行( ...

  7. Makefile的几个赋值运算符(转:笔记)

    http://www.cnblogs.com/pengdonglin137/p/3801060.html 在Makefile中我们经常看到 = := ?= +=这几个赋值运算符,那么他们有什么区别呢? ...

  8. A51汇编器的解释

    A51汇编器是运行于IBM PC系列及其兼容机上的交叉汇编软件,其主要功能是将MCS-51系列单片机汇编语言源程序翻译成符合Intel目标文件格式的可再定位的目标代码,经过L51连接器的连接和装配,产 ...

  9. 单线多拨,傻瓜式openwrt单线多拨叠加速率教程

    http://bbs.pceva.com.cn/thread-98362-1-1.html

  10. bzoj1753 [Usaco2005 qua]Who's in the Middle

    Description FJ is surveying his herd to find the most average cow. He wants to know how much milk th ...