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. ajaxFileUpload js判断类型

    function ajaxFileUpload() {    var File_box = document.getElementById('V_file');    var extend = Fil ...

  2. python字符串的encode和decode

    原文 decode的作用是将其他编码的字符串转换成unicode编码. str1.decode('gb2312') #表示将gb2312编码的字符串转换成unicode编码 encode的作用是将un ...

  3. css3实现各种渐变效果,比较适合做手机触屏版

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. C语言函数指针变量和指针函数以及指针数组

    C语言中,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址.我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数.然后通过指针变量就可以找到并调用这 ...

  5. NPAPI开发常识

    其实,就在几天前,我根本不知道什么是NPAPI插件.因为最近的项目中用到需要在非IE下检测客户端是否安装,最终找到浏览器插件NPAPI. 以下资料来源于网络收集,以此给那些和我一样迷茫的人.本文的目的 ...

  6. POJ 3709 K-Anonymous Sequence (单调队列优化)

    题意:给定一个不下降数列,一个K,将数列分成若干段,每段的数字个数不小于K,每段的代价是这段内每个数字减去这段中最小数字之和.求一种分法使得总代价最小? 思路:F[i]表示到i的最小代价.f[i]=m ...

  7. win8、win8.1官方版本、及安装密钥

    云盘地址:Windows 8 简体中文专业版+核心版 MSDN 正式版(32位)http://pan.baidu.com/s/1eQgiAiQSHA1:0C4A168E37E38EFB59E88443 ...

  8. sizeof与类,继承,virtual的种种

    对虚继承层次的对象的内存布局,在不同编译器实现有所区别. 首先,说说GCC的编译器. 它实现比较简单,不管是否虚继承,GCC都是将虚表指针在整个继承关系中共享的,不共享的是指向虚基类的指针. clas ...

  9. VS下 dllimport与dllexport作用与区别

    我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是C++的类的话 ...

  10. Red Hat Enterprise Linux 7的新功能

     简介红帽最新版本的旗舰平台交付显著增强的可用性. 性能和可靠性. 丰富的新功能为架构. 系统管理员和开发人员提供所需的资源以更高效地进行创新和管理.架构师: 红帽® 企业 Linux® 7 适合 ...