2008-08-14 27 views
18

¿Es posible formatear cierto texto en una etiqueta WinForm en lugar de dividir el texto en varias etiquetas? Por favor, ignore las etiquetas HTML dentro del texto de la etiqueta; solo se usa para expresar mi punto.Formateo de texto en la etiqueta WinForm

Por ejemplo:

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

que produciría el texto en la etiqueta como:

Esto es negrita texto. Esto es en cursiva texto.

+0

Bryan, si utilizó # 2 y # 3 de la respuesta de Danny, ¿te importa compartir el código o un enlace a lo que utilizó? Gracias. – FastAl

+0

@FastAl Creo que terminé usando el n. ° 1, pero es posible que haya usado el n. ° 3. Ya no tengo acceso a la base de código, así que no puedo dar un ejemplo. Lo siento. –

Respuesta

16

Eso no es posible con una etiqueta WinForms tal como está. La etiqueta debe tener exactamente una fuente, con exactamente un tamaño y una cara. Usted tiene un par de opciones:

  1. Utilice etiquetas separadas
  2. Crear una nueva clase de control derivado que hace su propio dibujo a través de GDI + y el uso que en lugar de la etiqueta; esta es probablemente su mejor opción, ya que le da control completo sobre cómo ordenarle al control que formatee su texto
  3. Use un control de etiqueta de terceros que le permita insertar fragmentos de HTML (hay un montón - compruebe CodeProject); esta sería la implementación de alguien más de # 2.
1

Estaría interesado en saber si es posible.

Cuando no pudimos encontrar una solución, recurrimos al control SuperLabel de Component Ones, que permite el marcado HTML en una etiqueta.

14

No realmente, pero podría falsificarlo con un RichTextBox de solo lectura sin bordes. RichTextBox es compatible con el formato de texto enriquecido (rtf).

5
  1. Crear el texto como un archivo RTF en WordPad
  2. Crear control de texto enriquecido sin fronteras y editable = false
  3. Añadir el archivo RTF al proyecto como un recurso
  4. En el Form1_Load qué

    myRtfControl.Rtf = Resource1.MyRtfControlText

+0

¡Buen punto para el uso de wordpad! Pequeña complicación: genera gran cantidad de basura que hace que la comprensión de la RTF resultante sea un poco más difícil (pero se puede eliminar con seguridad) ... Mejor que leer la "especificación" rtf. – sharpener

+0

@sharpener Debería ver el rtf que produce MS Word ... simplemente abrirlo en Wordpad y presionar "guardar" lo reduce inmensamente, a veces incluso hasta un 10% del tamaño del archivo original. Y no, solo _wish_ Estaba bromeando o exagerando. X_x – Nyerguds

1

El re es un excelente artículo de 2009 sobre Code Project llamado "A Professional HTML Renderer You Will Use" que implementa algo similar a lo que desea el cartel original.

Lo uso con éxito en varios proyectos de nosotros.

0

Al darse cuenta de que esta es una vieja pregunta, mi respuesta es más para aquellos, como yo, que todavía pueden estar buscando soluciones y tropezar con esta pregunta.

Aparte de lo que ya se ha mencionado, DevExpress LabelControl es una etiqueta que admite este comportamiento - demo here. Por desgracia, es parte de una biblioteca paga.

Si está buscando soluciones gratuitas, creo que HTML Renderer es la siguiente mejor opción.

+0

Cuando usábamos los controles genéricos de DevExpress, solían tener muchos problemas con el tema. Al igual, es fácil hacer que usen algún tema queer, pero es difícil que se vean igual que el sistema operativo actual. – hypersw

2

solución muy simple:

  1. agregar 2 etiquetas en el formulario, y LABELA LabelB
  2. ir a las características de LABELA y acoplarla a la izquierda.
  3. Vaya a las propiedades de LabelB y acoplarlas también a la izquierda.
  4. Establezca la fuente en negrita para LabelA.

Ahora la etiqueta B cambiará dependiendo de la longitud del texto de LabelA.

Eso es todo.

9

Otra solución, tardía para la fiesta: si no quiere usar un control de terceros, y solo está buscando llamar la atención sobre parte del texto en su etiqueta, y está bien con subrayados, puede usar un LinkLabel.

