I have used a richtextbox to display logs in my WinForms.
Language used is C#.
The software is used for inserting data of Bank Branches and after start of new Branch I want to display a text with new color.
I have seen the link Color different parts of a RichTextBox string and implemeted it successfully.
My problem is I want to prepend the new line instead of append. That is the new line will be displayed on top.
I am able to do this by changing the code to box.Text=DateTime.Now.ToString("dd-MM-yyyy-hh-mm-ss") + ": " + text + box.Text
But the color is changing for the entire text.
This is the procedure used for append
box.SelectionStart = box.TextLength;
box.SelectionLength = 0;
box.SelectionColor = color;
box.AppendText(DateTime.Now.ToString("dd-MM-yyyy-hh-mm-ss") + ": " + text);
box.SelectionColor = box.ForeColor;
This is what I have done:
box.Text=DateTime.Now.ToString("dd-MM-yyyy-hh-mm-ss") + ": " + text + box.text;
box.SelectionStart = 0;
box.SelectionLength = text.length;
box.SelectionColor = color;
But this is not working.
1) Never directly change the Text property of an already formatted RichtTextBox
2) To append use the RTB.AppendText function
3) To insert at any other position p, including the beginning use this:
rtb.SelectionStart = s; // set the cursor to the target position
rtb.Selection.Length = 0; // nothing selected, yet
rtb.SelectedText = yourNewText; // this inserts the new text
Now you can add the formatting you want:
rtb.SelectionStart = s; // now we prepare the new formatting..
rtb.SelectionLength = yourNewText.Length; //.. by selecting the text
rtb.SelectionColor = Color.Blue; // and/or whatever you want to do..
...
// Prepend, normal on first line, rest of lines gray italic
private void PrependToRichTextbox(RichTextBox rt, string msg)
{
rt.SelectionStart = 0;
rt.SelectionLength = 0;
rt.SelectedText = msg + Environment.NewLine;
int linecount = 0;
foreach (var line in rt.Lines)
{
rt.Select(rt.GetFirstCharIndexFromLine(linecount), line.Length);
rt.SelectionColor = linecount == 0 ? Color.Black : Color.Gray;
Font currentFont = rt.SelectionFont;
FontStyle newFontStyle;
newFontStyle = linecount == 0 ? FontStyle.Regular : FontStyle.Italic;
rt.SelectionFont = new Font(
currentFont.FontFamily,
currentFont.Size,
newFontStyle
);
linecount++;
}
}
Related
This is the code I use to draw rectangles from the RichTexbox text:
try
{
pictureBox1.Image = null;
bm = new Bitmap(OrgPic.Width, OrgPic.Height);
//Location
string spli1 = ScriptBox.Text; var p = spli1.Split('(', ')')[1];
string spli2 = (p.ToString().Split(',', ',')[1]);
string source = spli2;
string loc_1 = string.Concat(source.Where(c => !char.IsWhiteSpace(c)));
string[] coords = loc_1.Split('.');
Point lp = new Point(int.Parse(coords[0]), int.Parse(coords[1])); ;
Console_.Text += $"This Lines {ScriptBox.LinesCount}";
Console_.Text += "\n" + "split1: " + spli1.ToString();
Console_.Text += "\n" + "split2: " + loc_1.ToString();
Console_.Text += "\n" + "cords: " + coords.ToString();
Console_.Text += "\n" + "lp_Point: " + lp.ToString();
//Color
string color = ScriptBox.Text; var r = Color.FromName(color.Split('(', ',')[1]);
string colors = (r.ToString().Split('.', ']')[1]);
Console_.Text += "\n" + "Color final:" + colors.ToString();
Console_.Text += "\n" + "Color Sin split:" + r.ToString();
Color f = Color.FromName(colors);
Pen pen = new Pen(f);
pen.Width = 4;
gF = Graphics.FromImage(bm);
gF.DrawRectangle(pen, lp.X, lp.Y, 100, 60);
pictureBox1.Image = bm;
}
catch (Exception)
{
}
I basically search for the word Rect.Draw followed by the color. [selected color] and the coordinates in which to place the rectangle.
The problem is that when I go through the entire RichTexbox for the functions, it only draws the rectangle once, I don't know if I can explain myself. Example
Code 1:
Rect.Draw (color.red, 90.5)
this draws the red rectangle in its respective position
Code 2:
Rect.Draw (color.red, 90.5)
Rect.Draw (color.green, 100.5)
the code 2 it does not draw two rectangles. only respect the first and if i delete the first, the second being the only one will have priority.
Apparent solution: I would like to know how I can read RichTexbox line by line and treat each line as separate text. thus draw each rectangle procedurally.
First, RichTextBox has a string[] Lines property that you can use.
Also, this seems like a case basically begging to use regular expression (regex). Going by your code and the use of string magic you probably haven't heard of it before but regex is used for parsing strings and extracting information based on patterns. That is to say, pretty much exactly what you're trying to do here.
using System.Text.RegularExpressions;
partial class Form1 : Form
{
Regex rectRegex = null;
private void ProcessRtf()
{
//init regex once.
if(rectRegex == null)
rectRegex = new Regex("Rect\.Draw\s*\(color\.(?<COL>[A-Za-z]+),\s+(?<POS>\d+(\.\d+)?)\)");
foreach(string line in ScriptBox.Lines)
{
//for example: line = "Rect.Draw(color.red, 90.5)"
var match = rectRegex.Match(line);
if(match.Success)
{
string col = match.Groups["COL"].Value; //col = "red"
string pos = match.Groups["POS"].Value; //pos = "90.5"
//draw your rectangle
break; //abort foreach loop.
}
}
}
}
I'm trying to format a RichTextBox object with the following code:
public static void MessageString(RichTextBox textBox, MessageModel model)
{
//textBox.SelectionFont = new Font("Consolas", 8.25F, FontStyle.Regular, GraphicsUnit.Point, 0);
var message = new StringBuilder();
// date
message.Append(DateTimeString(model.RequestTime));
message.Append(" - ");
int start = textBox.Text.Length;
int length = message.Length - 1;
textBox.Text = string.Concat(textBox.Text, message.ToString());
textBox.DeselectAll();
textBox.Select(start, length);
textBox.SelectionColor = Color.LightGray;
textBox.PerformLayout();
// reset
message = new StringBuilder();
// time and user
message.Append(UserString(model.User));
message.Append(" wrote:");
message.Append(Environment.NewLine);
start = textBox.Text.Length;
length = message.Length - 1;
textBox.Text = string.Concat(textBox.Text, message.ToString());
textBox.DeselectAll();
textBox.Select(start, length);
textBox.SelectionColor = Color.Gray;
// reset
message = new StringBuilder();
// body
message.Append(model.Text);
message.Append(Environment.NewLine);
message.Append(Environment.NewLine);
start = textBox.Text.Length;
length = message.Length - 1;
textBox.Text = string.Concat(textBox.Text, message.ToString());
textBox.DeselectAll();
textBox.Select(start, length);
textBox.SelectionColor = Color.DarkBlue;
}
The problem is now, that the all text is formated with LightGray and only the body part os DarkBlue. The time and user part is also LightGray.
If i run this as part of a iteration list with more then one MessageModel, the whole textbox will be LightGray and only the last body part DarkBlue.
Actually i could not see the problem (forest, trees , u know). Each part should only select itself and formating it.
Could anyone help me?
Try replacing these lines
textBox.Text = string.Concat(textBox.Text, message.ToString());
with
textBox.AppendText(message.ToString());
i'm trying to format text that i'm inserting at the beginning of a new email when a user presses a button in the ribbon add-in
the code is simple in that it first checks if the type of text was previously inserted, removes it if it was, and then inserts a new bracket of text using Word.Range.InsertBefore(.....);
the text will be:
CLASSIFICATION: .......
CLASSIFICATION: .......
the problem that i am running into is after the insert i'm formatting the font using Range.Font,Text etc...
i need the CLASSIFICATION: ...... formatted and not the space between them
the space between the "CLASSIFICATION......" is being formatted when typing begins to the same size, color, etc.... as the "CLASSIFICATION"
the code i'm using is:
private void setClassificationText(string classificationText, Word.WdColorIndex color)
{
//current mail item document
Word.Document document = (Word.Document)mailItem.GetInspector.WordEditor;
Word.Range rng = document.Paragraphs[1].Range;
//check if a classification level was already supplied
if (checkIfClassificationExists(rng))
{
//get the first 2 Paragraphs and remove the text from them
int paraCount = 2;
for (int i = 1; i <= paraCount; i++)
{
Word.Range classificationRange = document.Paragraphs[i].Range;
removeTextFromParagraph(classificationRange);
}
rng.Collapse();
rng = document.Paragraphs[1].Range;
}
rng.InsertBefore(classificationText + CT.lineFeedStr5 + CT.classification + classificationText + CT.lineFeedStr3);
//sets the color and text
rng.Font.ColorIndex = color;
rng.Text = CT.classification + rng.Text;
rng.Font.Bold = 1;
}
private void removeTextFromParagraph(Word.Range rng)
{
int wordCount = rng.Words.Count;
rng.Delete(Count: wordCount);
}
solved the issue i was having.
i used the following:
private void setClassificationText(string classificationText, Word.WdColorIndex color)
{
//current mail item document
Word.Document document = (Word.Document)mailItem.GetInspector.WordEditor;
Word.Range rng = document.Paragraphs[1].Range;
//check if a classification level was already supplied
if (checkIfClassificationExists(rng))
{
//get the first 2 Paragraphs and remove the text from them
int paraCount = 2;
for (int i = 1; i <= paraCount; i++)
{
Word.Range classificationRange = document.Paragraphs[i].Range;
removeTextFromParagraph(classificationRange);
}
rng.Collapse();
rng = document.Paragraphs[1].Range;
}
//insert the text
rng.InsertBefore(classificationText + CT.lineFeedStr5 + CT.classification + classificationText);
//sets the color and text
rng.Font.ColorIndex = color;
rng.Text = CT.classification + rng.Text;
rng.Font.Bold = 1;
//get the beginning and ending positions of the blank space
startPosition = rng.Start + getClassificationLength(classificationText);
endPosition = (int)startPosition + CT.lineFeedStr5.Length-1;
//get the Word.Range for the blank space
Word.Range rngNormal = document.Range(ref startPosition, endPosition);
//set blank space to be normal font (not bold and black)
rngNormal.Bold = 0;
rngNormal.Font.ColorIndex = Word.WdColorIndex.wdBlack;
}
private int getClassificationLength(string classificationText)
{
int returnValue = 0;
returnValue = CT.classification.Length + classificationText.Length;
return returnValue;
}
hope this can help someone else out.
After 2 years I just returned to do a few things with MigraDoc & PDFsharp.
To make life easier I have created a helper function for styles and I wonder why this doesn't work as expected?
All font assignments work just fine: Font family, size and type as well as colors come out right. Also the links get created and they work, too.
But all paragraph styles are ignored. They are assigned to the new styles, as I can see in the debugger, but they are not rendered.
It is probably a rule about paragraphs and sections, which I don't know.
Can somebody enlighten me?
// all styles by name/definition
public string allStyles = "";
private string style(string styleName)
{
if (allStyles.IndexOf(" " + styleName + " ") < 0) // the stylename is new, so we create it..
{
string style = styleName + " ";
string fontChar = style[0].ToString();
string fs = "";
if (style[1] >= '0' & style[1] <= '9') fs += style.Substring(1, 1);
if (style[2] >= '0' & style[2] <= '9') fs += style.Substring(2, 1);
if (style[3] >= '0' & style[3] <= '9') fs += style.Substring(3, 1);
int fontSize = Convert.ToInt32(fs);
// now digits after position 2 may be ignored
// we use the rest of the stylename for the rest of the style details..
string styleName2 = styleName.Substring(1);
// add base style to the document style cache
Style newStyle = document.AddStyle(styleName, "Normal");
// now we modify the new style..:
newStyle.Font.Bold = styleName.IndexOf("B") >= 0;
newStyle.Font.Italic = styleName.IndexOf("I") >= 0;
if (fontChar == "A") newStyle.Font.Name = "Arial";
// .. 25 more fonts omitted..
// ..
if (styleName.IndexOf("a") >= 0) newStyle.Font.Color = MigraDoc.DocumentObjectModel.Colors.AntiqueWhite;
// .. 25 more colors omitted..
// ..
// .. here a a few ParagraphFormat styles, all of which don't work!!
if (styleName2.IndexOf("L") >= 0) newStyle.ParagraphFormat.Alignment = ParagraphAlignment.Left;
else if (styleName2.IndexOf("R") >= 0) newStyle.ParagraphFormat.Alignment = ParagraphAlignment.Right;
else if (styleName2.IndexOf("C") >= 0) newStyle.ParagraphFormat.Alignment = ParagraphAlignment.Center;
else if (styleName2.IndexOf("J") >= 0) newStyle.ParagraphFormat.Alignment = ParagraphAlignment.Justify;
if (styleName2.IndexOf("____") >= 0) newStyle.ParagraphFormat.SpaceAfter = 15;
else if (styleName2.IndexOf("___") >= 0) newStyle.ParagraphFormat.SpaceAfter = 10;
else if (styleName2.IndexOf("__") >= 0) newStyle.ParagraphFormat.SpaceAfter = 6;
else if (styleName2.IndexOf("_") >= 0) newStyle.ParagraphFormat.SpaceAfter = 3;
// add stylename to the collection string
allStyles += " " + styleName + " ";
}
// return the name after creating and modifying the style
return styleName;
// a plain FT output function
public void writeFT(Section currentSection, string text, string styl, bool newParagraph)
{
Paragraph currentParagraph;
if (newParagraph) currentParagraph = currentSection.AddParagraph();
else currentParagraph = currentSection.LastParagraph;
currentParagraph.AddFormattedText(text, style(styl));
}
// an function to output a hyperlink
public void writeLink(Section currentSection, string text, string link, string styl, bool newParagraph)
{
Paragraph currentParagraph;
if (newParagraph) currentParagraph = currentSection.AddParagraph();
else currentParagraph = currentSection.LastParagraph;
Hyperlink HL = currentParagraph.AddHyperlink(link, HyperlinkType.Bookmark);
HL.AddFormattedText(text, style(styl));
}
// and one for anchors
public void writeAnchor(Section currentSection, string text, string anchor, string styl, bool newParagraph)
{
Paragraph currentParagraph;
if (newParagraph ) currentParagraph = currentSection.AddParagraph();
else currentParagraph = currentSection.LastParagraph;
currentParagraph.AddFormattedText( text, style(styl));
currentParagraph.AddBookmark(anchor);
}
// an example call
writeFT(somesection, "This should be BIG & BLUE ", "A16b",true);
writeFT(somesection, "This should be BIG & RED ", "A16r",true);
writeFT(somesection, "GREEN but not spaced out", "A16g---___",true);
writeFT(somesection, "This should be BIG & BLACK", "A16k",true);
writeFT(somesection, "This should be BIG & BLUE ", "A16b",true);
writeFT(somesection, "This should be BIG & BLUE ", "A16b",true);
To set Paragraph styles, just use currentParagraph.Style = style(styl);. You can add text using AddText() instead of AddFormattedText() if you want to use that style for the paragraph (and you can still call AddFormattedText() to add text with a different character format).
AddFormattedText only supports character formats (not paragraph formats). Logical as it is part of a paragraph.
Your API should take that into account.
I am developing a windows form application using C#.Net. In part of my code I defined a function to log system events. Here is the body of this function:
richTextBoxLog.Text += "-";
richTextBoxLog.Text += some logs and strings ...;
richTextBoxLog.Text += "." + new string(' ', 1000) + Environment.NewLine;
richTextBoxLog.Select(richTextBoxLog.GetFirstCharIndexFromLine(logCounter), richTextBoxLog.Lines[logCounter].Length);
richTextBoxLog.SelectionBackColor = (logCounter % 2 == 0) ? Color.LightBlue: Color.LightGray;
logCounter++;
richTextBoxLog.ScrollToCaret();
the initial value of logCounter is zero (the line of first event refers to logCounter=0). For odd lines the back color should be Color.LightGray and for even lines it should be Color.LightBlue. However as you can see below it does not change the back color properly.
Each time this function is called (to add new text line) the region of richTextBoxLog.Select is updated according to the new line's start and end indices. But when an even line is added to the text box the back color of all of the previous lines turn into blue (even color).
I appreciate your help in advance.
Documentation http://msdn.microsoft.com/en-us/library/system.windows.forms.richtextbox.selectionbackcolor.aspx states:
Characters that are entered from that position have the specified SelectionBackColor.
Which seems likely to cause your issues. Although I still can't see how it influences previously added text.
Anyways, you can solve it by repainting all line colors when you add text:
richTextBoxLog.Text += "-";
richTextBoxLog.Text += some logs and strings ...;
richTextBoxLog.Text += "." + new string(' ', 1000) + Environment.NewLine;
var lineCount = 0;
foreach (var line in richTextBoxLog.Lines) {
richTextBoxLog.Select(richTextBoxLog.GetFirstCharIndexFromLine(lineCount), line.Length);
richTextBoxLog.SelectionBackColor = (lineCount % 2 == 0) ? Color.LightBlue : Color.LightGray;
lineCount++;
}
richTextBoxLog.ScrollToCaret();
It should be Helpfull:
public void AppendText(string text, Color color,Color backColor)
{
richTextBox1.SelectionStart = richTextBox1.TextLength;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectionColor = color;
richTextBox1.AppendText(text);
richTextBox1.SelectionColor = richTextBox1.ForeColor;
richTextBox1.SelectionBackColor = backColor;
richTextBox1.ScrollToCaret();
}