winforms 在 WinForm 标签中格式化文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:36:44  来源:igfitidea点击:

Formatting text in WinForm Label

winformstextformattinglabel

提问by Bryan Roth

Is it possible to format certain text in a WinForm Label instead of breaking the text into multiple labels? Please disregard the HTML tags within the label's text; it's only used to get my point out.

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

For example:

例如:

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

Which would produce the text in the label as:

这将产生标签中的文本为:

This is boldtext. This is italicizedtext.

这是粗体文本。这是 斜体文本。

采纳答案by TheSmurf

That's not possible with a WinForms label as it is. The label has to have exactly one font, with exactly one size and one face. You have a couple of options:

这对于 WinForms 标签是不可能的。标签必须只有一种字体,只有一种尺寸和一种面。您有几个选择:

  1. Use separate labels
  2. Create a new Control-derived class that does its own drawing via GDI+ and use that instead of Label; this is probably your best option, as it gives you complete control over how to instruct the control to format its text
  3. Use a third-party label control that will let you insert HTML snippets (there are a bunch - check CodeProject); this would be someone else's implementation of #2.
  1. 使用单独的标签
  2. 创建一个新的 Control 派生类,它通过 GDI+ 进行自己的绘图,并使用它而不是 Label;这可能是您最好的选择,因为它使您可以完全控制如何指示控件格式化其文本
  3. 使用第三方标签控件,可以让您插入 HTML 片段(有很多 - 检查 CodeProject);这将是其他人对#2 的实现。

回答by ageektrapped

Not really, but you could fake it with a read-only RichTextBox without borders. RichTextBox supports Rich Text Format (rtf).

不是真的,但您可以使用无边框的只读 RichTextBox 来伪造它。RichTextBox 支持富文本格式 (rtf)。

回答by Geoff

Another workaround, late to the party: if you don't want to use a third party control, and you're just looking to call attention to some of the text in your label, andyou're ok with underlines, you can use a LinkLabel.

另一个解决方法,晚到晚了:如果您不想使用第三方控件,并且只想引起对标签中某些文本的注意,并且您可以使用下划线,则可以使用一个链接标签

Note that many consider this a 'usability crime', but if you're not designing something for end user consumption then it may be something you're prepared to have on your conscience.

请注意,许多人认为这是一种“可用性犯罪”,但如果您不是为最终用户消费设计的东西,那么您可能已经准备好凭良心去做。

The trick is to add disabled links to the parts of your text that you want underlined, and then globally set the link colors to match the rest of the label. You can set almost all the necessary properties at design-time apart from the Links.Add()piece, but here they are in code:

诀窍是将禁​​用的链接添加到您想要加下划线的文本部分,然后全局设置链接颜色以匹配标签的其余部分。除了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;

Result:

结果:

enter image description here

在此处输入图片说明

回答by Nigrimmist

Worked solution for me - using custom RichEditBox. With right properties it will be looked as simple label with bold support.

对我来说有效的解决方案 - 使用自定义 RichEditBox。使用正确的属性,它将看起来像带有粗体支持的简单标签。

1)First, add your custom RichTextLabel class with disabled caret :

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)Split you sentence to words with IsSelected flag, that determine if that word should be bold or no :

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)Add function for convert you text to valid rtf (with unicode support!) :

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

样本

Works like a charm for me! Solutions compiled from :

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

How to convert a string to RTF in C#?

如何在 C# 中将字符串转换为 RTF?

Format text in Rich Text Box

在富文本框中格式化文本

How to hide the caret in a RichTextBox?

如何在 RichTextBox 中隐藏插入符号?

回答by Phil

  1. Create the text as a RTF file in wordpad
  2. Create Rich text control with no borders and editable = false
  3. Add the RTF file to the project as a resource
  4. In the Form1_load do

    myRtfControl.Rtf = Resource1.MyRtfControlText

  1. 在写字板中将文本创建为 RTF 文件
  2. 创建无边框且可编辑的富文本控件 = false
  3. 将 RTF 文件作为资源添加到项目中
  4. 在 Form1_load 中做

    myRtfControl.Rtf = Resource1.MyRtfControlText

回答by Martin Braun

AutoRichLabel

自动丰富标签

      AutoRichLabel with formatted RTF content

      带有格式化 RTF 内容的 AutoRichLabel

I was solving this problem by building an UserControlthat contains a TransparentRichTextBoxthat is readonly. The TransparentRichTextBoxis a RichTextBoxthat allows to be transparent:

