在 ContextMenuStrip 中更改图像和文本之间的 space
Change space between Image and Text in ContextMenuStrip
在我的应用程序中,我有一个包含两个项目的 ContextMenuStrip。
每个项目都有一个图像和一个文本。菜单项的图像部分与其文本之间存在默认间隙,如下图所示(间隙由红色箭头指示)。
我想通过向左移动文本来减少水平间隙,使间隙减少到最大 1 个像素。
可能吗?如果可以我怎么办?
展示如何处理通用 ToolStripProfessionalRenderer and a connected ProfessionalColorTable 的示例设置,用于个性化 ToolStrip(MenuStrip、ContextMenuStrip 等)的呈现和呈现。
它被组织在具有不同职责的不同对象中:
▶ 一个 Handler class(此处命名为 MenuDesigner
)负责初始化其他对象(Renderer、ColorTable 和颜色定义)。
它还公开了 public 允许自定义呈现和 MenuItems 外观的属性和方法。
这是唯一允许消费者与之交互的对象。
▶ 派生自ToolStripProfessionalRenderer
的class对象(此处命名为MenuDesignerRenderer
),负责菜单项的渲染,覆盖(部分或完全)默认行为。在此示例中(与问题相关),它覆盖 OnRenderItemText
- to customize the position of the MenuItems Text based on the value of the TextOffset
custom property and in relation to the ToolStrip padding - and OnRenderSeparator
,绘制 Separator
项目(如果有)以调整到项目文本的新位置。
使用 MenuDesigner
处理程序的 TextOffset
属性.
设置文本偏移量
▶ 一个class对象派生ProfessionalColorTable
(这里,命名为MenuColorTable
),用于覆盖颜色 Table 的部分或全部默认属性,这些属性定义 ToolStrip/MenuStrip 的标准颜色,以分配自定义颜色。
▶ 一个密封的(在VB.Net中设置为NotInheritable
)class(这里命名为MenuRendererColors
)带静态(Shared
) 属性,存储自定义颜色定义,然后将其分配给 ProfessionalColorTable
.
描述的不同对象和部分
其中一些颜色可以使用 MenuDesigner
处理程序重新定义。
在示例代码中,TextColor
(项目文本的颜色)和SelectionColor
(选择时项目的颜色)
● MenuDesigner
已初始化,在其构造函数中指定要自定义的 ToolStrip - 在本例中为 ContextMenuStrip。 MenuDesigner
handler 的初始化也初始化了 Renderer 和 ColorTable.
→ 当然,可以使用任何其他 ProfessonalColorTable 派生的 class 来代替这里介绍的
→ 这同样适用于定义自定义颜色的 class。
● 在Form Designer中建立一个ContextMenuStrip(这里命名为MyContextMenuStrip
),添加一个引用MenuDesigner
的私有字段并在表单构造函数,传递ContextMenuStrip自定义:
Public Class SomeForm
Private toolStripDesigner As MenuDesigner = Nothing
Public Sub New()
InitializeComponent()
toolStripDesigner = New MenuDesigner(MyContextMenuStrip)
End Sub
' [...]
End Class
要更改菜单项文本的位置,请将新值设置为 MenuDesigner.TextOffset
属性:
' Move the MenuItems Text 8 pixels to the left
toolStripDesigner.TextOffset = -8
TextOffset
属性将偏移量限制在(-8, 30)
范围内:8像素是Text的默认padding,在[=59=中是hard-coded ], 作为 DropDownMenus 的其他部分。
这些值会在必要时缩放。
要更改所选项目的文本颜色和背景颜色,请设置 MenuDesigner
class:
公开的相应属性
' Changes the Color of Text of the MenuItems
toolStripDesigner.TextColor = Color.LightGreen
' Changes the Background Color of a selected MenuItems
toolStripDesigner.SelectionColor = Color.MidnightBlue
可以向 MenuDesigner
处理程序添加更多属性或方法,以更改自定义颜色或在 run-time 处创建自定义行为。
这是它的工作原理:
菜单设计器class:
这是处理程序 class,用于初始化 ToolStripProfessionalRenderer
和相关的 ProfessionalColorTable
。
此对象可以公开 public 属性 和消费者可以 set/call 修改 ColorTable 设置和 Renderer 行为的方法。
它应该是唯一负责并允许与其他对象交互的对象(它充当代理 -> 这里所有 class 都是 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
渲染器class (ToolStripProfessionalRenderer
):
这些值和位置,e.ToolStrip.Padding.Left - 2, 3, e.Item.Width, 3
,不是幻数,这些是hard-coded值(正如之前链接的 .Net 源代码中所示)由这些 classes 的设计者设置: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
色彩Tableclass(专业色彩Table):
class 覆盖了将颜色分配给 MenuItems 部件的属性,以设置我们 MenuRendererColors
class.
中定义的自定义颜色
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
颜色定义class:
存储用于自定义 MenusItems 外观的颜色。如果需要,可以使用 manager class、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
在我的应用程序中,我有一个包含两个项目的 ContextMenuStrip。 每个项目都有一个图像和一个文本。菜单项的图像部分与其文本之间存在默认间隙,如下图所示(间隙由红色箭头指示)。
我想通过向左移动文本来减少水平间隙,使间隙减少到最大 1 个像素。
可能吗?如果可以我怎么办?
展示如何处理通用 ToolStripProfessionalRenderer and a connected ProfessionalColorTable 的示例设置,用于个性化 ToolStrip(MenuStrip、ContextMenuStrip 等)的呈现和呈现。
它被组织在具有不同职责的不同对象中:
▶ 一个 Handler class(此处命名为 MenuDesigner
)负责初始化其他对象(Renderer、ColorTable 和颜色定义)。
它还公开了 public 允许自定义呈现和 MenuItems 外观的属性和方法。
这是唯一允许消费者与之交互的对象。
▶ 派生自ToolStripProfessionalRenderer
的class对象(此处命名为MenuDesignerRenderer
),负责菜单项的渲染,覆盖(部分或完全)默认行为。在此示例中(与问题相关),它覆盖 OnRenderItemText
- to customize the position of the MenuItems Text based on the value of the TextOffset
custom property and in relation to the ToolStrip padding - and OnRenderSeparator
,绘制 Separator
项目(如果有)以调整到项目文本的新位置。
使用 MenuDesigner
处理程序的 TextOffset
属性.
▶ 一个class对象派生ProfessionalColorTable
(这里,命名为MenuColorTable
),用于覆盖颜色 Table 的部分或全部默认属性,这些属性定义 ToolStrip/MenuStrip 的标准颜色,以分配自定义颜色。
▶ 一个密封的(在VB.Net中设置为NotInheritable
)class(这里命名为MenuRendererColors
)带静态(Shared
) 属性,存储自定义颜色定义,然后将其分配给 ProfessionalColorTable
.
描述的不同对象和部分
其中一些颜色可以使用 MenuDesigner
处理程序重新定义。
在示例代码中,TextColor
(项目文本的颜色)和SelectionColor
(选择时项目的颜色)
● MenuDesigner
已初始化,在其构造函数中指定要自定义的 ToolStrip - 在本例中为 ContextMenuStrip。 MenuDesigner
handler 的初始化也初始化了 Renderer 和 ColorTable.
→ 当然,可以使用任何其他 ProfessonalColorTable 派生的 class 来代替这里介绍的
→ 这同样适用于定义自定义颜色的 class。
● 在Form Designer中建立一个ContextMenuStrip(这里命名为MyContextMenuStrip
),添加一个引用MenuDesigner
的私有字段并在表单构造函数,传递ContextMenuStrip自定义:
Public Class SomeForm
Private toolStripDesigner As MenuDesigner = Nothing
Public Sub New()
InitializeComponent()
toolStripDesigner = New MenuDesigner(MyContextMenuStrip)
End Sub
' [...]
End Class
要更改菜单项文本的位置,请将新值设置为 MenuDesigner.TextOffset
属性:
' Move the MenuItems Text 8 pixels to the left
toolStripDesigner.TextOffset = -8
TextOffset
属性将偏移量限制在(-8, 30)
范围内:8像素是Text的默认padding,在[=59=中是hard-coded ], 作为 DropDownMenus 的其他部分。
这些值会在必要时缩放。
要更改所选项目的文本颜色和背景颜色,请设置 MenuDesigner
class:
' Changes the Color of Text of the MenuItems
toolStripDesigner.TextColor = Color.LightGreen
' Changes the Background Color of a selected MenuItems
toolStripDesigner.SelectionColor = Color.MidnightBlue
可以向 MenuDesigner
处理程序添加更多属性或方法,以更改自定义颜色或在 run-time 处创建自定义行为。
这是它的工作原理:
菜单设计器class:
这是处理程序 class,用于初始化 ToolStripProfessionalRenderer
和相关的 ProfessionalColorTable
。
此对象可以公开 public 属性 和消费者可以 set/call 修改 ColorTable 设置和 Renderer 行为的方法。
它应该是唯一负责并允许与其他对象交互的对象(它充当代理 -> 这里所有 class 都是 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
渲染器class (ToolStripProfessionalRenderer
):
这些值和位置,e.ToolStrip.Padding.Left - 2, 3, e.Item.Width, 3
,不是幻数,这些是hard-coded值(正如之前链接的 .Net 源代码中所示)由这些 classes 的设计者设置: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
色彩Tableclass(专业色彩Table):
class 覆盖了将颜色分配给 MenuItems 部件的属性,以设置我们 MenuRendererColors
class.
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
颜色定义class:
存储用于自定义 MenusItems 外观的颜色。如果需要,可以使用 manager class、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