C# 使用GDI+绘制漂亮的MenuStrip和ContextMenuStrip皮肤
通过上面的效果截图可以看到,重绘后的MenuStrip和ContextMenuStrip可以添加自己的LOGO信息,实现了类似OFFICE2007的菜单显示效果。
.NET对菜单控件的绘制提供了一个抽象类ToolStripRenderer,这个类里面提供了相应的绘制函数,只要重写这些函数,就可以实现菜单的重绘。MenuStrip和ContextMenuStrip提供了一个属性Renderer,该属性就是由ToolStripRenderer定义的,MenuStrip和ContextMenuStrip的Renderer属性设置为继承ToolStripRenderer的绘制类,就可以轻松的绘制MenuStrip和ContextMenuStrip的皮肤了。
下面就是继承ToolStripRenderer类实现的本文开始贴出的菜单效果图的ProfessionalToolStripRendererEx类的代码:
public class ProfessionalToolStripRendererEx
: ToolStripRenderer
{
private static readonly int OffsetMargin = ;
private string _menuLogoString = "更多精彩尽在 www.csharpwin.com";
private ToolStripColorTable _colorTable;
public ProfessionalToolStripRendererEx()
: base()
{
}
public ProfessionalToolStripRendererEx(
ToolStripColorTable colorTable) : base()
{
_colorTable = colorTable;
}
public string MenuLogoString
{
get { return _menuLogoString; }
set { _menuLogoString = value; }
}
protected virtual ToolStripColorTable ColorTable
{
get
{
if (_colorTable == null)
{
_colorTable = new ToolStripColorTable();
}
return _colorTable;
}
}
protected override void OnRenderToolStripBackground(
ToolStripRenderEventArgs e)
{
ToolStrip toolStrip = e.ToolStrip;
Graphics g = e.Graphics;
Rectangle bounds = e.AffectedBounds;
if (toolStrip is ToolStripDropDown)
{
RegionHelper.CreateRegion(toolStrip, bounds);
using (SolidBrush brush = new SolidBrush(ColorTable.BackNormal))
{
g.FillRectangle(brush, bounds);
}
}
else if (toolStrip is MenuStrip)
{
LinearGradientMode mode =
toolStrip.Orientation == Orientation.Horizontal ?
LinearGradientMode.Vertical : LinearGradientMode.Horizontal;
RenderHelper.RenderBackgroundInternal(
g,
bounds,
ColorTable.Base,
ColorTable.Border,
ColorTable.BackNormal,
RoundStyle.None,
,
.35f,
false,
false,
mode);
}
else
{
base.OnRenderToolStripBackground(e);
}
}
protected override void OnRenderImageMargin(
ToolStripRenderEventArgs e)
{
ToolStrip toolStrip = e.ToolStrip;
Graphics g = e.Graphics;
Rectangle bounds = e.AffectedBounds;
if (toolStrip is ToolStripDropDown)
{
bool bDrawLogo = NeedDrawLogo(toolStrip);
bool bRightToLeft = toolStrip.RightToLeft == RightToLeft.Yes;
Rectangle imageBackRect = bounds;
imageBackRect.Width = OffsetMargin;
if (bDrawLogo)
{
Rectangle logoRect = bounds;
logoRect.Width = OffsetMargin;
if (bRightToLeft)
{
logoRect.X -= ;
imageBackRect.X = logoRect.X - OffsetMargin;
}
else
{
logoRect.X += ;
imageBackRect.X = logoRect.Right;
}
logoRect.Y += ;
logoRect.Height -= ;
using (LinearGradientBrush brush = new LinearGradientBrush(
logoRect,
ColorTable.BackHover,
ColorTable.BackNormal,
90f))
{
Blend blend = new Blend();
blend.Positions = new float[] { 0f, .2f, 1f };
blend.Factors = new float[] { 0f, 0.1f, .9f };
brush.Blend = blend;
logoRect.Y += ;
logoRect.Height -= ;
using (GraphicsPath path =
GraphicsPathHelper.CreatePath(logoRect, , RoundStyle.All, false))
{
using (SmoothingModeGraphics sg = new SmoothingModeGraphics(g))
{
g.FillPath(brush, path);
}
}
}
StringFormat sf = new StringFormat(StringFormatFlags.NoWrap);
Font font = new Font(
toolStrip.Font.FontFamily, , FontStyle.Bold);
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
sf.Trimming = StringTrimming.EllipsisCharacter;
g.TranslateTransform(logoRect.X, logoRect.Bottom);
g.RotateTransform(270f);
if (!string.IsNullOrEmpty(MenuLogoString))
{
Rectangle newRect = new Rectangle(
, , logoRect.Height, logoRect.Width);
using (Brush brush = new SolidBrush(ColorTable.Fore))
{
using (TextRenderingHintGraphics tg =
new TextRenderingHintGraphics(g))
{
g.DrawString(
MenuLogoString,
font,
brush,
newRect,
sf);
}
}
}
g.ResetTransform();
}
else
{
if (bRightToLeft)
{
imageBackRect.X -= ;
}
else
{
imageBackRect.X += ;
}
}
imageBackRect.Y += ;
imageBackRect.Height -= ;
using (SolidBrush brush = new SolidBrush(ColorTable.DropDownImageBack))
{
g.FillRectangle(brush, imageBackRect);
}
Point ponitStart;
Point pointEnd;
if (bRightToLeft)
{
ponitStart = new Point(imageBackRect.X, imageBackRect.Y);
pointEnd = new Point(imageBackRect.X, imageBackRect.Bottom);
}
else
{
ponitStart = new Point(imageBackRect.Right - , imageBackRect.Y);
pointEnd = new Point(imageBackRect.Right - , imageBackRect.Bottom);
}
using (Pen pen = new Pen(ColorTable.DropDownImageSeparator))
{
g.DrawLine(pen, ponitStart, pointEnd);
}
}
else
{
base.OnRenderImageMargin(e);
}
}
protected override void OnRenderToolStripBorder(
ToolStripRenderEventArgs e)
{
ToolStrip toolStrip = e.ToolStrip;
Graphics g = e.Graphics;
Rectangle bounds = e.AffectedBounds;
if (toolStrip is ToolStripDropDown)
{
using (SmoothingModeGraphics sg = new SmoothingModeGraphics(g))
{
using (GraphicsPath path =
GraphicsPathHelper.CreatePath(bounds, , RoundStyle.All, true))
{
using (Pen pen = new Pen(ColorTable.DropDownImageSeparator))
{
path.Widen(pen);
g.DrawPath(pen, path);
}
}
}
bounds.Inflate(-, -);
using (GraphicsPath innerPath = GraphicsPathHelper.CreatePath(
bounds, , RoundStyle.All, true))
{
using (Pen pen = new Pen(ColorTable.BackNormal))
{
g.DrawPath(pen, innerPath);
}
}
}
else if (toolStrip is StatusStrip)
{
using (Pen pen = new Pen(ColorTable.Border))
{
e.Graphics.DrawRectangle(
pen, , , e.ToolStrip.Width - , e.ToolStrip.Height - );
}
}
else if (toolStrip is MenuStrip)
{
base.OnRenderToolStripBorder(e);
}
else
{
using (Pen pen = new Pen(ColorTable.Border))
{
g.DrawRectangle(
pen, , , e.ToolStrip.Width - , e.ToolStrip.Height - );
}
}
}
protected override void OnRenderMenuItemBackground(
ToolStripItemRenderEventArgs e)
{
ToolStrip toolStrip = e.ToolStrip;
ToolStripItem item = e.Item;
if (!item.Enabled)
{
return;
}
Graphics g = e.Graphics;
Rectangle rect = new Rectangle(Point.Empty, e.Item.Size);
if (toolStrip is MenuStrip)
{
LinearGradientMode mode =
toolStrip.Orientation == Orientation.Horizontal ?
LinearGradientMode.Vertical : LinearGradientMode.Horizontal;
if (item.Selected)
{
RenderHelper.RenderBackgroundInternal(
g,
rect,
ColorTable.BackHover,
ColorTable.Border,
ColorTable.BackNormal,
RoundStyle.All,
true,
true,
mode);
}
else if (item.Pressed)
{
RenderHelper.RenderBackgroundInternal(
g,
rect,
ColorTable.BackPressed,
ColorTable.Border,
ColorTable.BackNormal,
RoundStyle.All,
true,
true,
mode);
}
else
{
base.OnRenderMenuItemBackground(e);
}
}
else if (toolStrip is ToolStripDropDown)
{
bool bDrawLogo = NeedDrawLogo(toolStrip);
int offsetMargin = bDrawLogo ? OffsetMargin : ;
if (item.RightToLeft == RightToLeft.Yes)
{
rect.X += ;
}
else
{
rect.X += offsetMargin + ;
}
rect.Width -= offsetMargin + ;
rect.Height--;
if (item.Selected)
{
RenderHelper.RenderBackgroundInternal(
g,
rect,
ColorTable.BackHover,
ColorTable.Border,
ColorTable.BackNormal,
RoundStyle.All,
true,
true,
LinearGradientMode.Vertical);
}
else
{
base.OnRenderMenuItemBackground(e);
}
}
else
{
base.OnRenderMenuItemBackground(e);
}
}
protected override void OnRenderItemImage(
ToolStripItemImageRenderEventArgs e)
{
ToolStrip toolStrip = e.ToolStrip;
Graphics g = e.Graphics;
if (toolStrip is ToolStripDropDown &&
e.Item is ToolStripMenuItem)
{
bool bDrawLogo = NeedDrawLogo(toolStrip);
int offsetMargin = bDrawLogo ? OffsetMargin : ;
ToolStripMenuItem item = (ToolStripMenuItem)e.Item;
if (item.Checked)
{
return;
}
Rectangle rect = e.ImageRectangle;
if (e.Item.RightToLeft == RightToLeft.Yes)
{
rect.X -= offsetMargin + ;
}
else
{
rect.X += offsetMargin + ;
}
using (InterpolationModeGraphics ig =
new InterpolationModeGraphics(g))
{
ToolStripItemImageRenderEventArgs ne =
new ToolStripItemImageRenderEventArgs(
g, e.Item, e.Image, rect);
base.OnRenderItemImage(ne);
}
}
else
{
base.OnRenderItemImage(e);
}
}
protected override void OnRenderItemText(
ToolStripItemTextRenderEventArgs e)
{
ToolStrip toolStrip = e.ToolStrip;
e.TextColor = ColorTable.Fore;
if (toolStrip is ToolStripDropDown &&
e.Item is ToolStripMenuItem)
{
bool bDrawLogo = NeedDrawLogo(toolStrip);
int offsetMargin = bDrawLogo ? : ;
Rectangle rect = e.TextRectangle;
if (e.Item.RightToLeft == RightToLeft.Yes)
{
rect.X -= offsetMargin;
}
else
{
rect.X += offsetMargin;
}
e.TextRectangle = rect;
}
base.OnRenderItemText(e);
}
protected override void OnRenderItemCheck(
ToolStripItemImageRenderEventArgs e)
{
ToolStrip toolStrip = e.ToolStrip;
Graphics g = e.Graphics;
if (toolStrip is ToolStripDropDown &&
e.Item is ToolStripMenuItem)
{
bool bDrawLogo = NeedDrawLogo(toolStrip);
int offsetMargin = bDrawLogo ? OffsetMargin : ;
Rectangle rect = e.ImageRectangle;
if (e.Item.RightToLeft == RightToLeft.Yes)
{
rect.X -= offsetMargin + ;
}
else
{
rect.X += offsetMargin + ;
}
rect.Width = ;
rect.Y += ;
rect.Height -= ;
using (SmoothingModeGraphics sg = new SmoothingModeGraphics(g))
{
using (GraphicsPath path = new GraphicsPath())
{
path.AddRectangle(rect);
using (PathGradientBrush brush = new PathGradientBrush(path))
{
brush.CenterColor = Color.White;
brush.SurroundColors = new Color[] { ControlPaint.Light(ColorTable.BackNormal) };
Blend blend = new Blend();
blend.Positions = new float[] { 0f, 0.3f, 1f };
blend.Factors = new float[] { 0f, 0.5f, 1f };
brush.Blend = blend;
g.FillRectangle(brush, rect);
}
}
using (Pen pen = new Pen(ControlPaint.Light(ColorTable.BackNormal)))
{
g.DrawRectangle(pen, rect);
}
ControlPaintEx.DrawCheckedFlag(g, rect, ColorTable.Fore);
}
}
else
{
base.OnRenderItemCheck(e);
}
}
protected override void OnRenderArrow(
ToolStripArrowRenderEventArgs e)
{
if (e.Item.Enabled)
{
e.ArrowColor = ColorTable.Fore;
}
ToolStrip toolStrip = e.Item.Owner;
if (toolStrip is ToolStripDropDown &&
e.Item is ToolStripMenuItem)
{
bool bDrawLogo = NeedDrawLogo(toolStrip);
int offsetMargin = bDrawLogo ? : ;
Rectangle rect = e.ArrowRectangle;
if (e.Item.RightToLeft == RightToLeft.Yes)
{
rect.X -= offsetMargin;
}
else
{
rect.X += offsetMargin;
}
e.ArrowRectangle = rect;
}
base.OnRenderArrow(e);
}
protected override void OnRenderSeparator(
ToolStripSeparatorRenderEventArgs e)
{
ToolStrip toolStrip = e.ToolStrip;
Rectangle rect = e.Item.ContentRectangle;
Graphics g = e.Graphics;
if (toolStrip is ToolStripDropDown)
{
bool bDrawLogo = NeedDrawLogo(toolStrip);
int offsetMargin = bDrawLogo ?
OffsetMargin * : OffsetMargin;
if (e.Item.RightToLeft != RightToLeft.Yes)
{
rect.X += offsetMargin + ;
}
rect.Width -= offsetMargin + ;
}
RenderSeparatorLine(
g,
rect,
ColorTable.DropDownImageSeparator,
ColorTable.BackNormal,
SystemColors.ControlLightLight,
e.Vertical);
}
internal void RenderSeparatorLine(
Graphics g,
Rectangle rect,
Color baseColor,
Color backColor,
Color shadowColor,
bool vertical)
{
float angle;
if (vertical)
{
angle = 90F;
}
else
{
angle = 180F;
}
using (LinearGradientBrush brush = new LinearGradientBrush(
rect,
baseColor,
backColor,
angle))
{
Blend blend = new Blend();
blend.Positions = new float[] { 0f, .2f, .5f, .8f, 1f };
blend.Factors = new float[] { 1f, .3f, 0f, .3f, 1f };
brush.Blend = blend;
using (Pen pen = new Pen(brush))
{
if (vertical)
{
g.DrawLine(pen, rect.X, rect.Y, rect.X, rect.Bottom);
}
else
{
g.DrawLine(pen, rect.X, rect.Y, rect.Right, rect.Y);
}
brush.LinearColors = new Color[] {
shadowColor, ColorTable.BackNormal };
pen.Brush = brush;
if (vertical)
{
g.DrawLine(pen, rect.X + , rect.Y, rect.X + , rect.Bottom);
}
else
{
g.DrawLine(pen, rect.X, rect.Y + , rect.Right, rect.Y + );
}
}
}
}
internal bool NeedDrawLogo(ToolStrip toolStrip)
{
ToolStripDropDown dropDown = toolStrip as ToolStripDropDown;
bool bDrawLogo =
(dropDown.OwnerItem != null &&
dropDown.OwnerItem.Owner is MenuStrip) ||
(toolStrip is ContextMenuStrip);
return bDrawLogo;
}
}
}
实现MenuStrip和ContextMenuStrip重绘并不是很难的事情,这里就不过多的介绍,C# 使用GDI+绘制漂亮的MenuStrip和ContextMenuStrip皮肤就为你介绍到这里,希望你能喜欢。
声明:
本文版权归作者和CS 程序员之窗所有,欢迎转载,转载必须保留以下版权信息,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
作者:Starts_2000
出处:CS 程序员之窗 http://www.csharpwin.com。
你可以免费使用或修改提供的源代码,但请保留源代码中的版权信息,详情请查看:
CS程序员之窗开源协议 http://www.csharpwin.com/csol.html。
C# 使用GDI+绘制漂亮的MenuStrip和ContextMenuStrip皮肤的更多相关文章
- 通过GDI+绘制 验证码
只为了记录下自己的学习历程,方便日后查看 现在开始言归正传,以下为其完整代码附上 using System; using System.Collections.Generic; using Syste ...
- C#利用GDI+绘制旋转文字等效果
C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现.但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少.经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经 ...
- MFC 用gdi绘制填充多边形区域
MFC 用gdi绘制填充多边形区域 这里的代码是实现一个三角形的绘制,并用刷子填充颜色 在OnPaint()函数里面 运用的是给定的三角形的三个点,很多个点可以绘制多边形 CBrush br(RGB( ...
- GDI绘制时钟效果,与系统时间保持同步,基于Winform
2018年工作之余,想起来捡起GDI方面的技术,特意在RichCodeBox项目中做了两个示例程序,其中一个就是时钟效果,纯C#开发.这个CSharpQuartz是今天上午抽出一些时间,编写的,算是偷 ...
- 『备注』GDI+ 绘制文本有锯齿,透明背景文本绘制
背景: GDI+ 绘制文本 时,如果 背景是透明的 —— 则会出现 锯齿. //其实,我不用这三个 属性 好多年了 //而且,这三个属性 在关键时刻还有可能 帮倒忙 //关键是:这三个属性,鸟用都没有 ...
- C#GDI+ 绘制线段(实线或虚线)、矩形、字符串、圆、椭圆
C#GDI+ 绘制线段(实线或虚线).矩形.字符串.圆.椭圆 绘制基本线条和图形 比较简单,直接看代码. Graphics graphics = e.Graphics; //绘制实线 )) { pen ...
- C# GDI绘制仪表盘(纯代码实现)
纯代码实现GDI绘制仪表盘,效果在代码下面. public partial class HalfDashboardUc : UserControl { /// <summary> /// ...
- 使用echarts绘制漂亮的渐变键盘仪表盘
echarts官方示例和默认样式都比较难看,经过一顿捣鼓实现比较漂亮的渐变仪表盘. 第一步:设置轴线 将图表轴线.label.分割线.隐藏,只保留刻度,然后修改刻度样式达到最终效果.不过要注意的是ax ...
- 如何使用GDI绘制半透明矩形
/*使用GDI绘制半透明矩形*/ void CDirectXDraw::DrawHalfOpacityRect(HDC hdc,CRect rect) { CDC dc; dc.Attach(hdc) ...
随机推荐
- c++面试题总结(2)
1. C中static有什么作用 (1)隐藏. 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,故使用static在不同的文件中定义同名函数和同名变量,而不必担心命 ...
- HDU1150Machine Schedule(二分图最大匹配的DFS解法)
题目大意就是说有两台机器,分别有n,m种模式可以调节,有k个工作,某一个工作i可以在第一台机器的a[i]模式下或第二台机器的b[i]模式下工作,两台机器的初始模式为0,问如何分配这K件工作使得两台机器 ...
- POJ 1852 Ants (等价思考)
题意:在一根杆上有 n 只蚂蚁,速度为1,方向不定,如果相碰,则反向运动,问你最长的时间和最短时间,所有蚂蚁都掉下杆去. 析:换个方法想,如果两只蚂蚁相碰了,会有什么现象?其实就和没有碰撞是一样的,没 ...
- VS2010 用WebBrowser控件 无响应
问题:偶尔我遇到这个问题,不知怎么的,拖放这个web控件它就卡死,无法响应,其他应用程序没有影响,任务管理器显示无法响应. 解决:原来是有道翻译的问题,具体为什么不清楚,只要一打开有道翻译,用web控 ...
- UI进阶 科大讯飞(1) 语音听写(语音转换成文字)
一.科大讯飞开放平台: http://www.xfyun.cn/ 注册.登录之后创建新应用. 因为本项目只实现了语音听写,所以在SDK下载中心勾选语音听写单项SDK就可以了 开发平台选择iOS,应用选 ...
- C# List 中 Find 方法
实例化一个集合 List<User> userCollection = new List<User>(); userCollection.Add(new User(1, &qu ...
- 网页上的JS call Unity3d里的function——SendMessage
注意: sendmessage只可以从网页发信息到unity游戏里,但是没有返回值 只可以发布三种类型的data,不可以其他复杂的强类型 发信息的时不会做编译检测 SendMessage Workfl ...
- SVN安装与使用
来自:http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407610.html SVN服务器搭建和使用(一) Subversion是优秀的版 ...
- Number
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseInt 概述 parseIn ...
- url中的scheme
iPhone上URL Schemes的作用为应用程序提供了一个其他应用程序或者safari可以启动他的方法. --http://blog.sina.com.cn/s/blog_5673c12f0100 ...