Можно ли отформатировать определенный текст в метке WinForm вместо того, чтобы разбивать текст на несколько меток? Не обращайте внимания на HTML-теги в тексте ярлыка; это используется только для того, чтобы выразить мою точку зрения.
Например:
Dim myLabel As New Label
myLabel.Text = "This is <b>bold</b> text. This is <i>italicized</i> text."
В результате текст на этикетке будет выглядеть так:
This is bold text. This is italicized text.
@FastAl Думаю, я только что использовал №1, но, возможно, использовал №3. У меня больше нет доступа к базе кода, поэтому я не могу привести пример. Извини.





Мне также было бы интересно узнать, возможно ли это.
Когда мы не могли найти решение, мы прибегали к элементу управления SuperLabel компонентов Ones, который позволяет разметку HTML в метке.
Это невозможно с ярлыком WinForms как таковым. На этикетке должен быть ровно один шрифт, ровно одного размера и одного начертания. У вас есть несколько вариантов:
Не совсем, но вы можете подделать его с помощью RichTextBox, доступного только для чтения, без границ. RichTextBox поддерживает Rich Text Format (RTF).
В Form1_load делаем
myRtfControl.Rtf = Resource1.MyRtfControlText
Хороший аргумент в пользу использования wordpad! Небольшое осложнение: он генерирует много мусора, что немного затрудняет понимание результирующего rtf (но может быть безопасно удалено) ... Лучше, чем чтение "спецификации" rtf.
@sharpener Вы должны увидеть rtf, который создает MS Word ... просто открыв его в Wordpad и нажав «сохранить», вы значительно уменьшите его, иногда даже до 10% от исходного размера файла. А нет, я только желание пошутил или преувеличил там X_x
Есть отличная статья 2009 года в Code Project под названием "Профессиональный HTML-рендерер, который вы будете использовать", которая реализует нечто похожее на то, что хочет исходный плакат.
Я успешно использую его в нескольких наших проектах.
Понимая, что это старый вопрос, мой ответ больше для тех, кто, как я, все еще может искать такие решения и наткнуться на этот вопрос.
Помимо того, что уже упоминалось, DevExpress LabelControl - это метка, которая поддерживает это поведение - демо здесь. Увы, это часть платной библиотеки.
Если вы ищете бесплатные решения, я считаю, что HTML-рендерер - следующая лучшая вещь.
Когда мы использовали общие элементы управления DevExpress, у них были огромные проблемы с темами. Мол, их легко заставить использовать какую-то странную тему, но сложно сделать так, чтобы они выглядели так же, как текущая ОС.
Очень простое решение:
Теперь LabelB будет смещаться в зависимости от длины текста LabelA.
Вот и все.
Другой обходной путь, поздно для вечеринки: если вы не хотите использовать сторонний элемент управления, и вы просто хотите привлечь внимание к некоторому тексту на вашей этикетке, и, вы в порядке с подчеркиванием, вы можете использовать а 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;
Результат:

О, замечательно. Я никогда не знал, что метки ссылок могут иметь определенные области в качестве ссылок. На самом деле это намного ближе к варианту использования, который я искал, чем вопрос, заданный здесь; мой ярлык все равно был доступен для кликов. Гораздо лучше, ведь теперь всего одна интерактивная область.
FlowLayoutPanel хорошо подходит для вашей проблемы. Если вы добавите метки на панель потока и отформатируете свойства шрифта и поля каждой метки, тогда у вас могут быть разные стили шрифтов. Довольно быстрое и простое решение для начала работы.
Сработанное решение для меня - использование настраиваемого 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?
Это лучшее доступное решение, если вы хотите оставаться максимально легким и избегать сторонних зависимостей. Я протестировал несколько альтернатив, и этот метод работает лучше всего, а также правильно обрабатывает .AutoSize и .WordWrap, как обычный ярлык. Я также встроил простую функцию конвертера HTML в RTF, которая обрабатывает прямые замены с помощью основных тегов (выделение жирным шрифтом, курсив и т. д.), Поэтому мне вообще не нужно запоминать формат RTF. Я просто загружаю строку в формате HTML.
Да. Вы можете реализовать, используя HTML Render. Видите, нажмите на ссылку: https://htmlrenderer.codeplex.com/ Надеюсь, это будет полезно.
Я решил эту проблему, построив 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}
Если вы хотите включить перенос слов, установите желаемый размер для максимальной ширины. Однако это зафиксирует максимальную ширину, даже если текст короче.
Веселиться!
Брайан, если вы использовали №2 или №3 ответа Дэнни, не могли бы вы поделиться кодом или ссылкой на то, что вы использовали? Спасибо.