通过上面的效果截图可以看到,重绘后的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 = 24;
 
        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,
                    0,
                    .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 -= 2;
                        imageBackRect.X = logoRect.X - OffsetMargin;
                    }
                    else
                    {
                        logoRect.X += 2;
                        imageBackRect.X = logoRect.Right;
                    }
                    logoRect.Y += 1;
                    logoRect.Height -= 2;
 
                    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 += 1;
                        logoRect.Height -= 2;
                        using (GraphicsPath path =
                            GraphicsPathHelper.CreatePath(logoRect, 8, 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, 11, 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(
                            0, 0, 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 -= 3;
                    }
                    else
                    {
                        imageBackRect.X += 3;
                    }
                }
 
                imageBackRect.Y += 2;
                imageBackRect.Height -= 4;
                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 - 1, imageBackRect.Y);
                    pointEnd = new Point(imageBackRect.Right - 1, 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, 8, RoundStyle.All, true))
                    {
                        using (Pen pen = new Pen(ColorTable.DropDownImageSeparator))
                        {
                            path.Widen(pen);
                            g.DrawPath(pen, path);
                        }
                    }
                }
 
                bounds.Inflate(-1, -1);
                using (GraphicsPath innerPath = GraphicsPathHelper.CreatePath(
                    bounds, 8, 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, 0, 0, e.ToolStrip.Width - 1, e.ToolStrip.Height - 1);
                }
            }
            else if (toolStrip is MenuStrip)
            {
                base.OnRenderToolStripBorder(e);
            }
            else
            {
                using (Pen pen = new Pen(ColorTable.Border))
                {
                    g.DrawRectangle(
                        pen, 0, 0, e.ToolStrip.Width - 1, e.ToolStrip.Height - 1);
                }
            }
        }
 
        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 : 0;
 
                if (item.RightToLeft == RightToLeft.Yes)
                {
                    rect.X += 4;
                }
                else
                {
                    rect.X += offsetMargin + 4;
                }
                rect.Width -= offsetMargin + 8;
                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 : 0;
 
                ToolStripMenuItem item = (ToolStripMenuItem)e.Item;
                if (item.Checked)
                {
                    return;
                }
                Rectangle rect = e.ImageRectangle;
                if (e.Item.RightToLeft == RightToLeft.Yes)
                {
                    rect.X -= offsetMargin + 2;
                }
                else
                {
                    rect.X += offsetMargin + 2;
                }
 
                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 ? 18 : 0;
 
                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 : 0;
                Rectangle rect = e.ImageRectangle;
 
                if (e.Item.RightToLeft == RightToLeft.Yes)
                {
                    rect.X -= offsetMargin + 2;
                }
                else
                {
                    rect.X += offsetMargin + 2;
                }
 
                rect.Width = 13;
                rect.Y += 1;
                rect.Height -= 3;
 
                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 ? 3 : 0;
 
                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 * 2 : OffsetMargin;
 
                if (e.Item.RightToLeft != RightToLeft.Yes)
                {
                    rect.X += offsetMargin + 2;
                }
                rect.Width -= offsetMargin + 4;
            }
 
            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 + 1, rect.Y, rect.X + 1, rect.Bottom);
                    }
                    else
                    {
                        g.DrawLine(pen, rect.X, rect.Y + 1, rect.Right, rect.Y + 1);
                    }
                }
            }
        }
 
        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。