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) ...
随机推荐
- linux rar工具
rar系统工具: wget http://www.rarlab.com/rar/rarlinux-3.8.0.tar.gz tar -zxvf rarlinux-3.8.0.tar.gz cd rar ...
- C#修改下拉框选项的高度
重写ListBox.DrawItem事件处理,别忘记将ListBox.DrawMode 设置为OwnerDrawVariable,ListBox.ItemHeight值改大一点,字体也适当放大一号. ...
- JVM性能优化,提高Java的伸缩性
很多程序员在解决JVM性能问题的时候,花开了很多时间去调优应用程序级别的性能瓶颈,当你读完这本系列文章之后你会发现我可能更加系统地看待这类的问题.我说过JVM的自身技术限制了Java企业级应用的伸缩性 ...
- 详解Android定位
相信很多的朋友都有在APP中实现定位的需求,今天我就再次超炒冷饭,为大家献上国内开发者常用到的三种定位方式.它们分别为GPS,百度和高德,惯例先简单介绍下定位的背景知识. 什么是GPS定位.基站定位和 ...
- [iOS微博项目 - 2.6] - 获取微博数据
github: https://github.com/hellovoidworld/HVWWeibo A.新浪获取微博API 1.读取微博API 2.“statuses/home_time ...
- php连接oracle数据库转载
php连接oracle数据库及查询数据的方法 投稿:shichen2014 字体:[增加 减小] 类型:转载 时间:2014-12-29 这篇文章主要介绍了php连接oracle数据库及查询数据的方法 ...
- 如何在使用了updatepanel后弹出提示信息
转载:http://www.cnblogs.com/brusehht/archive/2009/03/19/1416802.html 常情况下,我们在使用ajax利用updatepanel实现页面局部 ...
- counting sort 计数排序
//counting sort 计数排序 //参考算法导论8.2节 #include<cstdio> #include<cstring> #include<algorit ...
- 关于 TIdHttp
经验总结: 1.IdHttp 不支持多线程,只支持异步.所有网上的多线程写法下,如果同时并发多个长 GET 或 POST 请求时,会阻塞. 以下代码用于显示下载数据的进程. procedure TFo ...
- C++ 初始化与赋值
1.初始化与赋值的区别: 二者的区别不是看,是否有=这个赋值操作符,而是看操作的时候,对象是否已经有值. 初始化:创建对象,并给它设置初始值. 赋值:对象已经有值,擦除对象的当前值,并使用新值代替. ...