在WinForm标签中格式化文本

时间:2008-08-14 16:43:04

标签: winforms text formatting label

是否可以格式化WinForm标签中的某些文本而不是将文本分成多个标签?请忽略标签文本中的HTML标签;它只是用来说明我的观点。

例如:

Dim myLabel As New Label
myLabel.Text = "This is <b>bold</b> text.  This is <i>italicized</i> text."

这会在标签中产生以下内容:

  

这是粗体文字。这是   斜体文字。

12 个答案:

答案 0 :(得分:18)

使用WinForms标签是不可能的。标签必须只有一种字体,只有一种尺寸和一种面。你有几个选择:

  1. 使用单独的标签
  2. 创建一个新的Control派生类,通过GDI +执行自己的绘图,并使用它而不是Label;这可能是您的最佳选择,因为它可以让您完全控制如何指示控件格式化其文本
  3. 使用第三方标签控件,可以插入HTML代码段(有一堆 - 检查CodeProject);这将是别人对#2的实现。

答案 1 :(得分:15)

不是真的,但你可以使用没有边框的只读RichTextBox伪造它。 RichTextBox支持RTF格式(rtf)。

答案 2 :(得分:11)

另一种解决方法,即晚会:如果您不想使用第三方控件,而您只是想提醒您注意标签中的某些文字,你可以使用下划线,你可以使用LinkLabel

请注意,许多人认为这是&#39; usability crime&#39;,但如果您没有为最终用户消费设计某些东西,那么它可能是您准备拥有的东西你的良心。

诀窍是添加禁用链接到文本中要加下划线的部分,然后全局设置链接颜色以匹配标签的其余部分。您可以在设计时设置除Links.Add()之外的几乎所有必需属性,但这里它们在代码中:

linkLabel1.Text = "You are accessing a government system, and all activity " +
                  "will be logged.  If you do not wish to continue, log out now.";
linkLabel1.AutoSize = false;
linkLabel1.Size = new Size(365, 50);
linkLabel1.TextAlign = ContentAlignment.MiddleCenter;
linkLabel1.Links.Clear();
linkLabel1.Links.Add(20, 17).Enabled = false;   // "government system"
linkLabel1.Links.Add(105, 11).Enabled = false;  // "log out now"
linkLabel1.LinkColor = linkLabel1.ForeColor;
linkLabel1.DisabledLinkColor = linkLabel1.ForeColor;

结果:

enter image description here

答案 3 :(得分:9)

为我工作的解决方案 - 使用自定义RichEditBox。使用正确的属性,它将被视为具有大胆支持的简单标签。

1)首先,添加带有禁用插入符号的自定义RichTextLabel类:

public class RichTextLabel : RichTextBox
{
    public RichTextLabel()
    {
        base.ReadOnly = true;
        base.BorderStyle = BorderStyle.None;
        base.TabStop = false;
        base.SetStyle(ControlStyles.Selectable, false);
        base.SetStyle(ControlStyles.UserMouse, true);
        base.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

        base.MouseEnter += delegate(object sender, EventArgs e)
        {
            this.Cursor = Cursors.Default;
        };
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x204) return; // WM_RBUTTONDOWN
        if (m.Msg == 0x205) return; // WM_RBUTTONUP
        base.WndProc(ref m);
    }
}

2)将句子拆分为带有IsSelected标志的单词,用于确定该单词是否应为粗体:

        private void AutocompleteItemControl_Load(object sender, EventArgs e)
    {
        RichTextLabel rtl = new RichTextLabel();
        rtl.Font = new Font("MS Reference Sans Serif", 15.57F);
        StringBuilder sb = new StringBuilder();
        sb.Append(@"{\rtf1\ansi ");
        foreach (var wordPart in wordParts)
        {
            if (wordPart.IsSelected)
            {
                sb.Append(@"\b ");
            }
            sb.Append(ConvertString2RTF(wordPart.WordPart));
            if (wordPart.IsSelected)
            {
                sb.Append(@"\b0 ");
            }
        }
        sb.Append(@"}");

        rtl.Rtf = sb.ToString();
        rtl.Width = this.Width;
        this.Controls.Add(rtl);
    }

3)添加将文本转换为有效rtf的函数(支持unicode!):

   private string ConvertString2RTF(string input)
    {
        //first take care of special RTF chars
        StringBuilder backslashed = new StringBuilder(input);
        backslashed.Replace(@"\", @"\\");
        backslashed.Replace(@"{", @"\{");
        backslashed.Replace(@"}", @"\}");

        //then convert the string char by char
        StringBuilder sb = new StringBuilder();
        foreach (char character in backslashed.ToString())
        {
            if (character <= 0x7f)
                sb.Append(character);
            else
                sb.Append("\\u" + Convert.ToUInt32(character) + "?");
        }
        return sb.ToString();
    }

Sample

对我来说就像一个魅力! 解决方案来自:

How to convert a string to RTF in C#?

Format text in Rich Text Box

How to hide the caret in a RichTextBox?

答案 4 :(得分:5)

  1. 在wordpad中将文本创建为RTF文件
  2. 创建没有边框的富文本控件,editable = false
  3. 将RTF文件作为资源添加到项目中
  4. 在Form1_load中执行

    myRtfControl.Rtf = Resource1.MyRtfControlText

答案 5 :(得分:3)

AutoRichLabel

AutoRichLabel with formatted RTF content

我通过构建包含{1}} UserControl的{​​{1}}来解决此问题。 TransparentRichTextBoxTransparentRichTextBox,允许透明:

