Сведения о вопросе

FELL

22:57, 29th August, 2020

Теги

winforms   text   formatting   label    

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

Просмотров: 568   Ответов: 12

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

Например:

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

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

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



  Сведения об ответе

LAST

21:06, 1st October, 2020

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

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


  Сведения об ответе

davran

18:04, 19th August, 2020

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


  Сведения об ответе

prince

06:28, 13th August, 2020

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

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

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


  Сведения об ответе

DO__IT

21:48, 24th August, 2020

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


  Сведения об ответе

PHPH

15:08, 9th August, 2020

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

    myRtfControl.Rtf = Resource1.MyRtfControlText


  Сведения об ответе

qwerty101

14:19, 6th August, 2020

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 ). Чтобы избежать \ или { или }, пожалуйста, используйте ведущий \ . Для получения дополнительной информации есть полная спецификация формата rich text в интернете .

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

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

Веселитесь!


  Сведения об ответе

park

04:10, 20th August, 2020

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

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


  Сведения об ответе

FAriza

03:31, 5th August, 2020

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

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

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

Это все.


  Сведения об ответе

+-*/

20:34, 8th August, 2020

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

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


  Сведения об ответе

baggs

16:02, 11th August, 2020

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

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

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


  Сведения об ответе

lats

02:18, 5th August, 2020

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


  Сведения об ответе

+-*/

06:41, 15th August, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться