2009-12-18 22 views
82

Estoy intentando colorear partes de una cadena para anexarlas a un RichTextBox. Tengo una cadena construida a partir de diferentes cadenas.Color diferentes partes de una cadena RichTextBox

string temp = "[" + DateTime.Now.ToShortTimeString() + "] " + 
       userid + " " + message + Environment.NewLine; 

Así es como se vería el mensaje una vez que se haya construido.

[21:23] Usuario: mi mensaje aquí.

Quiero que todo, incluidos los corchetes [9:23] sea de un color, el "usuario" sea de otro color y el mensaje sea de otro color. Entonces me gustaría que la cadena se adjunte a mi RichTextBox.

¿Cómo puedo lograr esto?

+1

dupe? http://stackoverflow.com/questions/455713/selectively-coloring-text-in-richtextbox – abhilash

+0

Dupe, yes ... = P use search! –

+4

Hice la búsqueda y no encontré nada útil. – Fatal510

Respuesta

189

Aquí es un método de extensión que sobrecarga el método AppendText con un parámetro de color:

public static class RichTextBoxExtensions 
{ 
    public static void AppendText(this RichTextBox box, string text, Color color) 
    { 
     box.SelectionStart = box.TextLength; 
     box.SelectionLength = 0; 

     box.SelectionColor = color; 
     box.AppendText(text); 
     box.SelectionColor = box.ForeColor; 
    } 
} 

Y esta es la forma en que lo utilizaría:

var userid = "USER0001"; 
var message = "Access denied"; 
var box = new RichTextBox 
       { 
        Dock = DockStyle.Fill, 
        Font = new Font("Courier New", 10) 
       }; 

box.AppendText("[" + DateTime.Now.ToShortTimeString() + "]", Color.Red); 
box.AppendText(" "); 
box.AppendText(userid, Color.Green); 
box.AppendText(": "); 
box.AppendText(message, Color.Blue); 
box.AppendText(Environment.NewLine); 

new Form {Controls = {box}}.ShowDialog(); 

en cuenta que puede notar un poco de parpadeo si estás produciendo muchos mensajes. Consulte el artículo this C# Corner para obtener ideas sobre cómo reducir el parpadeo de RichTextBox.

+2

Tuve algunos problemas con esto. Utilicé en otro lugar 'box.Text + = mystring' y todos los colores desaparecieron. Cuando reemplacé esto con 'box.AppendText (mystring)', funcionó como un charme. – Natrium

+1

Tengo algunos problemas con el código, el color desaparece al agregar cadena en algún otro color. La única diferencia es que estoy asignando var box a un richtextbox previamente creado .... –

+0

¿Qué estoy haciendo mal ... "SelectionStart" es no es una propiedad de un RichTextBox (o no puedo acceder al menos)? Encontré "Selección" pero es una propiedad solo de obtención ... – 00jt

7

he ampliado el método con la fuente como un parámetro:

public static void AppendText(this RichTextBox box, string text, Color color, Font font) 
{ 
    box.SelectionStart = box.TextLength; 
    box.SelectionLength = 0; 

    box.SelectionColor = color; 
    box.SelectionFont = font; 
    box.AppendText(text); 
    box.SelectionColor = box.ForeColor; 
} 
0

Selección de texto como se ha dicho de alguien, la selección puede aparecer momentáneamente. En Windows Forms applications no hay otras soluciones para el problema, pero hoy encontré una manera incorrecta de trabajar: puedes poner PictureBox superpuesto al RichtextBox con la captura de pantalla de si, durante la selección y el cambio de color o fuente , haciéndolo después de reaparecer todo, cuando la operación está completa.

Código está aquí ...

//The PictureBox has to be invisible before this, at creation 
//tb variable is your RichTextBox 
//inputPreview variable is your PictureBox 
using (Graphics g = inputPreview.CreateGraphics()) 
{ 
    Point loc = tb.PointToScreen(new Point(0, 0)); 
    g.CopyFromScreen(loc, loc, tb.Size); 
    Point pt = tb.GetPositionFromCharIndex(tb.TextLength); 
    g.FillRectangle(new SolidBrush(Color.Red), new Rectangle(pt.X, 0, 100, tb.Height)); 
} 
inputPreview.Invalidate(); 
inputPreview.Show(); 
//Your code here (example: tb.Select(...); tb.SelectionColor = ...;) 
inputPreview.Hide(); 

mejor es utilizar WPF; esta solución no es perfecta, pero para Winform funciona.

3

Esta es la versión modificada que puse en mi código (estoy usando .Net 4.5) pero creo que debería funcionar en 4.0 también.

public void AppendText(string text, Color color, bool addNewLine = false) 
{ 
     box.SuspendLayout(); 
     box.SelectionColor = color; 
     box.AppendText(addNewLine 
      ? $"{text}{Environment.NewLine}" 
      : text); 
     box.ScrollToCaret(); 
     box.ResumeLayout(); 
} 

Diferencias con origin

  • posibilidad de añadir texto a una nueva línea o simplemente añadirlo
  • hay necesidad de cambiar la selección, que funciona de la misma
  • ScrollToCaret inserta a la fuerza autoscroll
  • agregado suspender/reanudar llamadas al diseño
0
private void Log(string s , Color? c = null) 
     { 
      richTextBox.SelectionStart = richTextBox.TextLength; 
      richTextBox.SelectionLength = 0; 
      richTextBox.SelectionColor = c ?? Color.Black; 
      richTextBox.AppendText((richTextBox.Lines.Count() == 0 ? "" : Environment.NewLine) + DateTime.Now + "\t" + s); 
      richTextBox.SelectionColor = Color.Black; 

     } 
0

Creo que modificar un "texto seleccionado" en un RichTextBox no es la forma correcta de agregar texto de color. Así que aquí un método para añadir un "color block":

 Run run = new Run("This is my text"); 
     run.Foreground = new SolidColorBrush(Colors.Red); // My Color 
     Paragraph paragraph = new Paragraph(run); 
     MyRichTextBlock.Document.Blocks.Add(paragraph); 

De MSDN:

Los Bloques propiedad es la propiedad de contenido de RichTextBox. Es una colección de elementos de párrafo . Contenido en cada elemento de párrafo puede contener los siguientes elementos:

  • Inline

  • InlineUIContainer

  • Run

  • Span

  • Negrita

  • hipervínculo

  • cursiva

  • Subrayado

  • LineBreak

Así que creo que hay que dividir la cadena dependiendo del color partes, y crear tantos Run objetos según sea necesario.

Cuestiones relacionadas