• 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 = 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。
  • 相关阅读:
    C++学习:explicit关键字
    CMake入门——简单CMakeLists的编写
    EOJ Monthly 2020.1 E. 数的变幻
    CF #610Div2 B2.K for the Price of One (Hard Version) (dp解法 && 贪心解法)
    hdu 5147 Sequence II【树状数组/线段树】
    hdu 6581 Vacation【思维】
    dubbo源码学习(一)之ExtensionLoader
    xsd学习教程
    spring自定义schema学习
    如何更好地学习dubbo源代码(转)
  • 原文地址:https://www.cnblogs.com/kevinl/p/13364497.html
Copyright © 2020-2023  润新知