Windows 10 风格的 ContextMenuStrip

7

有没有一种使用Visual Studio和Forms创建Windows 10样式的ContextMenuStrip的方法。我知道,可以更改其Renderer以使其看起来像Windows Vista、7和8。这就是我所做的:

enter image description here

但我也希望在Windows 10中使它看起来像这样:

enter image description here

有没有使用Windows Forms的方法,或者应该使用一些特殊的方式,例如使用Metro类等等?


2
如果您想完全相同,那么您需要使用本地菜单组件包装器。右键单击工具箱>选择项目>.NET Framework组件选项卡>勾选“ContextMenu”。 - Hans Passant
谢谢您的评论!我想要使用ContextMenuStrip,因为它有一些功能,我想在我的应用程序中实现。我相信,仍然可以更改ContextMenuStrip的Renderer,以改变其视觉风格。 - Sergey Dudkin
我正在寻找相同的东西,但是使用本机Win32 HMENU而不是WinForms ContextMenu(为了轻量级的C++应用程序坐落在系统托盘中)。有人有线索吗? - Charles Milette
2个回答

14
你可以实现自定义Renderer,并覆盖OnRenderArrowOnRenderItemCheck,并将你的自定义ColorTable传递给它。然后将其设置为你的ContextMenuRenderer

enter image description here

ColorTable的代码:

public class MyColorTable : ProfessionalColorTable
{
    public override Color MenuItemBorder
    {
        get { return Color.WhiteSmoke; }
    }
    public override Color MenuItemSelected
    {
        get { return Color.WhiteSmoke; }
    }
    public override Color ToolStripDropDownBackground
    {
        get { return Color.White; }
    }
    public override Color ImageMarginGradientBegin
    {
        get { return Color.White; }
    }
    public override Color ImageMarginGradientMiddle
    {
        get { return Color.White; }
    }
    public override Color ImageMarginGradientEnd
    {
        get { return Color.White; }
    }
}

渲染器的代码:

public class MyRenderer : ToolStripProfessionalRenderer
{
    public MyRenderer()
        : base(new MyColorTable())
    {
    }
    protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        var r = new Rectangle(e.ArrowRectangle.Location, e.ArrowRectangle.Size);
        r.Inflate(-2, -6);
        e.Graphics.DrawLines(Pens.Black, new Point[]{
        new Point(r.Left, r.Top),
        new Point(r.Right, r.Top + r.Height /2), 
        new Point(r.Left, r.Top+ r.Height)});
    }

    protected override void OnRenderItemCheck(ToolStripItemImageRenderEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        var r = new Rectangle(e.ImageRectangle.Location, e.ImageRectangle.Size);
        r.Inflate(-4, -6);
        e.Graphics.DrawLines(Pens.Black, new Point[]{
        new Point(r.Left, r.Bottom - r.Height /2),
        new Point(r.Left + r.Width /3,  r.Bottom), 
        new Point(r.Right, r.Top)});
    }
}

表单加载的代码:

private void Form_Load(object sender, EventArgs e)
{
    this.contextMenuStrip1.Renderer = new MyRenderer();
}

1
谢谢您的评论!对我来说完美无缺! - Sergey Dudkin

1

除了已经接受的答案,这里还有两个现成的上下文菜单渲染器。

VS 2019 Light:

VS 2019 Light context menu strip renderer

#Region "References"
Imports System.Drawing.Drawing2D
#End Region

Namespace MenuStripRenderer

    Public Class VS2019LightBlueRenderer

        Inherits ToolStripProfessionalRenderer

#Region "Colors"

        ReadOnly _colorMenuArrow As Color = Color.FromArgb(0, 122, 204)
        ReadOnly _colorCheckSquare As Color = Color.FromArgb(0, 122, 204)
        ReadOnly _colorCheckMark As Color = Color.FromArgb(19, 69, 99)
        ReadOnly _colorMenuItemText As Color = Color.FromArgb(33, 33, 33)

#End Region

#Region "Constructor"

        Public Sub New()
            MyBase.New(New MenuStripColorTable())
        End Sub

#End Region

