Renderer
,并覆盖OnRenderArrow
和OnRenderItemCheck
,并将你的自定义ColorTable
传递给它。然后将其设置为你的ContextMenu
的Renderer
。
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();
}
除了已经接受的答案,这里还有两个现成的上下文菜单渲染器。
VS 2019 Light:
#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 暗色主题:
#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