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. Android异步请求

    class MyTask_SendMessage extends AsyncTask<String, Void, String> { @Override protected void on ...

  2. js中window.print()去除页眉页脚

    //jsp打印时去除页眉页页脚 打印前加入下面代码即可 var HKEY_Root,HKEY_Path,HKEY_Key; HKEY_Root="HKEY_CURRENT_USER" ...

  3. 华为oj 计算字符个数

    练手而已 #include <stdio.h> #include <string.h> int main(void) { char string[200]={'\0'}; in ...

  4. 3、HelloKhala示例说明

    最简单的dome程序只需3行代码 int main() { //设置端口号 InetAddress listenAddr(USER_PORT); //将端口号绑定到Server NodeServer ...

  5. hdu2488 dfs

    G - 深搜 基础 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:65536KB     64bi ...

  6. wind7下搭建ftp服务器

    一.首先在本地机器上创建一个用户!这些用户是用来登录到FTP的!我的电脑右键->控制面板->管理工具->计算机管理->本地用户和组->用户->“右键”新建用户-&g ...

  7. Oracle11g R2学习系列 之八高级数据类型

    所谓的高级数据类型,就是大数据类型,即BCNB(助记词:BC牛逼)+XML数据类型. B:blob,用来存储可变长度的二进制数据. C:clob,主要用来存储可变长度的字符型数据,也就是其他数据库中提 ...

  8. 给EcStore商城会员添加推广返利功能

    EcStore商城后台应用中心安装“网站推广”应用,会员成为推广员有二种途径:一是后台/推广设置/推广员审核/推广注册模式设为:需注册后审核成为推广员 此模式下前台会员在使用推广前,需要在会员中心申请 ...

  9. Python-----格式化字符

    摘要: Python中 %s . %r Python中也有类似于C中的 printf()格式输出,使用 % 运算符,格式: 格式标记字符串 % 要输出的值组 右边的”值组“若有两个及以上的值则需要用小 ...

  10. 【转】简析SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue

    转载地址:http://blog.csdn.net/mn11201117/article/details/8671497 SynchronousQueue SynchronousQueue是无界的,是 ...