How to highliht specific word in richtextbox during writing? - c#

Basically I want to make an autocorrect for my language. I have a RichTextBox(name: MainText), where I write. during writing, the program should every word if it exists in a dictionary file. if not then change the specific word color to red.
It has a timer. after every second it gets the written text and puts the words to an str array, and reads correct words from dictionary.txt file and puts them in a list. during comparison of the strings, it never highlights the incorrect words and it has always indexOutOfRange errors. How to fix it?
Here is the timer tick void:
void CheckTimer_Tick(object sender, EventArgs e)
{
List<string> correct_words = File.ReadAllLines(DictPath).ToList();
string text = MainText.Text;
string[] Words = text.Split(' ', '.');
for (int i = 0; i < Words.Length; i++)
{
if (correct_words.Contains(Words[i])) { }
else
{
int index = 0;
String temp = MainText.Text;
MainText.Text = "";
MainText.Text = temp;
while (index < MainText.Text.LastIndexOf(Words[i]))
{
MainText.Find(Words[i], index, MainText.TextLength, RichTextBoxFinds.None);
MainText.SelectionColor = Color.Red;
index = MainText.Text.IndexOf(Words[i], index) + 1;
}
}
}
}
I also tried this void:
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;
box.SelectionStart = jx;
box.SelectionLength = phrase.Length;
box.SelectionColor = color;
ix = jx + 1;
}
box.SelectionStart = pos;
box.SelectionLength = 0;
box.ForeColor = Color.Black;
}
This worked if I gave it a specific string, but it couldn't recognize the phrase input from the dictionary and gave the indexOutOfRange error.

public Form1()
{
InitializeComponent();
}
private void textbox1_TextChanging(object sender, EventArgs e)
{
string[] words = textBox1.Text.Split(',');
foreach(string word in words)
{
int startindex = 0;
while(startindex < richTextBox1.TextLength)
{
int wordstartIndex = richTextBox1.Find(word, startindex, RichTextBoxFinds.None);
if (wordstartIndex != -1)
{
richTextBox1.SelectionStart = wordstartIndex;
richTextBox1.SelectionLength = word.Length;
richTextBox1.SelectionBackColor = Color.Yellow;
}
else
break;
startindex += wordstartIndex + word.Length;
}
}
}

For Clear Hightlight Use This Code
richTextBox1.SelectionStart = 0;
richTextBox1.SelectAll();
richTextBox1.SelectionBackColor = Color.White;

Related

How to use mutliple colors in same cell in excel with C#

I need to use multiple colors in one excel cell but the code below works only last condition.
I want like: grren-red-green-red-green-red
It works like: green-green-green-green-green-red
List<string> myTexts = new List<string>
{
"aaaaaaaaaaaaaaaaa", // green expected
"bbbbbbbbbbbbbbbbb", // red expected
"ccccccccccccccccc", // green expected
"ddddddddddddddddd", // red expected
"eeeeeeeeeeeeeeeee", // green expected
"fffffffffffffffff" // red expected
};
var startIndex = 1;
for (int i = 0; i < liste.Count; i++)
{
cell.Value2 += myTexts[i];
if (i%2 == 0)
{
cell.Characters(startIndex, myTexts[i].Length).Font.Color= Color.Green;
}
else
{
cell.Characters(startIndex, myTexts[i].Length).Font.Color = Color.Red;
}
startIndex += myTexts[i].Length;
}
it should work if you set the cell.value2 text outside the loop to the complete string and manipulate the style afterwards:
cell.Value2 = string.Join("", myTexts);
var startIndex = 1;
for (int i = 0; i < myTexts.Count; i++)
{
if (i % 2 == 0)
{
cell.Characters[startIndex, myTexts[i].Length].Font.Color = Color.Green;
}
else
{
cell.Characters[startIndex, myTexts[i].Length].Font.Color = Color.Red;
}
startIndex += myTexts[i].Length;
}

Count the string by words not char

I am working on this code in which it can identify the word listed below from the Web Browser. Those words will turn into asterisk once they are identified and will count how many words were replaced but it didn't work. Someone can help?
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Navigate(txbAdress.Text);
webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
IHTMLDocument2 doc2 = webBrowser1.Document.DomDocument as IHTMLDocument2;
StringBuilder html = new StringBuilder(doc2.body.outerHTML);
string query;
query = #"
select Word from ListWords
";
List<string> words = new List<string>();
DataSet ds;
DataRow drow;
ds = DatabaseConnection.Connection1(query);
int index, total;
total = ds.Tables[0].Rows.Count;
string current_word;
for (index = 0; index < total; index++ )
{
drow = ds.Tables[0].Rows[index];
current_word = drow.ItemArray.GetValue(0).ToString();
words.Add(current_word);
}
Console.WriteLine(query);
Console.WriteLine("array:" + words);
foreach (String key in words)
{
// String substitution = "<span style='background-color: rgb(255, 0, 0);'>" + key + "</span>";
int len = key.Length;
string replace = "";
for ( index = 0; index < len; index++)
{
replace += "*";
}
html.Replace(key, replace);
//count++;
}
//Console.WriteLine("Total number of words: " + count);
doc2.body.innerHTML = html.ToString();
}
Just count them before you replace them
Given
public int CountOccurrences(string source, string match)
{
var pos = 0;
var count = 0;
while ((pos < source.Length) && (pos = source.IndexOf(match, pos, StringComparison.Ordinal)) != -1)
{
count++;
pos += match.Length;
}
return count;
}
Example
var count = CountOccurrences(html,key);
html.Replace(key, substitution);

