简体   繁体   English

如何在vb.net或C#中向菜单条分隔符添加信息性文本

[英]How to add informative text to menu strip separator in vb.net or C#

In Window form. 以窗口形式。 I want to add informative text to the Menu separator. 我想向菜单分隔符添加内容丰富的文本。 Can anyone suggest how to do that? 谁能建议该怎么做? for example separator should appear like below 例如分隔符应如下所示

Menu Item1 
Menu Item2 
----- Separator title ----- 
Menu Item3
Menu Item4 

After Lots of attempts I am only able to add simple separator. 经过大量尝试后,我只能添加简单的分隔符。 Any help would be Great 任何帮助都会很棒

You can create your own menu separator 您可以创建自己的菜单分隔符

Public Class TextToolStripSeparator
    Inherits ToolStripMenuItem

    Public Overrides ReadOnly Property CanSelect() As Boolean
        Get
            Return DesignMode
        End Get
    End Property

    Public Overrides Property Text() As String
        Get
            Return MyBase.Text
        End Get
        Set
            value = value.Trim("-"C, " "C)
            MyBase.Text = "---- " & value & " -------"
        End Set
    End Property
End Class

It will automatically appear in the "Insert" context menu if it is defined in the same project. 如果在同一项目中定义,它将自动出现在“插入”上下文菜单中。


I also tried to override the OnPaint Method. 我也尝试重写OnPaint方法。 Without success. 没有成功。 There is some magic going on that prevents owner drawn objects to appear. 发生了一些魔术,阻止所有者绘制的对象出现。


EDIT : 编辑

Finally, after some research and a lot of trial and error I found a more satisfying solution. 最后,经过一些研究和反复试验,我找到了一个更令人满意的解决方案。 This is how the result will look 这就是结果的样子

在此处输入图片说明

First, we create our own tools strip separator class. 首先,我们创建自己的工具带分隔符类。

Public Class TextToolStripSeparator
    Inherits ToolStripMenuItem

    Public Overrides ReadOnly Property CanSelect() As Boolean
        Get
            Return DesignMode
        End Get
    End Property

    Public Overrides ReadOnly Property HasDropDownItems() As Boolean
        Get
            Return False
        End Get
    End Property
End Class

As you can see, it is very simple. 如您所见,这非常简单。 The more complicated part goes in our own MenuStrip class. 更复杂的部分放在我们自己的MenuStrip类中。 Here we provide a customized ToolStripRenderer , which, in the end, does the job. 在这里,我们提供了一个自定义的ToolStripRenderer ,最后可以完成工作。

Public Class MenuStripEx
    Inherits MenuStrip

    Public Sub New()
        Me.Renderer = New ToolStripRendererEx()
    End Sub

    Private Class ToolStripRendererEx
        Inherits ToolStripProfessionalRenderer

        Protected Overrides Sub OnRenderItemText(e As ToolStripItemTextRenderEventArgs)
            Const  flags As TextFormatFlags = TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter

            Dim item As ToolStripItem = e.Item
            If TypeOf item Is TextToolStripSeparator Then
                Dim textWidth As Integer = TextRenderer.MeasureText(item.Text, item.Font).Width
                Dim rect As Rectangle = e.TextRectangle
                rect.Width = e.ToolStrip.Width - rect.Left - 3
                TextRenderer.DrawText(e.Graphics, item.Text, item.Font, rect, Color.DimGray, flags)

                Dim y As Integer = rect.Y + rect.Height \ 2
                Dim margin As Integer = (rect.Width - textWidth) \ 2
                e.Graphics.DrawLine(Pens.DarkGray, rect.X, y, rect.X + margin, y)
                e.Graphics.DrawLine(Pens.DarkGray, rect.Right - margin, y, rect.Right, y)
            Else
                MyBase.OnRenderItemText(e)
            End If
        End Sub
    End Class
End Class

I needed to create a C# implementation of Olivier Jacot-Descombes's solution, so here it is in case anyone else needs it. 我需要创建Olivier Jacot-Descombes解决方案的C#实现,所以这里是万一其他人需要它的情况。 In my case I needed it for a ContextMenuStrip rather than a MenuStrip but it works just the same, the only difference is the name I've used. 就我而言,我需要它用于ContextMenuStrip而不是MenuStrip但它的工作原理相同,唯一的区别是我使用的名称。

public class TextToolStripSeparator : ToolStripMenuItem
{
    public override bool CanSelect { get { return DesignMode; } }

    public override bool HasDropDownItems { get { return false; } }
}

public class ContextMenuStripEx : ContextMenuStrip
{
    public ContextMenuStripEx()
    {
        this.Renderer = new ToolStripRendererEx();
    }

    private class ToolStripRendererEx : ToolStripProfessionalRenderer
    {
        protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
        {
            const TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter;

            ToolStripItem item = e.Item;

            if (item is TextToolStripSeparator)
            {
                int textWidth = TextRenderer.MeasureText(item.Text, item.Font).Width;
                Rectangle rect = e.TextRectangle;
                rect.Width = e.ToolStrip.Width - rect.Left;
                TextRenderer.DrawText(e.Graphics, item.Text, item.Font, rect, Color.DimGray, flags);

                int y = rect.Y + rect.Height / 2;
                int margin = (rect.Width - textWidth) / 2;
                e.Graphics.DrawLine(Pens.DarkGray, rect.X, y, rect.X + margin, y);
                e.Graphics.DrawLine(Pens.DarkGray, rect.Right - margin, y, rect.Right, y);
            }
            else
            {
                base.OnRenderItemText(e);
            }
        }

    }
}

因此,您不需要分隔符,而需要禁用的菜单项!

I don't think it is possible. 我认为不可能。 Not with built-in menustrip anyway. 反正没有内置菜单条。 I don't know whether there are 3rd part controls that you could use for this one. 我不知道您是否可以使用第三部分控件。 If you must need it, just make the title as you have shown in your question. 如果您需要它,只需按照问题中显示的标题进行即可。 Just don't write any code for any event of that menustripitem. 只是不要为该菜单项的任何事件编写任何代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM