在 ContextMenuStrip 中更改图像和文本之间的空间

Som*_*nna 2 vb.net graphics contextmenu contextmenustrip winforms

在我的应用程序中,我有一个包含两个项目的 ContextMenuStrip。每个项目都有一个图像和一个文本。如下图所示,菜单项的图像部分与其文本之间存在默认间隙(该间隙由红色箭头指示)。

在此处输入图片说明

我想通过向左移动文本来减少水平间隙,以便将间隙减少到最大 1 像素。

是否可以?如果是,我该怎么办?

Jim*_*imi 6

展示如何处理通用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 中设置为)类(此处称为MenuRendererColorsShared存储自定义颜色定义,然后将其分配给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处理程序添加更多属性或方法,以在运行时更改自定义颜色或创建自定义行为。


这是它的工作原理:

自定义 ToolStripProfessionalRenderer - ProfessionalColorTable


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)