Change color of expressions that starts with '#'

I need to create a winform to color expressions that starts with '#' that the user wrote in a textbox (can be a richTextBox or some Infragistics tool, does't really matter, it just have to work).
Exemple:
nothing #expression nothingelse
the #expression must be colored
I've tried to split the string from the textbox by the spaces to identify the word, but I wasn't abble to replace it correctly. Now I'm learning about Regex and trying to apply it to my problem.
I'm using C# in Visual Studio Community 2017.
EDIT
I changed a little the code from here, trying to fit it into my problem. But the limiter doesnt work as it is suppouse to. I belive that it is happening becouse that the selection starts in the '#', but there can be a space before that, so the code doesn't work.
Here is the code as I'm using it:
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
int current = richTextBox1.SelectionStart;
for (int i = 0; i < richTextBox1.Lines.Length; i++)
{
string line = richTextBox1.Lines[i];
int index = line.IndexOf(' '), lineFirstIndex = line.IndexOf('#');
if (index != -1 && lineFirstIndex != -1)
{
richTextBox1.Select(lineFirstIndex, index);
richTextBox1.SelectionColor = Color.Red;
}
else
{
lineFirstIndex = richTextBox1.GetFirstCharIndexFromLine(i);
richTextBox1.Select(lineFirstIndex, line.Length);
richTextBox1.SelectionColor = Color.Empty;
}
}
richTextBox1.Select(current, 0);
}
You need to use Regex like this :
foreach (string result in Regex.Split(TextBox1, #" #\w+"))
{
//do stuff...
}
I got the result that I wished, but there is a little problem. If i erase something with BackSpace, the backcolor starts to highlight everything.
I belive that this is something of the SelectionBackColor propriety, becouse it doesn't happend when I'm using SelectionColor.
The code:
private void FindAt() //acha arrobas
{
for(int r = 0; r <= tam; r++)
{
for(int z = 0; z < (tam - r); z++)
{
if (z > 8) break;
String temp = text.Substring(r, z);
char aux = '\0';
if (lista.FindStringExact(temp) != -1)
{
if (tam > r + z) aux = text.ElementAt(r + z);
if ((r > 0 && text.ElementAt(r - 1) == '#') && aux == ' ')
{
atIndex[0, ctrlAt] = r-1; //salva posição inicial da variavel, incluindo o # (por isso o -1)
atIndex[1, ctrlAt] = z + 1; //salva comprimento da variavel, + 1 por causa do # (segundo argumento da substring)
ctrlAt++;
}
}
}
}
}
and the function to color the substring:
private void ColorAt() //colore variaveis
{
for (int a = 0; a < ctrlAt; a++)
{
if (atIndex[0, a] != -1)
{
richTextBox1.Select(atIndex[0, a], atIndex[1, a]);
richTextBox1.SelectionBackColor = Color.Green;
}
else richTextBox1.SelectionBackColor = Color.Empty;
}
}

Why im not getting the real current char i clicked/selected?

This is the code:
private void richTextBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (mouseisup == false)
{
textBox1.Text = "";
int positionToSearch = richTextBox1.GetCharIndexFromPosition(new Point(e.X, e.Y));
richTextBox1.SelectionStart = positionToSearch;
textBox1.Text = richTextBox1.Text.Substring(positionToSearch, 1);
previousChar = positionToSearch;
textBox2.Text = "";
mouseisup = true;//add this statement
}
else
{
currentChar = richTextBox1.GetCharIndexFromPosition(new Point(e.X, e.Y));
if (currentChar > previousChar + 2 || currentChar < previousChar - 2)
{
richTextBox1.SelectionStart = currentChar;
textBox2.Text = richTextBox1.Text.Substring(currentChar, 1);
button1.Enabled = true;
}
mouseisup = false;
}
}
}
private void richTextBox1_MouseUp(object sender, MouseEventArgs e)
{
if (textBox2.Text == "")
{
mouseisup = true;
button1.Enabled = false;
}
}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
string[] text = Parse_Text.ParseText(richTextBox1.Text, textBox1.Text, textBox2.Text);
for (int i = 0; i < text.Length; i++)
{
richTextBox2.Text = text[i];
}
}
I created for the test a text new text file and entered the text file:
"Daniel > is smaller >< then daniel or Daniel depend on the D > but < <>"
Then in the program first click was on the first D of the first Daniel the second click was on the second D of the second Daniel.
Then in the new class in parse_text in this code :
List<string> parsedText = new List<string>();
string[] entries = null;
int startIndex = text.IndexOf(startTag);
if (startIndex >= 0)
{
int endIndex = text.IndexOf(endTag, startIndex);
startIndex is 0 but also endIndex is 0. But endTag is the second D it shouldnt be index 0.
So thats i also a problem.
Your problem is that you take an IndexOf of the character which will indeed give you the first occurence.
To avoid that, use the position of the character instead of the actual character.
You already have that information available on the line:
currentChar = richTextBox1.GetCharIndexFromPosition(new Point(e.X, e.Y));
EDIT
You should change your Parse_Text method for use with positions instead of characters.
On the top of my head you should get somehting like:
public static string[] ParseText(string text, int startPos, int endPos)
{
List<string> parsedText = new List<string>();
string[] entries = null;
if (startPos >= 0 && endPos > startPos)
{
string images = text.Substring(startPos + 1, endPos - startPos - 1);
entries = images.Split(new[] { ',' });
for (var i = 0; i < entries.Length; i++)
{
entries[i] = entries[i].Replace("\"", "");
}
for (int i = 0; i < entries.Length; i++)
{
parsedText.Add(entries[i]);
}
}
return entries;
}
Obviously you should add some extra tests regarding the allowed parameters.
For example:
text cannot be string.Empty
startPos cannot be less then zero
endPos must be greater then startPos

Highlighting strings in richtextBox

I need to highlight all words in richtextBox that are listed in .xls file, here's a part of my code:
public void HighlightWords(RichTextBox rtb1, DataTable dtXLS)
{
for (int i = 0; i < dtXLS.Rows.Count; i++)
{
string[] wordsToRedact = new string[dtXLS.Rows.Count];
wordsToRedact[i] = dtXLS.Rows[i][0].ToString();
Regex test = new Regex(#"[\p{P}|\s](" + wordsToRedact[i] + #")[\p{P}|\s]", RegexOptions.Singleline | RegexOptions.Compiled);
MatchCollection matchlist = test.Matches(rtb1.Text);
if (matchlist.Count > 0)
{
for (int j = 0; j < matchlist.Count; j++)
{
WordsToRedact words = new WordsToRedact(matchlist[j]);
HighLighting highLight = new HighLighting();
highLight.Highlight_Words(rtb1, words);
}
}
}
}
class HighLighting
{
public void Highlight_Words(RichTextBox rtb, WordsToRedact e)
{
rtb.SelectionBackColor = Color.LightSkyBlue;
rtb.SelectionStart = e.index;
rtb.SelectionLength = e.length;
rtb.ScrollToCaret();
}
}
class WordsToRedact
{
public int index;
public int length;
public string value;
public WordsToRedact(Match m)
{
this.index = m.Groups[1].Index;
this.length = m.Groups[1].Length;
this.value = m.Groups[1].Value;
}
}
The problem is, it didn't highlight some of the words that also matches the regex. Some are highlighted but some are not. Accuracy is my problem, and I don't know where I am getting wrong.
I checked your code, there were some problems in it, i list them below :
first :
for (int i = 0; i < dtXLS.Rows.Count; i++)
{
string[] wordsToRedact = new string[dtXLS.Rows.Count];
...
is wrong, you should initialize your string array before the for loop otherwise it gets renewed in each loop iteration, do this :
string[] wordsToRedact = new string[listBox1.Items.Count];
for (int i = 0; i < dtXLS.Rows.Count; i++)
{
...
second : (your major problem)
you should color the selected part after it is selected not before, that is why your code does not select the last match, you should do this :
rtb.SelectionStart = e.index;
rtb.SelectionLength = e.length;
rtb.SelectionBackColor = Color.LightSkyBlue;
and Last : (with doubt)
I think but I am not sure that you should use index zero [0] not [1]
public WordsToRedact(Match m)
{
this.index = m.Groups[0].Index;
this.length = m.Groups[0].Length;
this.value = m.Groups[0].Value;
}
This will work:
Regex test = new Regex(#"\b(" + wordsToRedact[i] + #")\b",
RegexOptions.Singleline | RegexOptions.Compiled);
mahdi-tahsildari's answer did answer my problem! But in addition with his answer I want also to post the other option that I've tried that also fixed the issue.
I changed the HighLighting class to this codes:
class HighLighting
{
public void HighlightText(RichTextBox rtb, string word)
{
int s_start = rtb.SelectionStart, startIndex = 0, index;
while ((index = rtb.Text.IndexOf(word, startIndex)) != -1)
{
rtb.Select(index, word.Length);
rtb.SelectionBackColor = Color.Yellow;
startIndex = index + word.Length;
}
rtb.SelectionStart = s_start;
rtb.SelectionLength = 0;
rtb.SelectionColor = Color.Black;
rtb.ScrollToCaret();
}
}
and everything goes fine. this code and mahdi-tahsildari's answer did the same thing! Thanks for all your help! :))

Categories

Resources