Som*_*nna 2 vb.net graphics contextmenu contextmenustrip winforms
在我的应用程序中,我有一个包含两个项目的 ContextMenuStrip。每个项目都有一个图像和一个文本。如下图所示,菜单项的图像部分与其文本之间存在默认间隙(该间隙由红色箭头指示)。
我想通过向左移动文本来减少水平间隙,以便将间隙减少到最大 1 像素。
是否可以?如果是,我该怎么办?
展示如何处理通用ToolStripProfessionalRenderer和连接的ProfessionalColorTable的示例设置,用于个性化 ToolStrips(MenuStrip、ContextMenuStrip 等)的呈现和呈现。
它被组织在具有不同职责的不同对象中:
? 一个 Handler 类(这里称为MenuDesigner),负责初始化其他对象(Renderer、ColorTable 和 Color 定义)。
它还公开允许自定义呈现和 MenuItem 方面的公共属性和方法。
它是唯一应该允许消费者与之交互的对象。
? 派生自ToolStripProfessionalRenderer(此处命名为MenuDesignerRenderer)的类对象,负责菜单项的呈现,覆盖(部分或完全)默认行为。在此示例中(与问题相关),它覆盖OnRenderItemText- 根据自TextOffset定义属性的值和与 ToolStrip 填充相关的自定义MenuItems 文本的位置- 和OnRenderSeparator绘制Separator项目(如果有)以调整到项目文本的新位置。
使用MenuDesigner处理程序的TextOffset属性设置文本偏移量。
? 派生的类对象ProfessionalColorTable(此处命名为MenuColorTable),用于覆盖定义 ToolStrip/MenuStrip 标准颜色的颜色表的部分或全部默认属性,以分配自定义颜色。
? 具有静态 ( ) 属性的密封(NotInheritable在 VB.Net 中设置为)类(此处称为MenuRendererColors)Shared存储自定义颜色定义,然后将其分配给ProfessionalColorTable.
其中一些颜色可以使用MenuDesigner处理程序重新定义。
在示例代码中,TextColor(项目文本的SelectionColor颜色)和(选择时项目的颜色)
? 在MenuDesigner初始化指定,在其构造,ToolStrip的定制-一个的ContextMenuStrip在这种情况下。MenuDesigner处理程序的初始化也会初始化 Renderer 和 ColorTable。
? 当然,可以使用任何其他 ProfessonalColorTable 派生类来代替此处介绍的类。
? 这同样适用于定义自定义颜色的类。
? MyContextMenuStrip在 Form Designer 中构建一个 ContextMenuStrip(此处命名为),添加一个引用 的私有字段MenuDesigner并在 Form 构造函数中对其进行初始化,传递 ContextMenuStrip 以进行自定义:
Public Class SomeForm
Private toolStripDesigner As MenuDesigner = Nothing
Public Sub New()
InitializeComponent()
toolStripDesigner = New MenuDesigner(MyContextMenuStrip)
End Sub
' [...]
End Class
Run Code Online (Sandbox Code Playgroud)
要更改 MenuItems 文本上的位置,请为该MenuDesigner.TextOffset属性设置一个新值:
' Move the MenuItems Text 8 pixels to the left
toolStripDesigner.TextOffset = -8
Run Code Online (Sandbox Code Playgroud)
该TextOffset属性将偏移量限制在范围内(-8, 30):8 像素是 Text 的默认填充,它在ToolStripDropDownMenu 类中硬编码,与 DropDownMenus 的其他部分一样。
必要时会缩放这些值。
要更改所选项目的文本颜色和背景颜色,请设置MenuDesigner该类公开的相应属性:
' Changes the Color of Text of the MenuItems
toolStripDesigner.TextColor = Color.LightGreen
' Changes the Background Color of a selected MenuItems
toolStripDesigner.SelectionColor = Color.MidnightBlue
Run Code Online (Sandbox Code Playgroud)
可以向MenuDesigner处理程序添加更多属性或方法,以在运行时更改自定义颜色或创建自定义行为。
这是它的工作原理:
MenuDesigner 类:
这是处理程序类,用于初始化 aToolStripProfessionalRenderer和相关的ProfessionalColorTable.
此对象可以公开消费者可以设置/调用的公共属性和方法,以修改 ColorTable 的设置和渲染器的行为。
它应该是唯一负责并允许与其他对象交互的对象(它充当代理 -> 在这里所有类都是public- 更容易测试 - 但都应该是internal( Friend) 或private,具体取决于用例)。
Imports System.Drawing
Imports System.Windows.Forms
Public Class MenuDesigner
Private m_TextOffset As Integer = 0
Public Sub New(toolStrip As ToolStrip)
Renderer = New MenuDesignerRenderer()
If toolStrip IsNot Nothing Then
Initialize(toolStrip)
End If
End Sub
Public Sub Initialize(toolStrip As ToolStrip)
toolStrip.Renderer = Renderer
End Sub
Public ReadOnly Property Renderer As MenuDesignerRenderer
Public Property TextColor As Color
Get
Return MenuRendererColors.Text
End Get
Set
MenuRendererColors.Text = Value
End Set
End Property
Public Property SelectionColor As Color
Get
Return MenuRendererColors.Selection
End Get
Set
MenuRendererColors.Selection = Value
End Set
End Property
Public Property TextOffset As Integer
Get
Return m_TextOffset
End Get
Set
If Value <> m_TextOffset Then
m_TextOffset = Math.Min(Math.Max(-8, Value), 30)
Renderer.TextOffset = m_TextOffset
End If
End Set
End Property
End Class
Run Code Online (Sandbox Code Playgroud)
渲染器类 ( ToolStripProfessionalRenderer):
这些值和位置e.ToolStrip.Padding.Left - 2, 3, e.Item.Width, 3不是幻数,它们是由这些类的设计者设置的硬编码值(如在之前链接的 .Net 源代码中所见):2像素是添加到默认填充的值,3是分隔线在其6高度的像素框内的偏移量。
Imports System.Drawing
Imports System.Windows.Forms
Public Class MenuDesignerRenderer
Inherits ToolStripProfessionalRenderer
Private m_colorTable As ProfessionalColorTable = Nothing
Public Sub New()
Me.New(New MenuColorTable())
End Sub
Public Sub New(colorTable As ProfessionalColorTable)
MyBase.New(colorTable)
m_colorTable = colorTable
End Sub
Friend Property TextOffset As Integer = 0
Protected Overrides Sub OnRenderItemBackground(e As ToolStripItemRenderEventArgs)
MyBase.OnRenderItemBackground(e)
' Customize when needed
End Sub
Protected Overrides Sub OnRenderSeparator(e As ToolStripSeparatorRenderEventArgs)
MyBase.OnRenderSeparator(e)
Using penForeground As New Pen(m_colorTable.SeparatorDark, 1),
penBackground As New Pen(e.Item.BackColor, 1)
e.Graphics.DrawLine(penBackground, e.ToolStrip.Padding.Left - 2, 3, e.Item.Width, 3)
e.Graphics.DrawLine(penForeground, e.ToolStrip.Padding.Left + TextOffset, 3, e.Item.Width, 3)
End Using
End Sub
Protected Overrides Sub OnRenderItemText(e As ToolStripItemTextRenderEventArgs)
e.Item.ForeColor = MenuRendererColors.Text
Dim textRect = e.TextRectangle
textRect.Offset(TextOffset, 0)
e.TextRectangle = textRect
MyBase.OnRenderItemText(e)
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
颜色表类 (ProfessionalColorTable):
该类覆盖将颜色分配给 MenuItems 部件的属性,以设置我们MenuRendererColors类中定义的自定义颜色。
Imports System.Drawing
Imports System.Windows.Forms
Public Class MenuColorTable
Inherits ProfessionalColorTable
Public Overrides ReadOnly Property ToolStripBorder As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property ToolStripGradientBegin As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property ToolStripGradientEnd As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property ToolStripDropDownBackground As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property MenuBorder As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property MenuItemBorder As Color = MenuRendererColors.ImageBand
Public Overrides ReadOnly Property MenuStripGradientBegin As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property MenuStripGradientEnd As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property CheckBackground As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property CheckPressedBackground As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property CheckSelectedBackground As Color = MenuRendererColors.Background
Public Overrides ReadOnly Property MenuItemSelected As Color = MenuRendererColors.Selection
Public Overrides ReadOnly Property MenuItemSelectedGradientBegin As Color = MenuRendererColors.Selection
Public Overrides ReadOnly Property MenuItemSelectedGradientEnd As Color = MenuRendererColors.Selection
Public Overrides ReadOnly Property MenuItemPressedGradientBegin As Color = MenuRendererColors.Selection
Public Overrides ReadOnly Property MenuItemPressedGradientEnd As Color = MenuRendererColors.Selection
Public Overrides ReadOnly Property SeparatorDark As Color = MenuRendererColors.SeparatorDark
Public Overrides ReadOnly Property SeparatorLight As Color = MenuRendererColors.SeparatorLight
Public Overrides ReadOnly Property ImageMarginGradientBegin As Color = MenuRendererColors.ImageBand
Public Overrides ReadOnly Property ImageMarginGradientMiddle As Color = MenuRendererColors.ImageBand
Public Overrides ReadOnly Property ImageMarginGradientEnd As Color = MenuRendererColors.ImageBand
Public Overrides ReadOnly Property ImageMarginRevealedGradientBegin As Color = MenuRendererColors.ImageBand
Public Overrides ReadOnly Property ImageMarginRevealedGradientMiddle As Color = MenuRendererColors.ImageBand
Public Overrides ReadOnly Property ImageMarginRevealedGradientEnd As Color = MenuRendererColors.ImageBand
End Class
Run Code Online (Sandbox Code Playgroud)
颜色定义类:
存储用于自定义 MenusItems 方面的颜色。如果需要,可以使用管理器类在运行时更改这些MenuDesigner。
Imports System.Drawing
Public NotInheritable Class MenuRendererColors
Public Shared Property Text As Color = Color.White
Public Shared Property Background As Color = Color.FromArgb(32, 32, 32)
Public Shared Property Selection As Color = Color.FromArgb(200, Color.DodgerBlue)
Public Shared Property ImageBand As Color = Color.FromArgb(200, 200, 200)
Public Shared Property CheckBoxBand As Color = Color.FromArgb(200, 200, 200)
Public Shared Property SeparatorDark As Color = Color.DodgerBlue
Public Shared Property SeparatorLight As Color = Color.LawnGreen
End Class
Run Code Online (Sandbox Code Playgroud)