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

问题描述

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

enter image description here

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

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

解决方法

一个示例设置,展示了如何处理通用ToolStripProfessionalRenderer和连接的ProfessionalColorTable,用于个性化ToolStrip的呈现和呈现(MenuStrip,ContextMenuStrip等)。

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

►一个Handler类(在这里称为 MenuDesigner ),该类负责初始化其他对象(Renderer,ColorTable和Color定义)。
它还公开了允许自定义MenuItems呈现和外观的公共属性和方法。
这是应该允许消费者与之交互的唯一对象。

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

►派生出 ProfessionalColorTable (在此命名为 MenuColorTable )的类对象,该类对象用于覆盖的部分或全部默认属性。颜色表,它定义ToolStrip / MenuStrip的标准颜色,以分配自定义颜色。

►静态(在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)范围内:Text的默认填充为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处理程序中,以在运行时更改自定义颜色或创建自定义行为。


它是这样工作的:

Custom ToolStripProfessionalRenderer - ProfessionalColorTable


MenuDesigner类
这是处理程序类,用于初始化ToolStripProfessionalRenderer和相关的ProfessionalColorTable
该对象可以公开用户可以设置/调用的公共属性和方法,以修改ColorTable的设置和渲染器的行为。

它应该是唯一负责并允许与其他对象交互的对象(充当代理-这里的所有类都是public-测试起来更容易-但是所有的对象都应该是internal({{ 1}})或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 不是魔术数字,它们是硬编码的值(在.Net源代码中可以看到)这些类的设计者设置的{之前链接的代码):e.ToolStrip.Padding.Left - 2,3,e.Item.Width,3像素是添加到默认填充中的值,2是分隔线在其3像素框中的偏移量,高度。

6

颜色表类(ProfessionalColorTable)
此类覆盖将Colors分配给MenuItems部件的属性,以设置在我们的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.Graphics.DrawLine(penForeground,e.ToolStrip.Padding.Left + TextOffset,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 类中定义的自定义颜色。

MenuRendererColors

►颜色定义类:

存储用于自定义MenusItems外观的颜色。可以根据需要使用 manager 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 在运行时更改它们。

MenuDesigner

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...