#Region "Overridden Methods"

        Protected Overrides Sub OnRenderArrow(e As ToolStripArrowRenderEventArgs)

            'Draw arrow color
            If e IsNot Nothing Then e.ArrowColor = _colorMenuArrow
            MyBase.OnRenderArrow(e)

        End Sub

        Protected Overrides Sub OnRenderItemText(e As ToolStripItemTextRenderEventArgs)

            If e IsNot Nothing Then

                Dim textRect = e.TextRectangle
                textRect.Height = e.Item.Height - 4 '4 is the default difference between the item height and the text rectangle height

                e.TextRectangle = textRect
                e.TextFormat = TextFormatFlags.VerticalCenter
                e.TextColor = _colorMenuItemText

            End If

            MyBase.OnRenderItemText(e)

        End Sub

        Protected Overrides Sub OnRenderMenuItemBackground(e As ToolStripItemRenderEventArgs)

            If e Is Nothing OrElse Not e.Item.Enabled Then Return
            MyBase.OnRenderMenuItemBackground(e)

        End Sub

        Protected Overrides Sub OnRenderItemCheck(e As ToolStripItemImageRenderEventArgs)

            If e IsNot Nothing Then

                Dim g = e.Graphics
                g.SmoothingMode = SmoothingMode.AntiAlias

                Dim rectImage = New Rectangle(e.ImageRectangle.Location, e.ImageRectangle.Size)
                rectImage.Inflate(-1, -1)

                Using p = New Pen(_colorCheckSquare, 1)
                    g.DrawRectangle(p, rectImage)
                End Using

                Dim rectCheck = rectImage
                rectCheck.Width = rectImage.Width - 6
                rectCheck.Height = rectImage.Height - 8
                rectCheck.X += 3
                rectCheck.Y += 4

                Using p = New Pen(_colorCheckMark, 2)
                    g.DrawLines(p, {New Point(rectCheck.Left, rectCheck.Bottom - CInt(rectCheck.Height / 2)), New Point(rectCheck.Left + CInt(rectCheck.Width / 3), rectCheck.Bottom), New Point(rectCheck.Right, rectCheck.Top)})
                End Using

            End If

        End Sub

#End Region

#Region "Classes"

        Private Class MenuStripColorTable

            Inherits ProfessionalColorTable

#Region "Colors"

            ReadOnly _colorMenuBorder As Color = Color.FromArgb(204, 206, 219)
            ReadOnly _colorMenuItemSelected As Color = Color.FromArgb(201, 222, 245)
            ReadOnly _colorBackground As Color = Color.FromArgb(246, 246, 246)
            ReadOnly _colorSeparator As Color = Color.FromArgb(224, 227, 230)
            ReadOnly _colorStatusStripGradient As Color = Color.FromArgb(234, 237, 241)
            ReadOnly _colorButtonSelected As Color = Color.FromArgb(88, 146, 226)
            ReadOnly _colorButtonPressed As Color = Color.FromArgb(110, 160, 230)

#End Region

#Region "Properties"

            Public Overrides ReadOnly Property ToolStripDropDownBackground As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property MenuStripGradientBegin As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property MenuStripGradientEnd As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property CheckBackground As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property CheckPressedBackground As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property CheckSelectedBackground As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property MenuItemSelected As Color
                Get
                    Return _colorMenuItemSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ImageMarginGradientBegin As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property ImageMarginGradientMiddle As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property ImageMarginGradientEnd As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property MenuItemBorder As Color
                Get
                    Return _colorMenuItemSelected
                End Get
            End Property

            Public Overrides ReadOnly Property MenuBorder As Color
                Get
                    Return _colorMenuBorder
                End Get
            End Property

            Public Overrides ReadOnly Property SeparatorDark As Color
                Get
                    Return _colorSeparator
                End Get
            End Property

            Public Overrides ReadOnly Property SeparatorLight As Color
                Get
                    Return _colorSeparator
                End Get
            End Property

            Public Overrides ReadOnly Property StatusStripGradientBegin As Color
                Get
                    Return _colorStatusStripGradient
                End Get
            End Property

            Public Overrides ReadOnly Property StatusStripGradientEnd As Color
                Get
                    Return _colorStatusStripGradient
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonSelectedGradientBegin As Color
                Get
                    Return _colorButtonSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonSelectedGradientMiddle As Color
                Get
                    Return _colorButtonSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonSelectedGradientEnd As Color
                Get
                    Return _colorButtonSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonSelectedBorder As Color
                Get
                    Return _colorButtonSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonPressedGradientBegin As Color
                Get
                    Return _colorButtonPressed
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonPressedGradientMiddle As Color
                Get
                    Return _colorButtonPressed
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonPressedGradientEnd As Color
                Get
                    Return _colorButtonPressed
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonPressedBorder As Color
                Get
                    Return _colorButtonPressed
                End Get
            End Property

#End Region

        End Class

#End Region

    End Class

End Namespace

VS 2019 暗色主题:

VS 2019 暗色主题上下文菜单条渲染器

#Region "References"
Imports System.Drawing.Drawing2D
#End Region

Namespace MenuStripRenderer

    Public Class VS2019DarkBlueRenderer

        Inherits ToolStripProfessionalRenderer

#Region "Colors"

        ReadOnly _colorMenuArrow As Color = Color.FromArgb(237, 237, 237)
        ReadOnly _colorCheckSquare As Color = Color.FromArgb(0, 122, 204)
        ReadOnly _colorCheckMark As Color = Color.FromArgb(237, 237, 237)
        ReadOnly _colorMenuItemText As Color = Color.FromArgb(237, 237, 237)

#End Region

#Region "Constructor"

        Public Sub New()
            MyBase.New(New MenuStripColorTable())
        End Sub

#End Region

