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

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

Например:

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

Который будет производить текст в метке как:

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

14.08.2008 16:43:03
Брайан, если вы использовали № 2 или № 3 из ответа Дэнни, вы не против поделиться кодом или ссылкой на то, что вы использовали? Спасибо.
FastAl 27.02.2012 16:35:16
@FastAl Я полагаю, что я только что использовал # 1, но я мог использовать # 3. У меня больше нет доступа к базе кода, поэтому я не могу привести пример. Сожалею.
Bryan Roth 8.03.2012 22:10:58
12 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

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

1
14.08.2008 16:45:14

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

15
14.08.2008 17:07:39
  1. Создать текст в виде файла RTF в WordPad
  2. Создать элемент управления Rich Text без границ и editable = false
  3. Добавьте файл RTF в проект в качестве ресурса
  4. В Form1_load делай

    myRtfControl.Rtf = Resource1.MyRtfControlText

5
21.10.2009 16:58:53
Хороший момент использования WordPad! Небольшое усложнение: он генерирует много мусора, что делает понимание результирующего rtf немного сложнее (но может быть безопасно удалено) ... Лучше, чем чтение "spec" rtf.
sharpener 29.10.2014 18:02:55
@sharpener Вы должны увидеть rtf, который создает MS Word ... просто открыв его в Wordpad и нажав «сохранить», можно уменьшить его, иногда даже до 10% от исходного размера файла. И нет, я только хотел бы, чтобы я шутил или преувеличивал там X_x
Nyerguds 31.03.2016 14:03:26

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

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

2
30.12.2011 08:19:41

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

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

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

1
27.02.2014 15:36:14
Когда мы использовали общие элементы управления DevExpress, у них возникали огромные проблемы с тематикой. Мол, легко заставить их использовать какую-то странную тему, но трудно заставить их выглядеть так же, как текущая ОС.
hypersw 13.08.2015 19:19:42

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

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

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

Это все.

2
16.04.2014 16:01:51

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

Результат:

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

11
13.04.2017 12:32:14
О, замечательно. Я никогда не знал, что ярлыки ссылок могут иметь определенные области в качестве ссылок. На самом деле это гораздо ближе к варианту использования, который я искал, чем к фактическому вопросу, заданному здесь; мой ярлык был кликабельным в любом случае. Гораздо приятнее с одной кликабельной областью сейчас.
Nyerguds 31.03.2016 13:40:21

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

0
27.08.2014 12:34:37

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

Образец

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

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

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

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

11
23.05.2017 11:54:33
Это лучшее из доступных решений, если вы хотите оставаться максимально легким и избегать сторонних зависимостей. Я протестировал несколько альтернатив, и этот метод работает лучше всего, а также правильно обрабатывает .AutoSize и .WordWrap, как обычные метки. Я также встроил простую функцию преобразования HTML в RTF, которая обрабатывает прямые замены базовыми тегами (жирным шрифтом, курсивом и т. Д.), Поэтому мне вообще не нужно запоминать формат RTF. Я просто загружаю строку в формате HTML.
Special Sauce 22.04.2017 02:17:23

Да уж. Вы можете реализовать, используя HTML Render. Чтобы увидеть, нажмите на ссылку: https://htmlrenderer.codeplex.com/ Я надеюсь, что это полезно.

0
1.04.2015 15:45:41

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

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

Веселиться!

3
4.08.2018 23:56:52