首页 / 知识

在WinForm标签中格式化文本

2023-04-12 05:25:00

Formatting text in WinForm Label

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

例如:

1
2
Dim myLabel As New Label
myLabel.Text ="This is bold text.  This is italicized text."

它将在标签中产生文本为:

This is bold text. This is
italicized text.


使用WinForms标签是不可能的。标签必须具有正好一种字体,正好具有一种尺寸和一个面。您有两种选择:

  • 使用单独的标签
  • 创建一个新的Control派生类,该类通过GDI +进行自己的绘制,并使用它代替Label;这可能是您最好的选择,因为它使您可以完全控制如何指示控件设置其文本格式
  • 使用第三方标签控件,该控件可让您插入HTML代码段(有一堆-检查CodeProject);这将是其他人实施的#2。

  • 并非如此,但是您可以使用无边框的只读RichTextBox伪造它。 RichTextBox支持RTF格式(rtf)。


    另一个变通方法,晚于聚会:如果您不想使用第三方控件,而您只是想引起人们对标签中某些文本的注意,并且可以使用下划线,则可以使用LinkLabel。

    请注意,许多人认为这是"可用性犯罪",但是如果您不打算为最终用户使用设计某些东西,那么您可能会出于良心准备。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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


    对我来说可行的解决方案-使用自定义RichEditBox。具有正确的属性,它将被视为带有粗体支持的简单标签。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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标志将句子拆分为多个单词,以确定该单词应为粗体还是否:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
            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(@"{\
    tf1\\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!):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
       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

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

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

    在富文本框中格式化文本

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


  • 在写字板中将文本创建为RTF文件
  • 创建无边界的Rich Text控件,并且editable = false
  • 将RTF文件作为资源添加到项目中
  • 在Form1_load中

    myRtfControl.Rtf = Resource1.MyRtfControlText


  • AutoRichLabel

    AutoRichLabel with formatted RTF content

    我通过构建包含只读的TransparentRichTextBoxUserControl解决了这个问题。 TransparentRichTextBox是允许透明的RichTextBox

    TransparentRichTextBox.cs:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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,因为RichTextBoxAutoSize被破坏了。

    AutoRichLabel.designer.cs:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    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:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    /// <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 ;\
    ed0\\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 ;\
    ed0\\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(@"{\
    tf1") ? value : @"{\
    tf1" + 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.
        }
    }

    RTF格式的语法非常简单:

    段:

    1
    {\\pard This is a paragraph!\\par}

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

    1
    2
    3
    \\b bold text\\b0
    \\i italic text\\i0
    \\ul underline text\\ul0

    使用颜色表的替代颜色:

    1
    2
    3
    {\\colortbl ;\
    ed0\\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)。要转义\\{},请使用前导\\
    有关更多信息,请在线获取富文本格式的完整规范。

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

    1
    2
    3
    4
    {\\colortbl ;\
    ed0\\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}

    AutoRichLabel with formatted RTF content

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

    玩得开心!


    很简单的解决方案:

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

    就这样。


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

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


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

    除了已经提到的内容,DevExpress的LabelControl是支持这种行为的标签-此处为演示。 las,它是付费图书馆的一部分。

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


    我也将有兴趣找出是否有可能。

    当我们找不到解决方案时,我们求助于组件'SuperLabel'控件,该控件允许在标签中进行HTML标记。


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


    FlowLayoutPanel可以很好地解决您的问题。如果将标签添加到流面板并设置每个标签的字体和边距属性的格式,则可以使用不同的字体样式。相当简单快捷的解决方案,可以开始工作。


    标签文本格式化设置

    最新内容

    相关内容

    热门文章

    推荐文章

    标签云

    猜你喜欢