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) ...
随机推荐
- android get uuid获取uuid
https://github.com/Paldom/UniqueDeviceID protected void getDeviceUUID(){ try { Context context = cor ...
- MYSQL数据库性能调优之八:mysql日志
MySQL日志 主要包含:错误日志.查询日志.慢查询日志.事务日志.二进制日志.中继日志: 使用 SHOW GLOBAL VARIABLES LIKE '%log%'; 查询所有日志配置详情: 一. ...
- POJ 1696 Space Ant(极角排序)
Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2489 Accepted: 1567 Descrip ...
- Jsp页面设计易忘点
文本标签: <b>文本加粗 <i>斜体 <u>下划线 <sub>作为下标 <sup>作为上标 样式: italic;斜体 text-deco ...
- LC并联谐振回路
- UVALive 7079 - How Many Maos Does the Guanxi Worth(最短路Floyd)
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- SQLCONNECTION使用HTTP通信协议和中间件连接
SQLCONNECTION支持TCP/IP和HTTP两种通信协议和中间件连接.一般地,默认情况下使用TCP/IP协议. HTTP 协议的一个非常重要的优势在于穿越防火墙. SQLCONNECTION使 ...
- How Tomcat Works(十四)补充
在How Tomcat Works(十四)中,本人并没有对javax.servlet.Filter及javax.servlet.FilterChain做详细的描述,本文在这里做一下补充 FilterC ...
- iOS国际化多语言设置
一.创建工程.添加语言
- C# 获取字符串中的数字
/// <summary> /// 获取字符串中的数字(不包含小数点) /// </summary> /// <param name="str"> ...