#Region "Overridden Methods"

        Protected Overrides Sub OnRenderArrow(e As ToolStripArrowRenderEventArgs)

            If e IsNot Nothing Then e.ArrowColor = _colorMenuArrow
            MyBase.OnRenderArrow(e)

        End Sub

        Protected Overrides Sub OnRenderItemCheck(e As ToolStripItemImageRenderEventArgs)

            If e IsNot Nothing Then

                Dim g = e.Graphics
                g.SmoothingMode = SmoothingMode.AntiAlias

                Dim rectImage = New Rectangle(e.ImageRectangle.Location, e.ImageRectangle.Size)
                rectImage.Inflate(-1, -1)

                Using p = New Pen(_colorCheckSquare, 1)
                    g.DrawRectangle(p, rectImage)
                End Using

                Dim rectCheck = rectImage
                rectCheck.Width = rectImage.Width - 6
                rectCheck.Height = rectImage.Height - 8
                rectCheck.X += 3
                rectCheck.Y += 4

                Using p = New Pen(_colorCheckMark, 2)
                    g.DrawLines(p, {New Point(rectCheck.Left, rectCheck.Bottom - CInt(rectCheck.Height / 2)), New Point(rectCheck.Left + CInt(rectCheck.Width / 3), rectCheck.Bottom), New Point(rectCheck.Right, rectCheck.Top)})
                End Using

            End If

        End Sub

        Protected Overrides Sub OnRenderItemText(e As ToolStripItemTextRenderEventArgs)

            If e IsNot Nothing Then

                Dim textRect = e.TextRectangle
                textRect.Height = e.Item.Height - 4 '4 is the default difference between the item height and the text rectangle height

                e.TextRectangle = textRect
                e.TextFormat = TextFormatFlags.VerticalCenter
                e.TextColor = _colorMenuItemText

            End If

            MyBase.OnRenderItemText(e)

        End Sub

        Protected Overrides Sub OnRenderMenuItemBackground(e As ToolStripItemRenderEventArgs)

            If e Is Nothing OrElse Not e.Item.Enabled Then Return
            MyBase.OnRenderMenuItemBackground(e)

        End Sub

#End Region

#Region "Classes"

        Private Class MenuStripColorTable

            Inherits ProfessionalColorTable

#Region "Colors"

            ReadOnly _colorMenuBorder As Color = Color.FromArgb(61, 61, 67)
            ReadOnly _colorMenuItemSelected As Color = Color.FromArgb(76, 76, 77)
            ReadOnly _colorBackground As Color = Color.FromArgb(43, 43, 43)
            ReadOnly _colorSeparator As Color = Color.FromArgb(61, 61, 67)
            ReadOnly _colorStatusStripGradient As Color = Color.FromArgb(234, 237, 241)
            ReadOnly _colorButtonSelected As Color = Color.FromArgb(88, 146, 226)
            ReadOnly _colorButtonPressed As Color = Color.FromArgb(110, 160, 230)

#End Region

#Region "Properties"

            Public Overrides ReadOnly Property ToolStripDropDownBackground As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property MenuStripGradientBegin As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property MenuStripGradientEnd As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property CheckBackground As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property CheckPressedBackground As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property CheckSelectedBackground As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property MenuItemSelected As Color
                Get
                    Return _colorMenuItemSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ImageMarginGradientBegin As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property ImageMarginGradientMiddle As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property ImageMarginGradientEnd As Color
                Get
                    Return _colorBackground
                End Get
            End Property

            Public Overrides ReadOnly Property MenuItemBorder As Color
                Get
                    Return _colorMenuItemSelected
                End Get
            End Property

            Public Overrides ReadOnly Property MenuBorder As Color
                Get
                    Return _colorMenuBorder
                End Get
            End Property

            Public Overrides ReadOnly Property SeparatorDark As Color
                Get
                    Return _colorSeparator
                End Get
            End Property

            Public Overrides ReadOnly Property SeparatorLight As Color
                Get
                    Return _colorSeparator
                End Get
            End Property

            Public Overrides ReadOnly Property StatusStripGradientBegin As Color
                Get
                    Return _colorStatusStripGradient
                End Get
            End Property

            Public Overrides ReadOnly Property StatusStripGradientEnd As Color
                Get
                    Return _colorStatusStripGradient
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonSelectedGradientBegin As Color
                Get
                    Return _colorButtonSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonSelectedGradientMiddle As Color
                Get
                    Return _colorButtonSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonSelectedGradientEnd As Color
                Get
                    Return _colorButtonSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonSelectedBorder As Color
                Get
                    Return _colorButtonSelected
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonPressedGradientBegin As Color
                Get
                    Return _colorButtonPressed
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonPressedGradientMiddle As Color
                Get
                    Return _colorButtonPressed
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonPressedGradientEnd As Color
                Get
                    Return _colorButtonPressed
                End Get
            End Property

            Public Overrides ReadOnly Property ButtonPressedBorder As Color
                Get
                    Return _colorButtonPressed
                End Get
            End Property

#End Region

        End Class

#End Region

    End Class

End Namespace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接