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) ...
随机推荐
- openstack neutron网络主机节点网口配置 liberty版本之前的
- JVM内存的那些事
前言 对于C语言开发的程序员来说,在内存管理方面,必须负责每一个对象的生命周期,从有到无. 对于Java程序员你来说,在虚拟机内存管理的帮助下,不需要为每个new对象都匹配free操作,内存泄露和内存 ...
- 第三百五十五天 how can I 坚持
快一年了,三百五十五天了,等写个程序算算时间,看看日期和天数能不能对的上,哈哈. 计划还是未制定,天气预报还是没有写完,立马行动,发完这个博客,立马行动. 计划:设计模式1个月,三大框架3个月,计算机 ...
- 【转】Hive导入10G数据的测试
原博文出自于: http://blog.fens.me/hadoop-hive-10g/ 感谢! Hive导入10G数据的测试 让Hadoop跑在云端系列文章,介绍了如何整合虚拟化和Hadoop,让H ...
- Linux下的设置静态IP命令详解
网络配置的配置文件在/etc/sysconfig/network-scripts/下,文件名前缀为ifcfg-后面跟的就是网卡的名称,可以通过双TAB键查看然后编辑,也可以使用ifconfig查看,也 ...
- HDU 4619 Warm up 2(2013多校2 1009 二分匹配)
Warm up 2 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total S ...
- Swift项目兼容Objective-C问题汇总
Swift项目兼容Objective-C问题汇总 转载自 http://www.cocoachina.com/swift/20150608/12025.html 本文是投稿文章,作者:一叶(博客)欢迎 ...
- C#上位机读数据库
string connectionString = string.Format("server=(local);uid=sa;pwd=1234567890;database=msp430&q ...
- Mysql用户密码设置修改和权限分配
我的mysql安装在c:\mysql 一.更改密码 第一种方式: 1.更改之前root没有密码的情况 c:\mysql\bin>mysqladmin -u root password " ...
- JavaBean技术
引言: JavaBeans与一般Java类的编写类似. 在JSP页面中要使用JavaBeans,只要在JSP页面中使用JavaBeans的操作标记就可以了. JavaBeans的编写和使用非常简单,下 ...