2008-08-14 8 views
18

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

Например:

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

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

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

+0

Брайан, если вы использовали № 2 или № 3 ответа Дэнни, не могли бы вы поделиться кодом или ссылкой с тем, что вы использовали? Спасибо. – FastAl 2012-02-27 16:35:16

+0

@FastAl Я верю, что я только что закончил тем, что использовал # 1, но я, возможно, использовал # 3. У меня больше нет доступа к кодовой базе, поэтому я не могу привести пример. Сожалею. – 2012-03-08 22:10:58

ответ

16

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

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

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

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

14

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

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

    myRtfControl.Rtf = Resource1.MyRtfControlText

+0

Хорошее использование словаря! Небольшое усложнение: он генерирует много мусора, что делает понимание возникающего в результате rtf немного сложнее (но можно безопасно удалить) ... Лучше, чем читать rtf «spec». – sharpener 2014-10-29 18:02:55

+0

@sharpener Вы должны увидеть rtf, который создает MS Word ... просто открывая это в Wordpad, и нажатие «save» уменьшает это очень, иногда даже до 10% от исходного размера файла. И нет, я только _wish_ Я шутил или преувеличивал там X_x – Nyerguds 2016-03-31 14:03:26

1

re - отличная статья от 2009 года по проекту Code под названием «A Professional HTML Renderer You Will Use», которая реализует нечто похожее на то, что хочет исходный плакат.

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

0

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

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

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

+0

. Когда мы использовали общие элементы управления DevExpress, у них были проблемы с сюжетом. Например, легко заставить их использовать какую-то странную тему, но трудно заставить их выглядеть так же, как и текущая ОС. – hypersw 2015-08-13 19:19:42

2

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

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

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

Вот и все.

9

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

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

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

0

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

6

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

Sample

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

How to convert a string to RTF in C#?

Format text in Rich Text Box

How to hide the caret in a RichTextBox?

2

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 по-своему, потому что AutoSizeRichTextBox сломался.

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 HST.SCADA.OPCServer.Config.Controls.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). Чтобы избежать \ или { или }, пожалуйста, используйте ведущий \. Для получения дополнительной информации есть full specification of the rich text format online.

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

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

Удачи!

Смежные вопросы