我通过构建一个UserControl包含TransparentRichTextBox只读的a来解决这个问题。这TransparentRichTextBox是一个RichTextBox允许透明的:

TransparentRichTextBox.cs:

TransparentRichTextBox.cs:

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;
        }
    }
}

The final UserControlacts as wrapper of the TransparentRichTextBox. Unfortunately, I had to limit it to AutoSizeon my own way, because the AutoSizeof the RichTextBoxbecame broken.

finalUserControl充当TransparentRichTextBox. 不幸的是,我不得不把它限制在AutoSize我自己的方式,因为AutoSizeRichTextBox成为打破。

AutoRichLabel.designer.cs:

AutoRichLabel.designer.cs:

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;
}

AutoRichLabel.cs:

AutoRichLabel.cs:

/// <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
{\pard This is a paragraph!\par}
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
\b bold text\b0
\i italic text\i0
\ul underline text\ul0
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. } }

The syntax of the rich text format is quite simple:

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

Paragraph:

段落:

{\colortbl ;\red0\green77\blue187;}
{\pard The word \cf1 fish\cf0  is blue.\par

Bold / Italic / Underline text:

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

{\colortbl ;\red0\green77\blue187;}
{\pard\b BOLD\b0  \i ITALIC\i0  \ul UNDERLINE\ul0 \\{\}\par}
{\pard\cf1\b BOLD\b0  \i ITALIC\i0  \ul UNDERLINE\ul0\cf0 \\{\}\par}

Alternate color using color table:

使用颜色表的替代颜色:

##代码##

But please note: Always wrap every text in a paragraph. Also, different tags can be stacked (i.e. \pard\b\i Bold and Italic\i0\b0\par) and the space character 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). To escape \or {or }, please use a leading \. For more information there is a full specification of the rich text format online.

但请注意:始终将每个文本包装在一个段落中。此外,可以堆叠不同的标签(即\pard\b\i Bold and Italic\i0\b0\par)并且忽略标签后面的空格字符。因此,如果您需要在其后面留一个空格,请插入两个空格(即\pard The word \bBOLD\0 is bold.\par)。要转义\or{},请使用前导\。有关详细信息,请参阅在线富文本格式完整规范

Using this quite simple syntax you can produce something like you can see in the first image. The rich text content that was attached to the RtfContentproperty of my AutoRichLabelin the first image was:

使用这种非常简单的语法,您可以生成类似于您在第一张图片中看到的内容。第一张图片中附加到RtfContent我的属性的富文本内容AutoRichLabel是:

##代码##

AutoRichLabel with formatted RTF content

带有格式化 RTF 内容的 AutoRichLabel

If you want to enable word wrap, please set the maximum width to a desired size. However, this will fix the width to the maximum width, even when the text is shorter.

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

Have fun!

玩得开心!

回答by user3541933

Very simple solution:

非常简单的解决方案:

  1. Add 2 labels on the form, LabelA and LabelB
  2. Go to properties for LabelA and dock it to left.
  3. Go to properties for LabelB and dock it to left as well.
  4. Set Font to bold for LabelA .
  1. 在表单上添加 2 个标签,LabelA 和 LabelB
  2. 转到 LabelA 的属性并将其停靠在左侧。
  3. 转到 LabelB 的属性并将其停靠在左侧。
  4. 将 LabelA 的字体设置为粗体。

Now the LabelB will shift depending on length of text of LabelA.

现在 LabelB 将根据 LabelA 的文本长度移动。

That's all.

就这样。

回答by Uwe Keim

There is an excellent article from 2009 on Code Project named "A Professional HTML Renderer You Will Use" which implements something similar to what the original poster wants.

2009 年有一篇关于代码项目的优秀文章,名为“您将使用的专业 HTML 渲染器”,它实现了与原始海报想要的类似的东西。

I use it successfully within several projects of us.

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

回答by pKami

Realising this is an old question, my answer is more for those, like me, who still may be looking for such solutions and stumble upon this question.

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

Apart from what was already mentioned, DevExpress's LabelControlis a label that supports this behaviour - demo here. Alas, it is part of a paid library.

除了已经提到的之外,DevExpress 的LabelControl是一个支持这种行为的标签 -演示在这里。唉,它是付费图书馆的一部分。

If you're looking for free solutions, I believe HTML Rendereris the next best thing.

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

回答by Martin

I Would also be interested in finding out if it is possible.

我也很想知道是否有可能。

When we couldn't find a solution we resorted to Component Ones 'SuperLabel' control which allows HTML markup in a label.

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