【问题标题】:Change space between Image and Text in ContextMenuStrip在 ContextMenuStrip 中更改图像和文本之间的空间
【发布时间】:2021-01-15 07:42:23
【问题描述】:

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

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

有可能吗?如果可以,我该怎么做?

【问题讨论】:

    标签: vb.net winforms graphics contextmenu contextmenustrip


    【解决方案1】:

    显示如何处理通用ToolStripProfessionalRenderer 和连接ProfessionalColorTable 的示例设置,用于个性化工具条(MenuStrip、ContextMenuStrip 等)的呈现和呈现。

    它被组织在具有不同职责的不同对象中:

    ▶ 一个 Handler 类(此处名为 MenuDesigner),负责初始化其他对象(Renderer、ColorTable 和 Color 定义)。
    它还公开了允许自定义菜单项的呈现和方面的公共属性和方法。
    它是消费者应该被允许与之交互的唯一对象。

    ▶ 一个派生自ToolStripProfessionalRenderer(此处名为MenuDesignerRenderer)的类对象,负责渲染菜单项,覆盖(部分或完全)默认行为。在此示例中(与问题相关),它覆盖 OnRenderItemText - 根据 TextOffset 自定义属性的值和与 ToolStrip 填充相关的值自定义 MenuItems 文本的位置- 和 OnRenderSeparator,它会绘制 Separator 项目(如果有)以调整到项目文本的新位置。
    使用 MenuDesigner 处理程序的 TextOffset 属性设置文本偏移量。

    ▶ 一个类对象派生的ProfessionalColorTable(这里命名为MenuColorTable),用于覆盖颜色表的部分或全部默认属性定义 ToolStrip/MenuStrip 的标准颜色,以分配自定义颜色。

    ▶ 具有静态 (Shared) 属性的密封(在 VB.Net 中设置为 NotInheritable)类(此处命名为 MenuRendererColors)存储自定义颜色定义,它们是然后分配给ProfessionalColorTable描述的不同对象和部分。
    其中一些颜色可以使用MenuDesigner 处理程序重新定义。
    在示例代码中,TextColor(项目文本的颜色)和 SelectionColor(项目选择时的颜色)


    MenuDesigner 已初始化,在其构造函数中指定要自定义的 ToolStrip - 在本例中为 ContextMenuStrip。 MenuDesigner 处理程序的初始化还初始化了 Renderer 和 ColorTable。
    → 当然,可以使用任何其他 ProfessonalColorTable 派生类来代替此处介绍的类。
    → 这同样适用于定义自定义颜色的类。

    ● 在表单设计器中构建一个 ContextMenuStrip(这里命名为 MyContextMenuStrip),添加一个引用 MenuDesigner 的私有字段并在 Form 构造函数中对其进行初始化,传递 ContextMenuStrip 进行自定义:

    Public Class SomeForm
        Private toolStripDesigner As MenuDesigner = Nothing
    
        Public Sub New()
            InitializeComponent()
            toolStripDesigner = New MenuDesigner(MyContextMenuStrip)
        End Sub
    
       ' [...]
    End Class
    

    要更改 MenuItems 文本上的位置,请为 MenuDesigner.TextOffset 属性设置一个新值:

    ' Move the MenuItems Text 8 pixels to the left
    toolStripDesigner.TextOffset = -8
    

    TextOffset 属性将偏移量限制在(-8, 30) 范围内:8 像素是文本的默认填充,它与 DropDownMenus 的其他部分一样硬编码在 ToolStripDropDownMenu class 中。
    这些值会在必要时进行缩放。

    要更改所选项目的文本颜色和背景颜色,请设置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
    

    可以将更多属性或方法添加到MenuDesigner 处理程序,以在运行时更改自定义颜色或创建自定义行为。


    这就是它的工作原理:


    MenuDesigner 类
    这是处理程序类,用于初始化ToolStripProfessionalRenderer 和相关的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
    

    渲染器类 (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
    

    颜色表类(ProfessionalColorTable)
    此类覆盖将 Colors 分配给 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
    

    颜色定义类

    存储用于自定义 MenusItems 方面的颜色。如果需要,可以在运行时使用 managerMenuDesigner 更改这些。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多