richTextBox - add text and table - c#

i want to add formatted text and table to a richTextBox.
For this I use these codes:
Text:
richTextBox1.SelectionFont = new Font("Maiandra GD", 30, FontStyle.Bold);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.SelectionIndent = 0;
richTextBox1.AppendText("text text text");
And the table:
StringBuilder tableRtf = new StringBuilder();
tableRtf.Append(#"{\rtf1\fbidis\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}");
for (int j = 0; j <5; j++)
{
tableRtf.Append(#"\trowd");
tableRtf.Append(#"\cellx2500" + " ghhghgjghjghjhggjh");
tableRtf.Append(#"\intbl\cell");
tableRtf.Append(#"\cellx10000\intbl\cel");
tableRtf.Append(" " + "sdfsdfs" + #"\intbl\clmrg\cell\row");
}
tableRtf.Append(#"\pard");
tableRtf.Append(#"}");
richTextBox1.Rtf=tableRtf.ToString();
But the
richTextBox1.Rtf=tableRtf.ToString();
kills the previous contents.
How can I make compatible them?
It is not a duplicate because I want two thing:
1) add formatted text to richTextBox this way:
richTextBox1.SelectionFont = new Font("Maiandra GD", 30, FontStyle.Bold);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.AppendText("text text text");
It is well readable and I can modify easily.
2) And I want to add tables.
So the structure:
text text text text text
text text text text text
|TABLE|
text text text text text
text text text text text
text text text text text
|TABLE|
etc.
But I don't know how can I apply tables without losing previous contents?

What you need to do is to dissect the rtf codes into the headers and the bodies.
The table body starts with the loop and keeping the \par is surely a good idea.
But you must neither replace the old text nor simply append the body to the end.
Instead you need to insert it before the last curly! This is because that last curly marks the end of the whole rtf code and anything after it will be ignored!
This was simple.
For a full solution you also will want to combine the headers.
This is a lot more work and writing it all out would go beyond an SO answer.
But the basic principle is simple:
You need to understand the things your table header adds to the things already in the primal header.
The most common things are afont table and a color table.
So if you want to use one or more different fonts in the appended table you need to do this:
add them to the font table with a new font index, e.g. as \f1\fnil Consolas; after the previous semicolon.
use it by changing the loop to include the new font right after the first \intbl table-paragraph-formatting control word: \intbl\f2\fs24 ghhghgjghjghjhggjh.
repeat as needed if you want to use different fonts in the table.
add a cfNfont color selector, if you want to.
The same idea will also work for the color table. It doesn't have a explicit indexing, so order matters; all colors are appended, each with a semicolon at the end:
{\colortbl ;\red255\green0\blue0;\red25\green0\blue220;}
..adds a blue color to the red from the formatted text.
You see, this is work and takes some effort and preparations.
You can find the full rtf specs here.
Here is a screenshot of playing a little with the rtf..:
Note that the parts of table header was created by the control; you may want to use a dummy control for this or maybe you can figure out which parts you need and which are not necessary..
Update: Here is a 'appending rtf for dummies' version:
tableRtf.Append(#"{\fonttbl{\f0\fnil\fcharset0 Courier;}}");
for (int j = 0; j <5; j++)
{
tableRtf.Append(#"\trowd");
tableRtf.Append(#"\cellx2500" + " ghhghgjghjghjhggjh");
tableRtf.Append(#"\intbl\cell");
tableRtf.Append(#"\cellx10000\intbl\cel");
tableRtf.Append(" " + "sdfsdfs" + #"\intbl\clmrg\cell\row");
}
tableRtf.Append(#"\pard");
tableRtf.Append(#"}");
string rtf1 = richTextBox1.Rtf.Trim().TrimEnd('}');
string rtf2 = tableRtf.ToString();
richTextBox1.Rtf = rtf1 + rtf2;
Note that the font table inserted before the table body does work! But make sure not to add the rtf-start tag!!

Related

RTF Replace, wrong Colors [duplicate]

Cannot keep the highlighted effect I set in my RichTextBox on my text after removing content of a line in front of him.
No matter how much text I remove from the control it always removes the custom SelectionColor and SelectionBackColor I set to a text already contained in it.
Code of my Removal method:
private void btnRemove_Click(object sender, EventArgs e)
{
//Remove selected line from RichTextBox
richTextBox1.Text = richTextBox1.Text.Remove(richTextBox1.Text.Length - 1, 1);
//Remove all blank lines remaining after deletion
richTextBox1.Text = Regex.Replace(richTextBox1.Text, #"^\s*$(\n|\r|\r\n)", "", RegexOptions.Multiline);
}
The number of letters I want to remove here is 1 as the word "AND" is a simple image inserted by means of Clipboard Paste method.
You must never (read my lips: Never, never, never) change to Text or the Lines property of a RichtTextBox or else you will lose/mess up all previous formatting.
So you need to change this:
richTextBox1.Text = richTextBox1.Text.Remove(richTextBox1.Text.Length - 1, 1);
To this sequence:
First Select the part of the Text you want to change in some way:
richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
richTextBox1.SelectionLength = 1;
Now you can change it. To delete either use:
richTextBox1.SelectedText = "";
or
richTextBox1.Cut();
The latter version also will place the text in the clipboard; doing it it will keep the formatting of that portion and you could Paste it to some other place..
The same rules apply when you want to add or change any type of formatting:
First Select Then Modify
And, yes, this means that the second command will grow quite a bit, i.e. you will have to replace the RegEx.Replace by a loop :-(

Retain highlighted color of text after editing

Cannot keep the highlighted effect I set in my RichTextBox on my text after removing content of a line in front of him.
No matter how much text I remove from the control it always removes the custom SelectionColor and SelectionBackColor I set to a text already contained in it.
Code of my Removal method:
private void btnRemove_Click(object sender, EventArgs e)
{
//Remove selected line from RichTextBox
richTextBox1.Text = richTextBox1.Text.Remove(richTextBox1.Text.Length - 1, 1);
//Remove all blank lines remaining after deletion
richTextBox1.Text = Regex.Replace(richTextBox1.Text, #"^\s*$(\n|\r|\r\n)", "", RegexOptions.Multiline);
}
The number of letters I want to remove here is 1 as the word "AND" is a simple image inserted by means of Clipboard Paste method.
You must never (read my lips: Never, never, never) change to Text or the Lines property of a RichtTextBox or else you will lose/mess up all previous formatting.
So you need to change this:
richTextBox1.Text = richTextBox1.Text.Remove(richTextBox1.Text.Length - 1, 1);
To this sequence:
First Select the part of the Text you want to change in some way:
richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
richTextBox1.SelectionLength = 1;
Now you can change it. To delete either use:
richTextBox1.SelectedText = "";
or
richTextBox1.Cut();
The latter version also will place the text in the clipboard; doing it it will keep the formatting of that portion and you could Paste it to some other place..
The same rules apply when you want to add or change any type of formatting:
First Select Then Modify
And, yes, this means that the second command will grow quite a bit, i.e. you will have to replace the RegEx.Replace by a loop :-(

richTextBox proper tab setting

I have a list in my richTextBox and I want it to look better. I add the attributes one-by-one, of course from variables, but this is the concept:
richTextBox1.AppendText("attr1 - ");
richTextBox1.AppendText("some text\r\n");
richTextBox1.AppendText("attr2 - ");
richTextBox1.AppendText("some even longer text\r\n");
//etc...
This is how it looks like now:
atrr1 - some text
attr2 - some even longer
text
attr3 - some text
This is what I need:
atrr1 - some text
attr2 - some even longer
text
attr3 - some text
The wrapping should be automatic, I don't want horizontal scroll-bar in my tool. I wish I could share some code but unfortunately I couldn't find any way to solve this.
you can use stringbuilder to achieve your goal and write code formatted like a html table:
StringBuilder tableRtf = new StringBuilder();
tableRtf.Append(#"\trowd \trgraph \cellx1000 Content text of cell \cell\row\pard\par");
richTextBox1.Rtf = tableRtf.ToString();
so you can use it in a for loop
for (int i = 0; i < ROWS_NUMBER; i++)
{
//add cell with columns
}
\trowd --> start table
\trgraph --> start paragraph
\cellx1000 --> cell with width of 1000
refer this likn for documentation

C# Cursor/ Caret Not display when Append text in Richtextbox

I am new to Programming, i am making C# Windows Form Application were, on selecting Tree node, it append the text in Richtextbox:
Qs1: For me Caret is not displayed after selecting the tree Node.
Qs2: Make display like editor, where if word start with // ( Comment) should be in green color.
Thanks
if (treeView1.SelectedNode.Name == "Node1")
{
this.richTextBox1.SelectedText += " my text for Node1" + Environment.NewLine
richTextBox1.Focus();
}
else if (treeView1.SelectedNode.Name == "Node2")
{
this.richTextBox1.SelectedText += " my text for Node2" + Environment.NewLine
richTextBox1.Focus();
}
You're asking two questions related to RichTextBox. The preferred form on StackOverflow is one question per question. You'll probably get more responses with more focused questions.
That being said:
According to the documentation for the Select method:
The text box must have focus in order for the caret to be moved.
So you need to do that first.
In addition, as a general rule, you should never modify the pre-existing Text or SelectedText with += because this will clear away any and all RTF formatting on that text. Instead, to insert text, you should set the selection to the desired location, with length zero, and insert there. Thus:
public static void FocusAndAppendToSelectedText(this RichTextBox richTextBox, string text)
{
Action append = () =>
{
richTextBox.Focus();
var start = richTextBox.SelectionStart;
var length = richTextBox.SelectionLength;
var insertAt = start + length;
richTextBox.Select(insertAt, 0);
richTextBox.SelectedText = text;
};
if (richTextBox.InvokeRequired)
richTextBox.BeginInvoke(append);
else
append();
}
Also, you should use \n rather than Environment.Newline because the latter will get simplified into the former anyway.
A question like "[How to] Make display like editor, where if word start with // ( Comment) should be in green color" is very general. Try to break it down into discrete issues and ask questions for those you can't figure out yourself. To get you started, see this question here: highlight the '#' until line end in richtextbox. However, you may want to set the SelectionBackColor not the SelectionColor, depending on your precise UI requirements.

How can I insert hard newlines into text where the text wraps in a window?

This question started out with someone wanting to import every apparent 'line of text' in a Word document into a row in an Excel sheet, but I'm sure this is not possible without some development.
I would like to insert a newline (whatever that may be configured as) at every point that a string is wrapped to a new line when displayed in a window. How can I do that? I figure I would need to query the window and get an array of its text lines, then count characters in each line, and in the original string, insert a newline after the number of characters that are displayed for that line.
I do of course realise that changing the window size will invalidate all the work of this code I'm asking how to write, but that is not a relevant issue here.
USEFUL INFO:
I have found a solution to the original, Word to Excel export, problem. When you save a Word document as a text file, after you click Save on the Save dialogue, you are given another dialogue with an option for inserting line breaks.
What you can do is something like this:
int width = txtBox.width;
Graphics g = CreateGraphics();
SizeF size = g.MeasureString(myText, txtBox.Font);
if (size.Width > width)
{
int i = 0;
List<string> lines = new List<String>();
string str = "";
while (i<myText.Length)
{
str = str + myText.SubString(i,1);
int w = (int)(g.MeasureString(str, txtBox.Font).Width);
while (w<width && i<myText.Length)
{
i++;
str = str + myText.SubString(i,1);
}
str = str + '\n';
}
// str now contains your newline formatted string
return str;
}
return myText;
What you can do is get the width of the display control and the font it is using, then use GetTextMetrics to get a TEXTMETRIC struct that can be used to find out the width of each character. This is very involved as it takes into account all the different character profiles.
An easier way is to use GetTextExtentPoint32 which, given a string and the font properties, will return its width in pixels. So you can make a rough estimate as to where the line break would be, call this function on that substring, and insert a line break when the result of GetTextExtentPoint32 is just less than the width of the text control.
Cheers.

Categories

Resources