Tenga en cuenta que muchos consideran esto como 'usability crime', pero si no está diseñando algo para el consumo del usuario final, puede ser algo que esté dispuesto a tener en su conciencia.

El truco consiste en agregar enlaces deshabilitados a las partes del texto que desea subrayar, y luego establecer globalmente los colores del enlace para que coincida con el resto de la etiqueta. Puede configurar casi todas las propiedades necesarias en tiempo de diseño, aparte de la pieza Links.Add(), pero aquí está en código:

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; 

Resultado:

enter image description here

+2

Oh, maravilloso. Nunca supe que las etiquetas de los enlaces podrían tener áreas específicas como enlaces. En realidad, esto está mucho más cerca del caso de uso que estaba buscando que la pregunta real hecha aquí; mi etiqueta se puede hacer clic de todos modos. Mucho mejor con solo un área clicable ahora. – Nyerguds

0

Un FlowLayoutPanel funciona bien para su problema . Si agrega etiquetas al panel de flujo y formatea las propiedades de margen y fuente de cada etiqueta, entonces puede tener diferentes estilos de fuente. Una solución bastante rápida y fácil para trabajar.

6

Solución trabajada para mí, utilizando RichEditBox personalizado. Con las propiedades correctas se verá como una simple etiqueta con soporte en negrita.

1) En primer lugar, añadir su clase RichTextLabel personalizado con discapacitados acento circunflejo:

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) de Split sentencio a palabras con bandera IsSelected, que determinan si esa palabra debe estar en negrita o no:

 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) Añadir función para convertir a usted el texto RTF válido (con soporte 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

funciona como un encanto para mí! Soluciones compilados a partir de:

How to convert a string to RTF in C#?

Format text in Rich Text Box

How to hide the caret in a RichTextBox?

+0

Esta es la mejor solución disponible si desea mantenerse lo más ligero posible y evitar dependencias de terceros. Probé varias alternativas y este método funciona mejor y también maneja .AutoSize y .WordWrap correctamente como una etiqueta normal. También construí una función simple de conversión de HTML a RTF que maneja sustituciones directas con las etiquetas básicas (negrita, cursiva, etc.) así que no necesito recordar el formato RTF. Solo cargo la cadena con formato HTML. –

2

AutoRichLabel

            AutoRichLabel with formatted RTF content

Me resolver este problema mediante la construcción de un UserControl que contiene una TransparentRichTextBox que es de sólo lectura. El TransparentRichTextBox es una RichTextBox que permite ser transparente:

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

Los finales UserControl actúa como envoltura de la TransparentRichTextBox. Desafortunadamente, tuve que limitarlo a AutoSize en mi propio camino, porque el AutoSize del RichTextBox se rompió.

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

La sintaxis del formato de texto enriquecido es bastante simple:

Párrafo:

{\pard This is a paragraph!\par} 

Negrita/Cursiva/subrayado texto:

\b bold text\b0 
\i italic text\i0 
\ul underline text\ul0 

color alternativo utilizando la tabla de colores:

{\colortbl ;\red0\green77\blue187;} 
{\pard The word \cf1 fish\cf0 is blue.\par 

Pero tenga en cuenta: Siempre envuelva cada texto de un párrafo. Además, se pueden apilar diferentes etiquetas (es decir, \pard\b\i Bold and Italic\i0\b0\par) y se ignora el carácter de espacio detrás de una etiqueta. Entonces, si necesita un espacio detrás de él, inserte dos espacios (es decir, \pard The word \bBOLD\0 is bold.\par). Para escapar \ o { o }, utilice un \ líder. Para obtener más información, hay un full specification of the rich text format online.

Usando esta sintaxis bastante simple puede producir algo como lo que puede ver en la primera imagen.El contenido de texto enriquecido que se adjuntó a la propiedad RtfContent de mi AutoRichLabel en la primera imagen fue:

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

Si desea habilitar el ajuste de línea, ajuste la anchura máxima de un tamaño deseado Sin embargo, esto arreglará el ancho hasta el ancho máximo, incluso cuando el texto sea más corto.

divertirse!

Cuestiones relacionadas