[ToolStripMenuItem].Text = "Some text\nMore text in a new line";
internal class MenuDesignerRendererTextWrap<T> : ToolStripProfessionalRenderer where T :
ToolStripRenderer, new() {
public MenuDesignerRendererTextWrap() : this(new T()) { }
public MenuDesignerRendererTextWrap(T renderer) => Renderer = renderer;
public T Renderer { get; }
private readonly TextFormatFlags flags =
TextFormatFlags.LeftAndRightPadding | TextFormatFlags.VerticalCenter;
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e) {
if (string.IsNullOrEmpty(e.Text)) return;
// The size of the Item is provided here
e.Item.AutoSize = false;
// An Item's viewport is 3 pixels higher than the text's Height
var textHeight = TextRenderer.MeasureText(
e.Graphics, e.Text, e.TextFont,
new Size(e.TextRectangle.Width, int.MaxValue), flags).Height + 3;
var textRect = new Rectangle(
e.TextRectangle.Left, e.TextRectangle.Top, e.TextRectangle.Width, textHeight);
// Bounds of the Item's text
e.TextRectangle = textRect;
// Overall height of the MenuItem: text's viewport.Height + 3 pixels
e.Item.Height = textHeight + 3;
base.OnRenderItemText(e);
}
}
1条答案
按热度按时间afdcj2ne1#
一个示例,使用一个泛型类处理标准ToolStripProfessionalRenderer对象并重写其OnRenderItemText()方法以提供MenuItem的自定义计算大小。
当然,您可以 * 注入 * 自己的
ToolStripProfessionalRenderer
,也可以提供自定义的ProfessionalColorTable,以定义ToolStrip(或派生类,如ContextMenuStrip)及其MenuItem的所有颜色这里有一个例子(用稍微不同的语言编码,但注解和一般描述仍然适用):Change space between Image and Text in ContextMenuStrip
要使ContextMenuStrip使用此自定义渲染器,请使用ToolStripRenderer派生对象(此处为标准
ToolStripProfessionalRenderer
)进行初始化,并设置其对应的Property:注意事项:
我建议在代码中设置MenuItems的文本,当这个文本应该换行时。
您可以插入换行符(
\r
,\n
或\r\n
中的任何一个都可以)将文本分为两行或多行。这在设计师中很难做到。ContextMenuStrip和MenuItems都自动调整其大小作为默认行为。实际上,您还希望ContextMenuStrip自动调整大小为子MenuItem的总高度,否则您必须自己完成此操作。
此外,Item文本的默认呈现使用TextRenderer将文本呈现到Bitmap上。其中一个直接的影响是换行不起作用,因此在设计器中设置一个长字符串不会导致渲染器将其绘制在多行中(无论您是否尝试强制它,设置自定义TextFormatFlags)。
你可以自己使用
Graphics.DrawString()
,在基类代码中绕过TextRenderer,但是渲染是不同的(另外,除了这篇文章的范围:)如前所述,在代码中设置MenuItem的文本更简单,强制换行(这里只有
\n
):