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

时间:2012-02-07 12:25:33

标签: c# vb.net winforms

以窗体形式。我想在菜单分隔符中添加信息性文本。任何人都可以建议如何做到这一点? 例如,分隔符应如下所示

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

经过多次尝试后,我只能添加简单的分隔符。任何帮助都很棒

4 个答案:

答案 0 :(得分:3)

您可以创建自己的菜单分隔符

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

如果在同一项目中定义它,它将自动出现在“插入”上下文菜单中。


我还试图覆盖OnPaint方法。没有成功。有一些魔法会阻止所有者绘制的对象出现。


修改

最后,经过一些研究和大量的反复试验,我发现了一个更令人满意的解决方案。这就是结果的样子

enter image description here

首先,我们创建自己的工具条分隔符类。

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

如您所见,它非常简单。更复杂的部分在我们自己的MenuStrip类中。在这里,我们提供了一个定制的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

答案 1 :(得分:1)

所以你不需要分隔符,你需要一个禁用的菜单项!

答案 2 :(得分:1)

我需要创建一个Olivier Jacot-Descombes解决方案的C#实现,所以在这里以防万一其他人需要它。在我的情况下,我需要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);
            }
        }

    }
}

答案 3 :(得分:0)

我认为不可能。无论如何都没有内置的menustrip。我不知道你是否可以使用第三部分控件。 如果您必须需要它,只需按照您在问题中显示的标题即可。只是不要为任何menustripitem事件编写任何代码。