在ContextMenuStrip中更改图像和文本之间的空间 [英] Change space between Image and Text in ContextMenuStrip

查看:54
本文介绍了在ContextMenuStrip中更改图像和文本之间的空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

解决方案

一个示例设置,显示了如何处理通用


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

它应该是唯一负责并允许与其他对象交互的对象(它充当代理->在这里,所有类都是 public -测试起来更容易-但所有类都应该是内部( Friend )还是 private (取决于使用情况).

 导入System.Drawing导入System.Windows.Forms公共类MenuDesigner私有m_TextOffset为整数= 0公用子新增(toolStrip作为ToolStrip)渲染器=新的MenuDesignerRenderer()如果toolStrip没什么,那就初始化(toolStrip)万一结束子公共子初始化(toolStrip作为ToolStrip)toolStrip.Renderer =渲染器结束子将公共只读属性渲染器作为MenuDesignerRenderer公共属性TextColor作为颜色得到返回MenuRendererColors.Text结束获取放MenuRendererColors.Text =值端套最终财产公共属性选择颜色作为颜色得到返回MenuRendererColors.Selection结束获取放MenuRendererColors.Selection =值端套最终财产公共属性TextOffset为整数得到返回m_TextOffset结束获取放如果值<>然后m_TextOffsetm_TextOffset = Math.Min(Math.Max(-8,Value),30)Renderer.TextOffset = m_TextOffset万一端套最终财产末级 

渲染器类( ToolStripProfessionalRenderer ):

这些值和位置 e.ToolStrip.Padding.Left-2、3,e.Item.Width,3 不是魔术数字,这些是这些类的设计者设置的硬编码值(如在之前链接的.Net源代码中所示): 2 像素是添加到默认填充中的值, 3 是分隔线在其高度为 6 个像素的框内的偏移量.

 导入System.Drawing导入System.Windows.Forms公共类MenuDesignerRenderer继承ToolStripProfessionalRenderer私有m_colorTable为ProfessionalColorTable = Nothing公开子New()我新(新MenuColorTable())结束子Public Sub New(colorTable为ProfessionalColorTable)MyBase.New(colorTable)m_colorTable = colorTable结束子朋友属性TextOffset为整数= 0受保护的重写Sub OnRenderItemBackground(例如,作为ToolStripItemRenderEventArgs)MyBase.OnRenderItemBackground(e)'根据需要定制结束子受保护的重写Sub OnRenderSeparator(例如,作为ToolStripSeparatorRenderEventArgs)MyBase.OnRenderSeparator(e)使用penForeground作为新笔(m_colorTable.SeparatorDark,1),penBackground作为新的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)最终使用结束子受保护的重写Sub OnRenderItemText(例如,作为ToolStripItemTextRenderEventArgs)e.Item.ForeColor = MenuRendererColors.Text昏暗的textRect = e.TextRectangletextRect.Offset(TextOffset,0)e.TextRectangle = textRectMyBase.OnRenderItemText(e)结束子末级 

颜色表类(ProfessionalColorTable):
此类覆盖将Colors分配给MenuItems部件的属性,以设置在我们的 MenuRendererColors 类中定义的自定义颜色.

 导入System.Drawing导入System.Windows.Forms公共类MenuColorTable继承ProfessionalColorTable公共将ReadOnly属性ToolStripBorder重写为Color = MenuRendererColors.Background公共重写ReadOnly属性ToolStripGradientBegin作为Color = MenuRendererColors.Background公共重写ReadOnly属性ToolStripGradientEnd,因为Color = MenuRendererColors.Background公共重写ReadOnly属性ToolStripDropDownBackground,因为Color = MenuRendererColors.Background公共重写ReadOnly属性MenuBorder作为Color = MenuRendererColors.Background公共重写ReadOnly属性MenuItemBorder,因为Color = MenuRendererColors.ImageBand公共重写ReadOnly属性MenuStripGradientBegin作为Color = MenuRendererColors.Background公共重写ReadOnly属性MenuStripGradientEnd,因为Color = MenuRendererColors.Background公共将ReadOnly属性CheckBackground替换为Color = MenuRendererColors.Background公共重写ReadOnly属性CheckPressedBackground,因为Color = MenuRendererColors.Background公共重写ReadOnly属性CheckSelectedBackground,因为Color = MenuRendererColors.Background公共重写ReadOnly属性MenuItemSelected为Color = MenuRendererColors.Selection公共重写ReadOnly属性MenuItemSelectedGradientBegin作为Color = MenuRendererColors.Selection公共重写ReadOnly属性MenuItemSelectedGradientEnd为Color = MenuRendererColors.Selection公共重写ReadOnly属性MenuItemPressedGradientBegin作为Color = MenuRendererColors.Selection公共重写ReadOnly属性MenuItemPressedGradientEnd,因为Color = MenuRendererColors.Selection公共重写ReadOnly属性SeparatorDark为Color = MenuRendererColors.SeparatorDark公共重写ReadOnly属性SeparatorLight,因为Color = MenuRendererColors.SeparatorLight公共重写ReadOnly属性ImageMarginGradientBegin作为Color = MenuRendererColors.ImageBand公共重写ReadOnly属性ImageMarginGradientMiddle作为Color = MenuRendererColors.ImageBand公共将ReadOnly属性ImageMarginGradientEnd替换为Color = MenuRendererColors.ImageBand公共重写ReadOnly属性ImageMarginRevealedGradientBegin,因为Color = MenuRendererColors.ImageBand公共重写ReadOnly属性ImageMarginRevealedGradientMiddle作为Color = MenuRendererColors.ImageBand公共重写ReadOnly属性ImageMarginRevealedGradientEnd,因为Color = MenuRendererColors.ImageBand末级 

►颜色定义类:

存储用于自定义MenusItems外观的颜色.可以根据需要使用 manager MenuDesigner 在运行时更改这些设置.

 导入System.Drawing公共NotInheritable类MenuRendererColors公共共享属性文本为Color = Color.White公共共享属性背景为Color = Color.FromArgb(32,32,32)将公共共享属性选择为Color = Color.FromArgb(200,Color.DodgerBlue)公共共享属性ImageBand作为Color = Color.FromArgb(200,200,200)公共共享属性CheckBoxBand为Color = Color.FromArgb(200,200,200)公共共享属性SeparatorDark As Color = Color.DodgerBlue公共共享属性SeparatorLight as Color = Color.LawnGreen末级 

In my application, I have a ContextMenuStrip with two items. Each item has an image and a text. There's a default gap between the Image section of the Menu Items and their text, as shown in the image below (the gap is indicated by red arrows).

I want to reduce the horizontal gap by moving the text towards the left, so that the gap is reduced to a maximum of 1 pixel.

Is it possible? If yes how can I?

解决方案

A sample setup that shows how to handle a generic ToolStripProfessionalRenderer and a connected ProfessionalColorTable, used to personalize the rendering and presentation of ToolStrips (MenuStrip, ContextMenuStrip etc.).

It's organized in different objects with different responsibilities:

► A Handler class (here, named MenuDesigner) which is responsible for the initialization of the other objects (Renderer, ColorTable and Color definitions).
It also exposes public properties and methods that allow to customize the rendering and the aspect of the MenuItems.
It's the only object that consumers should be allowed to interact with.

► A class object derived from ToolStripProfessionalRenderer (here, named MenuDesignerRenderer), responsible for the rendering of the Menu Items, overriding (partially or completely) the default behavior. In this example (in relation to the question), it overrides 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, which draws the Separator Items, if any, to adjust to the new position of the Items Text.
The Text offset is set using the MenuDesigner handler's TextOffset Property.

► A class object derived ProfessionalColorTable (here, named MenuColorTable), which is used to override some or all the default Properties of the Color Table which define the standard Colors of a ToolStrip/MenuStrip, to assign custom colors.

► A sealed (set to NotInheritable in VB.Net) class (here, named MenuRendererColors) with static (Shared) properties, stores the custom Color definitions, which are then assigned to the different objects and parts described by the ProfessionalColorTable.
Some of these Colors can be redefined using the MenuDesigner handler.
In the sample code, TextColor (Color of the Items Text) and SelectionColor (Color of the Items when selected)


● The MenuDesigner is initialized specifying, in its Constructor, the ToolStrip to customize - a ContextMenuStrip in this case. The initialization of the MenuDesigner handler also initializes the Renderer and the ColorTable.
→ Of course, any other ProfessonalColorTable derived class can be used instead of the one presented here.
→ The same applies to the class that defines the custom Colors.

● Build a ContextMenuStrip (here named MyContextMenuStrip) in the Form Designer, add a private field that references the MenuDesigner and initialize it in the Form constructor, passing the ContextMenuStrip to customize:

Public Class SomeForm
    Private toolStripDesigner As MenuDesigner = Nothing

    Public Sub New()
        InitializeComponent()
        toolStripDesigner = New MenuDesigner(MyContextMenuStrip)
    End Sub

   ' [...]
End Class

To change the position on the MenuItems Text, set a new value to the MenuDesigner.TextOffset Property:

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

The TextOffset property limits the offset to the range (-8, 30): 8 pixels is the default padding of the Text, it's hard-coded in the ToolStripDropDownMenu class, as other parts of the DropDownMenus.
These values are scaled when necessary.

To change the Color of Text and the Background Color of a selected Item, set the corresponding properties exposed by the 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

More properties or methods can be added to the MenuDesigner handler to change custom Colors or create custom behaviors at run-time.


This is how it works:


MenuDesigner class:
this is the handler class, used to initialize a ToolStripProfessionalRenderer and the related ProfessionalColorTable.
This object can expose public property and methods that a consumer can set/call to modify settings of the ColorTable and the behavior of the Renderer.

It should be the only object responsible and allowed to interact with the other (it acts as a proxy -> here all classes are public - it's easier to test - but all should be internal (Friend) or private, depending on the use case).

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

Renderer class (ToolStripProfessionalRenderer):

These values and positions, e.ToolStrip.Padding.Left - 2, 3, e.Item.Width, 3, are not magic numbers, these are hard-coded values (as it can be seen in the .Net source code linked before) set by the designers of these classes: 2 pixels is a value added to the default padding, 3 is the offset of the Separator line inside its box of 6 pixels in height.

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

Color Table class (ProfessionalColorTable):
This class overrides the properties that assign Colors to MenuItems parts to set the custom color defined in our 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

► Colors definition class:

Stores the Colors use to customize the aspect of MenusItems. These can be changed at run-time, if needed, using the 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中更改图像和文本之间的空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