I created RichTextBox and I add this code:
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
//( )
int selectionStart = richTextBox1.SelectionStart;
string helpText = richTextBox1.Text;
int closerPos;
for (int i = 0; i < helpText.Length; i++)
{
if (helpText[i] == '(')
{
selectionStart = richTextBox1.SelectionStart;
closerPos = helpText.Substring(i).IndexOf(')') + i;
helpText = helpText.Substring(i + 1, closerPos - i - 1);
richTextBox1.Text = richTextBox1.Text.Remove(i + 1, closerPos - i - 1);
richTextBox1.Select(i + 1, 0);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.SelectedText = helpText;
richTextBox1.SelectionColor = Color.Black;
helpText = richTextBox1.Text;
richTextBox1.SelectionStart = selectionStart;
}
}
}
This code should color the text between the ( ).
For example:
"Hi (need to be colored) text (sdadsasd) "
the text between the ( ) need to be colored in red. but only the last text is colored. How can I fix it?
You're only getting the first paranthesis with that if condition.
Try splitting the text like helpText.Split('(');
Then iterate over it and do your logic.
I think you can accomplish this without moving byte by byte. You can try to do it using the IndexOf method.
This is something I was thinking of:
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
string rbText = richTextBox1.Text;
int position = 0;
int startBrace = rbText.IndexOf('(', position) + 1;
while (startBrace != -1)
{
position = rbText.IndexOf(')', startBrace);
if (position != -1)
{
richTextBox1.Select(startBrace, position - startBrace);
richTextBox1.SelectionColor = Color.Red;
startBrace = rbText.IndexOf('(', position) + 1;
}
else
break;
}
}
Keep in mind that I haven't fully test this code.
I already see a potential issue, helpText is being used as an array when it is only a single-variable string. Try breaking the entirety of helpText down into a char array, then iterating through that to find your brackets.
Related
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
if (results.Count > 0)
{
richTextBox1.SelectionStart = results[(int)numericUpDown1.Value - 1];
richTextBox1.ScrollToCaret();
richTextBox1.SelectionColor = Color.Red;
}
}
I want that when changing the numericUpDown it will color like highlight only the result :
results[(int)numericUpDown1.Value - 1]
Doing ForeColor is coloring all the text in the richTextBox.
I forgot to mention that before this I have a function that highlight specific text in the richTextBox :
void HighlightPhrase(RichTextBox box, string phrase, Color color)
{
int pos = box.SelectionStart;
string s = box.Text;
for (int ix = 0; ; )
{
int jx = s.IndexOf(phrase, ix, StringComparison.CurrentCultureIgnoreCase);
if (jx < 0)
{
break;
}
else
{
box.SelectionStart = jx;
box.SelectionLength = phrase.Length;
box.SelectionColor = color;
ix = jx + 1;
results.Add(jx);
}
}
box.SelectionStart = pos;
box.SelectionLength = 0;
}
And using it :
string word = textBox1.Text;
string[] test = word.Split(new string[] { ",," }, StringSplitOptions.None);
foreach (string myword in test)
{
HighlightPhrase(richTextBox1, myword, Color.Yellow);
label16.Text = results.Count.ToString();
label16.Visible = true;
if (results.Count > 0)
{
numericUpDown1.Maximum = results.Count;
numericUpDown1.Enabled = true;
richTextBox1.SelectionStart = results[(int)numericUpDown1.Value - 1];
richTextBox1.ScrollToCaret();
}
}
Color color = Color.red;
string result = "Result";
string nonColoredPart = "This is not colored";
string partialResultColored = "<color=#" + ColorUtility.ToHtmlStringRGBA(color) + ">" + result+ "</color>" + nonColoredPart;
And then assign the text to the place that accepts Rich Text.
Whenever you want to change the color / font / indentation / tabs etc of only part of the RichTextBox, first select the part that you want to change, then call one of the Selection... methods of the RichTextBox
RichTextBox richTextbox = ...
int startSelect = ...
int selectionLength = ...
richTextbox.Select(startSelect, selectionLength);
// color the selected part red.
richTextBox.SelectionColor = System.Drawing.Color.Red;
// if desired: change other properties of the selected part
System.Drawing.Font currentFont = richTextBox1.SelectionFont;
richTextBox1.SelectionFont = new Font(
currentFont.FontFamily,
currentFont.Size,
FontStyle.Bold);
Check the Select... properties of class RichTextBox
How can I color a line in the RichTextBox which begins with a #, so like a comment in python. I have this code but it should color only the line where the # is in it. My code colors everything after one # is written:
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
string text = richTextBox1.Text;
if (richTextBox1.Lines.Contains("#") == true)
{
int firstcharindex = richTextBox1.GetFirstCharIndexOfCurrentLine();
int currentline = richTextBox1.GetLineFromCharIndex(firstcharindex);
richTextBox1.Select(firstcharindex, 10);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.DeselectAll();
richTextBox1.Select(richTextBox1.Text.Length, 0);
}
}
You are missing the else condition, also do it for each line within TexBox like below
string text = richTextBox1.Text;
foreach (var line in richTextBox1.Lines)
{
if (line.Contains("#"))
{
int firstcharindex = richTextBox1.GetFirstCharIndexOfCurrentLine();
int currentline = richTextBox1.GetLineFromCharIndex(firstcharindex);
richTextBox1.Select(firstcharindex, 10);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.DeselectAll();
richTextBox1.Select(richTextBox1.Text.Length, 0);
}
else
{
int firstcharindex = richTextBox1.GetFirstCharIndexOfCurrentLine();
int currentline = richTextBox1.GetLineFromCharIndex(firstcharindex);
richTextBox1.Select(firstcharindex, 10);
richTextBox1.SelectionColor = Color.Black;
richTextBox1.DeselectAll();
richTextBox1.Select(richTextBox1.Text.Length, 0);
}
}
You have to specify the richTextBox1.SelectionLength. You have to set this to your line length.
Also see: Selectively coloring text in RichTextBox
How can I make, that when the user types specific words like 'while' or 'if' in a rich textbox, the words will color purple without any problems? I've tried diffrent codes, but none of them were usable. The codes were like below:
if (richTextBox.Text.Contains("while"))
{
richTextBox.Select(richTextBox.Text.IndexOf("while"), "while".Length);
richTextBox.SelectionColor = Color.Aqua;
}
Also, I want that when the user removes the word or removes a letter from the word, the word will color back to its default color. I'm making a program with a code editor in it.
I am using Visual c#.
Thank you.
Add an event to your rich box text changed,
private void Rchtxt_TextChanged(object sender, EventArgs e)
{
this.CheckKeyword("while", Color.Purple, 0);
this.CheckKeyword("if", Color.Green, 0);
}
private void CheckKeyword(string word, Color color, int startIndex)
{
if (this.Rchtxt.Text.Contains(word))
{
int index = -1;
int selectStart = this.Rchtxt.SelectionStart;
while ((index = this.Rchtxt.Text.IndexOf(word, (index + 1))) != -1)
{
this.Rchtxt.Select((index + startIndex), word.Length);
this.Rchtxt.SelectionColor = color;
this.Rchtxt.Select(selectStart, 0);
this.Rchtxt.SelectionColor = Color.Black;
}
}
}
This is something that you can do, I would recommend using a regular expression to find all matches of the word in case it occurs many times. Also keep in mind that the string find could be a list of strings out side of a for loop to consider multiple words but this should get you started.
//dont foget to use this at the top of the page
using System.Text.RegularExpressions;
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
string find = "while";
if (richTextBox1.Text.Contains(find))
{
var matchString = Regex.Escape(find);
foreach (Match match in Regex.Matches(richTextBox1.Text, matchString))
{
richTextBox1.Select(match.Index, find.Length);
richTextBox1.SelectionColor = Color.Aqua;
richTextBox1.Select(richTextBox1.TextLength, 0);
richTextBox1.SelectionColor = richTextBox1.ForeColor;
};
}
}
You can use richTextBox1_KeyDown event
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
String abc = this.richTextBox1.Text.Split(' ').Last();
if (abc == "while")
{
int stIndex = 0;
stIndex = richTextBox1.Find(abc, stIndex, RichTextBoxFinds.MatchCase);
richTextBox1.Select(stIndex, abc.Length);
richTextBox1.SelectionColor = Color.Aqua;
richTextBox1.Select(richTextBox1.TextLength, 0);
richTextBox1.SelectionColor = richTextBox1.ForeColor;
}
}
}
If instead of a word you want to highlight a regular expression, you can use this:
private void ColorizePattern(string pattern, Color color)
{
int selectStart = this.textBoxSrc.SelectionStart;
foreach (Match match in Regex.Matches(textBoxSrc.Text, pattern))
{
textBoxSrc.Select(match.Index, match.Length);
textBoxSrc.SelectionColor = color;
textBoxSrc.Select(selectStart, 0);
textBoxSrc.SelectionColor = textBoxSrc.ForeColor;
};
}
Related to this question:
Displaying tooltip on mouse hover of a text
How can I do the same thing on a keyword in the RichTextBox but not a link?
In RichTextBox I type:
Hello World, How are You?
I set hovering the word "World" for tooltip and when it hovers ToolTip will appear saying "this is world"!
But if it hovers out of the RichTextBox or in the word "World" itself, tooltip will disappear.
It's a little simple. You have to use the GetCharIndexFromPosition method of your RichTextBox to get the Char index under the Mouse Pointer, make some simple loops to find the whole word and then show it in a Tooltip popup normally. Here is the code:
string punctuations = " ,.;!?'\")]}\n";
//This saves your words with their corresponding definitions/details
Dictionary<string, string> dict = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
ToolTip tt = new ToolTip();
int k;
int lineBreakIndex = 60;
int textHeight;
//MouseMove event handler for your richTextBox1
private void richTextBox1_MouseMove(object sender, MouseEventArgs e){
if (richTextBox1.TextLength == 0) return;
Point lastCharPoint = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength - 1);
if (e.Y > textHeight || (e.Y >= lastCharPoint.Y && e.X > lastCharPoint.X + textHeight - lastCharPoint.Y))
{
tt.Hide(richTextBox1);
k = -1;
return;
}
int i = richTextBox1.GetCharIndexFromPosition(e.Location);
int m = i, n = i;
while (m>-1&&!punctuations.Contains(richTextBox1.Text[m])) m--;
m++;
while (n<richTextBox1.TextLength&&!punctuations.Contains(richTextBox1.Text[n])) n++;
if (n > m){
string word = richTextBox1.Text.Substring(m, n - m);
if (dict.ContainsKey(word)){
if (k != m){
tt.ToolTipTitle = word;
tt.Show(dict[word], richTextBox1, e.X, e.Y + 10);
k = m;
}
}
else{
tt.Hide(richTextBox1);
k = -1;
}
}
}
//This will get the entry text with lines broken.
private string GetEntryText(string key){
string s = dict[key];
int lastLineEnd = lineBreakIndex;
for (int i = lastLineEnd; i < s.Length; i += lineBreakIndex)
{
while (s[i] != ' '){
if (--i < 0) break;
}
i++;
s = s.Insert(i, "\n");
lastLineEnd = i+1;
}
return s;
}
//MouseLeave event handler for your richTextBox1
private void richTextBox1_MouseLeave(object sender, EventArgs e){
tt.Hide(richTextBox1);
k = -1;
}
//ContentsResized event handler for your richTextBox1
private void richTextBox1_ContentsResized(object sender, ContentsResizedEventArgs e)
{
textHeight = e.NewRectangle.Height;
}
//Here are some sample words with definitions:
dict.Add("world", "- World is a common name for the whole of human civilization, specifically human experience, history, or the human condition in general, worldwide, i.e. anywhere on Earth.");
dict.Add("geek", "- A person who is single-minded or accomplished in scientific or technical pursuits but is felt to be socially inept");
Specifically, what I'd like is to have a user right-click in a TextBox, figure out and save the index position within the text where the right-click occurred, and then later insert some text at that position once the user makes a choice from the context menu that pops up because of the right click.
The tricky part is getting the index position based on the coordinates of the right-click.
This is in Silverlight 4.
private int _insertPoint;
private void userNotification_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
// Move and open the context menu relative to its container.
contextMenu.HorizontalOffset = e.GetPosition(container).X;
contextMenu.VerticalOffset = e.GetPosition(container).Y;
contextMenu.IsOpen = true;
// Get the click coordinates relative to the TextBox.
int clickX = e.GetPosition(textBox).X;
int clickY = e.GetPosition(textBox).Y;
_insertPoint = ?; // Here's the problem.
}
private void SelectFieldToInsert(object sender, MouseButtonEventArgs e)
{
// Close the context menu.
contextMenu.IsOpen = false;
var item = sender as ListBoxItem;
textBox.Text = textBox.Text.Insert(_insertPoint, "<" + item.Content + ">");
}
The TextBox.SelectionStart property on a textbox should help you. From the link:
If there is no selection, the SelectionStart value gets or sets the location of the cursor.
How about:
// Get the click coordinates relative to the TextBox.
int clickX = (int)e.GetPosition(textBox).X;
int clickY = (int)e.GetPosition(textBox).Y;
int startPosition = 0;
double currentHeight = 0;
double calculatedHeight = 0;
int charIndex;
TextBlock tb = new TextBlock();
tb.Width = this.textBox.Width;
tb.FontFamily = this.textBox.FontFamily;
tb.FontSize = this.textBox.FontSize;
for (charIndex = 0; charIndex < this.textBox.Text.Length; charIndex++)
{
tb.Text = this.textBox.Text.Substring(startPosition, charIndex - startPosition + 1);
if (tb.ActualHeight > currentHeight)
{
if (currentHeight == 0)
{
currentHeight = tb.ActualHeight;
calculatedHeight = currentHeight;
}
else
{
startPosition = charIndex + 1;
charIndex++;
tb.Text = this.textBox.Text.Substring(startPosition, charIndex - startPosition + 1);
currentHeight = tb.ActualHeight;
calculatedHeight += currentHeight;
}
}
if (tb.ActualWidth > clickX && calculatedHeight > clickY) break;
}
_insertPoint = charIndex;
I won't lie and say it's elegant, but it appears to work reasonably well.