TransparentRichTextBox.cs:

RichTextBox

最终public class TransparentRichTextBox : RichTextBox { [DllImport("kernel32.dll", CharSet = CharSet.Auto)] static extern IntPtr LoadLibrary(string lpFileName); protected override CreateParams CreateParams { get { CreateParams prams = base.CreateParams; if (TransparentRichTextBox.LoadLibrary("msftedit.dll") != IntPtr.Zero) { prams.ExStyle |= 0x020; // transparent prams.ClassName = "RICHEDIT50W"; } return prams; } } } 充当UserControl的包装。不幸的是,我必须以自己的方式将其限制为TransparentRichTextBox,因为AutoSize的{​​{1}}已被破坏。

AutoRichLabel.designer.cs:

AutoSize

AutoRichLabel.cs:

RichTextBox

富文本格式的语法非常简单:

段落:

partial class AutoRichLabel
{
    /// <summary> 
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.rtb = new TransparentRichTextBox();
        this.SuspendLayout();
        // 
        // rtb
        // 
        this.rtb.BorderStyle = System.Windows.Forms.BorderStyle.None;
        this.rtb.Dock = System.Windows.Forms.DockStyle.Fill;
        this.rtb.Location = new System.Drawing.Point(0, 0);
        this.rtb.Margin = new System.Windows.Forms.Padding(0);
        this.rtb.Name = "rtb";
        this.rtb.ReadOnly = true;
        this.rtb.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None;
        this.rtb.Size = new System.Drawing.Size(46, 30);
        this.rtb.TabIndex = 0;
        this.rtb.Text = "";
        this.rtb.WordWrap = false;
        this.rtb.ContentsResized += new System.Windows.Forms.ContentsResizedEventHandler(this.rtb_ContentsResized);
        // 
        // AutoRichLabel
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
        this.BackColor = System.Drawing.Color.Transparent;
        this.Controls.Add(this.rtb);
        this.Name = "AutoRichLabel";
        this.Size = new System.Drawing.Size(46, 30);
        this.ResumeLayout(false);

    }

    #endregion

    private TransparentRichTextBox rtb;
}

粗体/斜体/下划线文字:

/// <summary>
/// <para>An auto sized label with the ability to display text with formattings by using the Rich Text Format.</para>
/// <para>­</para>
/// <para>Short RTF syntax examples: </para>
/// <para>­</para>
/// <para>Paragraph: </para>
/// <para>{\pard This is a paragraph!\par}</para>
/// <para>­</para>
/// <para>Bold / Italic / Underline: </para>
/// <para>\b bold text\b0</para>
/// <para>\i italic text\i0</para>
/// <para>\ul underline text\ul0</para>
/// <para>­</para>
/// <para>Alternate color using color table: </para>
/// <para>{\colortbl ;\red0\green77\blue187;}{\pard The word \cf1 fish\cf0  is blue.\par</para>
/// <para>­</para>
/// <para>Additional information: </para>
/// <para>Always wrap every text in a paragraph. </para>
/// <para>Different tags can be stacked (i.e. \pard\b\i Bold and Italic\i0\b0\par)</para>
/// <para>The space behind a tag is ignored. So if you need a space behind it, insert two spaces (i.e. \pard The word \bBOLD\0  is bold.\par)</para>
/// <para>Full specification: http://www.biblioscape.com/rtf15_spec.htm </para>
/// </summary>
public partial class AutoRichLabel : UserControl
{
    /// <summary>
    /// The rich text content. 
    /// <para>­</para>
    /// <para>Short RTF syntax examples: </para>
    /// <para>­</para>
    /// <para>Paragraph: </para>
    /// <para>{\pard This is a paragraph!\par}</para>
    /// <para>­</para>
    /// <para>Bold / Italic / Underline: </para>
    /// <para>\b bold text\b0</para>
    /// <para>\i italic text\i0</para>
    /// <para>\ul underline text\ul0</para>
    /// <para>­</para>
    /// <para>Alternate color using color table: </para>
    /// <para>{\colortbl ;\red0\green77\blue187;}{\pard The word \cf1 fish\cf0  is blue.\par</para>
    /// <para>­</para>
    /// <para>Additional information: </para>
    /// <para>Always wrap every text in a paragraph. </para>
    /// <para>Different tags can be stacked (i.e. \pard\b\i Bold and Italic\i0\b0\par)</para>
    /// <para>The space behind a tag is ignored. So if you need a space behind it, insert two spaces (i.e. \pard The word \bBOLD\0  is bold.\par)</para>
    /// <para>Full specification: http://www.biblioscape.com/rtf15_spec.htm </para>
    /// </summary>
    [Browsable(true)]
    public string RtfContent
    {
        get
        {
            return this.rtb.Rtf;
        }
        set
        {
            this.rtb.WordWrap = false; // to prevent any display bugs, word wrap must be off while changing the rich text content. 
            this.rtb.Rtf = value.StartsWith(@"{\rtf1") ? value : @"{\rtf1" + value + "}"; // Setting the rich text content will trigger the ContentsResized event. 
            this.Fit(); // Override width and height. 
            this.rtb.WordWrap = this.WordWrap; // Set the word wrap back. 
        }
    }

    /// <summary>
    /// Dynamic width of the control. 
    /// </summary>
    [Browsable(false)]
    public new int Width
    {
        get
        {
            return base.Width;
        } 
    }

    /// <summary>
    /// Dynamic height of the control. 
    /// </summary>
    [Browsable(false)]
    public new int Height
    {
        get
        {
            return base.Height;
        }
    }

    /// <summary>
    /// The measured width based on the content. 
    /// </summary>
    public int DesiredWidth { get; private set; }

    /// <summary>
    /// The measured height based on the content. 
    /// </summary>
    public int DesiredHeight { get; private set; }

    /// <summary>
    /// Determines the text will be word wrapped. This is true, when the maximum size has been set. 
    /// </summary>
    public bool WordWrap { get; private set; }

    /// <summary>
    /// Constructor. 
    /// </summary>
    public AutoRichLabel()
    {
        InitializeComponent();
    }

    /// <summary>
    /// Overrides the width and height with the measured width and height
    /// </summary>
    public void Fit()
    {
        base.Width = this.DesiredWidth;
        base.Height = this.DesiredHeight;
    }

    /// <summary>
    /// Will be called when the rich text content of the control changes. 
    /// </summary>
    private void rtb_ContentsResized(object sender, ContentsResizedEventArgs e)
    {
        this.AutoSize = false; // Disable auto size, else it will break everything
        this.WordWrap = this.MaximumSize.Width > 0; // Enable word wrap when the maximum width has been set. 
        this.DesiredWidth = this.rtb.WordWrap ? this.MaximumSize.Width : e.NewRectangle.Width; // Measure width. 
        this.DesiredHeight = this.MaximumSize.Height > 0 && this.MaximumSize.Height < e.NewRectangle.Height ? this.MaximumSize.Height : e.NewRectangle.Height; // Measure height. 
        this.Fit(); // Override width and height. 
    }
}

使用颜色表替换颜色:

{\pard This is a paragraph!\par}

但请注意:始终将每个文本都包装在一个段落中。此外,可以堆叠不同的标签(即\b bold text\b0 \i italic text\i0 \ul underline text\ul0 ),并忽略标签后面的空格字符。因此,如果您需要一个空格,请插入两个空格(即{\colortbl ;\red0\green77\blue187;} {\pard The word \cf1 fish\cf0 is blue.\par )。要转义\pard\b\i Bold and Italic\i0\b0\par\pard The word \bBOLD\0 is bold.\par\,请使用前导{。 有关更多信息,请full specification of the rich text format online

使用这种非常简单的语法,您可以生成第一张图片中可以看到的内容。在第一张图片中附加到} \属性的富文本内容为:

RtfContent
  

AutoRichLabel with formatted RTF content

如果要启用自动换行,请将最大宽度设置为所需的大小。但是,即使文本较短,这也会将宽度固定为最大宽度。

玩得开心!

答案 6 :(得分:2)

2009年有一篇名为“A Professional HTML Renderer You Will Use”的代码项目的优秀文章实现了与原始海报相似的内容。

我在我们的几个项目中成功使用它。

答案 7 :(得分:2)

非常简单的解决方案:

  1. 在表单上添加2个标签,LabelA和LabelB
  2. 转到LabelA的属性并将其停靠在左侧。
  3. 转到LabelB的属性并将其停靠在左侧。
  4. 将LabelA的字体设置为粗体。
  5. 现在LabelB将根据LabelA的文本长度而移动。

    这就是全部。

答案 8 :(得分:1)

我也有兴趣了解是否有可能。

当我们找不到解决方案时,我们使用了Component Ones的'SuperLabel'控件,它允许在标签中添加HTML标记。

答案 9 :(得分:1)

意识到这是一个老问题,我的回答更多的是像我这样的人,他们仍然可能正在寻找这样的解决方案并偶然发现这个问题。

除了已经提到的内容之外,DevExpress的LabelControl是一个支持此行为的标签 - demo here。唉,它是付费图书馆的一部分。

如果您正在寻找免费的解决方案,我相信HTML Renderer是下一个最好的解决方案。

答案 10 :(得分:0)

FlowLayoutPanel适用于您的问题。如果向流程面板添加标签并格式化每个标签的字体和边距属性,则可以使用不同的字体样式。非常快速简便的解决方案。

答案 11 :(得分:0)

呀。 您可以使用HTML Render实现。 如您所见,请点击链接:https://htmlrenderer.codeplex.com/ 我希望这很有用。