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) ...
随机推荐
- 【MySql】权限不足导致的无法连接到数据库以及权限的授予和撤销
[环境参数] 1.Host OS:Win7 64bit 2.Host IP:192.168.10.1 3.VM: VMware 11.1.0 4.Client OS:CentOS 6 5.Client ...
- c#与vb.net在App_Code里面编译要通过,需要以下web.config的配置
web.config的配置: <system.web> <codeSubDirectories> <add directoryName="VB"/&g ...
- 30大最有影响力的Web设计与开发英文博客
1stwebdesigner的创始人Dainis Graveris挑选出30个高质量和具有影响力的Web设计与前端技术博客,其中很多我们都耳熟能详.但这么完整的列表,还是值得收藏的.另外,你大概不会了 ...
- nginx配置 首页不显示 index.html首页是显示域名
原状况如下: 访问:www.test.com 敲回车后浏览器中自动跳转致: www.test.com/index.html 公司新需求如下: 访问:www.test.com 敲回车后浏览器中url不变 ...
- POJ 3304 Segments (直线和线段相交判断)
Segments Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7739 Accepted: 2316 Descript ...
- C#读取文件为byte数组
private byte[] FileContent(string fileName) { using (FileStream fs = new FileStream(fileName, FileMo ...
- Dom操作的分类
1.DOM core 使用DOM core来获取表单对象的方法: document.getElementByTagName("form"); 使用DOM Core来获取某元素的sr ...
- Heritrix 3.1.0 源码解析(三十七)
今天有兴趣重新看了一下heritrix3.1.0系统里面的线程池源码,heritrix系统没有采用java的cocurrency包里面的并发框架,而是采用了线程组ThreadGroup类来实现线程池的 ...
- Windows操作系统单文件夹下到底能存放多少文件及单文件的最大容量
本文是转自:http://hi.baidu.com/aqgjoypubihoqxr/item/c896921f8c2eaba5feded5f2 最近需要了解Windows中单个文件夹下 ...
- 【转】Android -- Looper.prepare()和Looper.loop()
Looper.prepare()和Looper.loop() 原文地址:http://blog.csdn.net/heng615975867/article/details/9194219 Andro ...