Форматирование текста в WinForm Label

Можно ли отформатировать определенный текст в метке WinForm вместо того, чтобы разбивать текст на несколько меток? Не обращайте внимания на HTML-теги в тексте ярлыка; это используется только для того, чтобы выразить мою точку зрения.

Например:

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

В результате текст на этикетке будет выглядеть так:

Это жирный текст. Это курсивный текст.

Ответов (12)

Решение

Это невозможно с ярлыком WinForms как таковым. На этикетке должен быть ровно один шрифт, ровно одного размера и одного начертания. У вас есть несколько вариантов:

  1. Используйте отдельные ярлыки
  2. Создайте новый производный от Control класс, который выполняет свой собственный рисунок через GDI +, и используйте его вместо Label; это, вероятно, ваш лучший вариант, поскольку он дает вам полный контроль над тем, как указать элементу управления форматировать его текст
  3. Используйте сторонний элемент управления ярлыком, который позволит вам вставлять фрагменты HTML (их много - проверьте CodeProject); это будет чья-то реализация №2.

Мне также было бы интересно узнать, возможно ли это.

Когда мы не могли найти решение, мы прибегали к элементу управления SuperLabel компонентов Ones, который позволяет разметку HTML в метке.

Не совсем, но вы можете подделать его с помощью RichTextBox, доступного только для чтения, без границ. RichTextBox поддерживает Rich Text Format (RTF).

Есть отличная статья 2009 года в Code Project под названием « Профессиональный HTML-рендерер, который вы будете использовать », которая реализует нечто похожее на то, что хочет исходный плакат.

Я успешно использую его в нескольких наших проектах.

Понимая, что это старый вопрос, мой ответ больше для тех, кто, как я, все еще может искать такие решения и наткнуться на этот вопрос.

Помимо того, что уже упоминалось, LabelControl от DevExpress - это метка, которая поддерживает это поведение - демонстрация здесь . Увы, это часть платной библиотеки.

Если вы ищете бесплатные решения, я считаю, что HTML Renderer - это лучшее, что вам нужно.

Очень простое решение:

  1. Добавьте в форму 2 метки: LabelA и LabelB.
  2. Перейдите в свойства LabelA и закрепите его слева.
  3. Перейдите в свойства LabelB и также закрепите его слева.
  4. Установите жирный шрифт для LabelA.

Теперь LabelB будет смещаться в зависимости от длины текста LabelA.

Это все.

FlowLayoutPanel хорошо подходит для вашей проблемы. Если вы добавите метки на панель потока и отформатируете свойства шрифта и поля каждой метки, тогда у вас могут быть разные стили шрифтов. Довольно быстрое и простое решение для начала работы.

AutoRichLabel

      AutoRichLabel с форматированным содержимым RTF

Я решил эту проблему , создав файл UserControl, содержащий только для TransparentRichTextBox чтения. TransparentRichTextBox Является , RichTextBox что позволяет быть прозрачным:

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

Финал UserControl действует как оболочка TransparentRichTextBox . К сожалению, мне пришлось ограничиться AutoSize на своем пути, потому AutoSize что RichTextBox сломалась часть.

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:

/// <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 ). Для того, чтобы избежать \ или , { или }, пожалуйста , используйте ведущий \ . Для получения дополнительной информации в Интернете есть полная спецификация форматированного текста .

Используя этот довольно простой синтаксис, вы можете создать что-то вроде того, что вы видите на первом изображении. Форматированный текстовый контент, который был прикреплен к RtfContent свойству my AutoRichLabel на первом изображении, был:

{\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}

AutoRichLabel с форматированным содержимым RTF

Если вы хотите включить перенос слов, установите желаемый размер для максимальной ширины. Однако это зафиксирует максимальную ширину, даже если текст короче.

Повеселись!

Другой обходной путь, поздно для вечеринки: если вы не хотите использовать сторонний элемент управления, и вы просто хотите привлечь внимание к некоторому тексту на своей этикетке, и вас устраивает подчеркивание, вы можете использовать LinkLabel .

Обратите внимание, что многие считают это « преступлением в отношении юзабилити », но если вы разрабатываете что-то не для конечного пользователя, то, возможно, вы готовы оставить это на своей совести.

Уловка состоит в том, чтобы добавить отключенные ссылки к тем частям вашего текста, которые вы хотите подчеркнуть, а затем глобально установить цвета ссылок, чтобы они соответствовали остальной части метки. Вы можете установить почти все необходимые свойства во время разработки, кроме 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;

Результат:

введите описание изображения здесь

  1. Создайте текст как файл RTF в Wordpad
  2. Создать элемент управления Rich text без границ и editable = false
  3. Добавьте файл RTF в проект в качестве ресурса
  4. В Form1_load делаем

    myRtfControl.Rtf = Resource1.MyRtfControlText

Ага. Вы можете реализовать, используя HTML Render. Как видите, щелкните ссылку: https://htmlrenderer.codeplex.com/ Надеюсь, это будет полезно.

Сработанное решение для меня - использование настраиваемого 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 (с поддержкой юникода!):

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

Образец

Для меня работает как шарм! Решения составлены из:

Как преобразовать строку в RTF на C#?

Форматирование текста в поле RTF

Как скрыть курсор в RichTextBox?