Вопрос

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

Например:

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

Что привело бы к появлению текста в метке в виде:

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

Это было полезно?

Решение

Это невозможно с меткой WinForms в ее нынешнем виде.Надпись должна содержать ровно один шрифт, ровно один размер и одну грань.У вас есть пара вариантов:

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

Другие советы

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

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

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

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

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

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

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

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

    myRtfControl.Rtf = Resource1.MyRtfControlText

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

Синтаксис формата rich text довольно прост:

Абзац:

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

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

Получайте удовольствие!

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

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

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

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

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

Вот и все.

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top