Форматирование текста в WinForm Label - PullRequest
21 голосов
/ 14 августа 2008

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

Например:

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

Что даст текст в метке как:

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

Ответы [ 12 ]

18 голосов
/ 14 августа 2008

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

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

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

11 голосов
/ 13 июня 2014

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

Результат:

enter image description here

9 голосов
/ 25 февраля 2015

Отработанное решение для меня - с помощью пользовательского 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

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

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

Форматировать текст в Rich Text Box

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

5 голосов
/ 21 октября 2009
  1. Создать текст в виде файла RTF в WordPad
  2. Создать элемент управления Rich Text без границ и редактируемый = false
  3. Добавить файл RTF в проект в качестве ресурса
  4. В Form1_load сделать

    myRtfControl.Rtf = Resource1.MyRtfControlText

3 голосов
/ 19 октября 2015

AutoRichLabel

AutoRichLabel with formatted RTF content

Я решил эту проблему, создав 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 моего 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 with formatted RTF content

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

Веселись!

2 голосов
/ 16 апреля 2014

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

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

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

Вот и все.

2 голосов
/ 30 декабря 2011

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

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

1 голос
/ 27 февраля 2014

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

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

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

1 голос
/ 14 августа 2008

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

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

...