In my RichtextBox, if I have written as below.
This is my pen,
his pen is beautiful.
Now I search word "is" then
output would be as below.
All "is" should be highlighted.
What about:
static class Utility {
public static void HighlightText(this RichTextBox myRtb, string word, Color color) {
if (word == string.Empty)
return;
int s_start = myRtb.SelectionStart, startIndex = 0, index;
while((index = myRtb.Text.IndexOf(word, startIndex)) != -1) {
myRtb.Select(index, word.Length);
myRtb.SelectionColor = color;
startIndex = index + word.Length;
}
myRtb.SelectionStart = s_start;
myRtb.SelectionLength = 0;
myRtb.SelectionColor = Color.Black;
}
}
Looks like this would do it.
http://www.dotnetcurry.com/ShowArticle.aspx?ID=146
int start = 0;
int indexOfSearchText = 0;
private void btnFind_Click(object sender, EventArgs e)
{
int startindex = 0;
if(txtSearch.Text.Length > 0)
startindex = FindMyText(txtSearch.Text.Trim(), start, rtb.Text.Length);
// If string was found in the RichTextBox, highlight it
if (startindex >= 0)
{
// Set the highlight color as red
rtb.SelectionColor = Color.Red;
// Find the end index. End Index = number of characters in textbox
int endindex = txtSearch.Text.Length;
// Highlight the search string
rtb.Select(startindex, endindex);
// mark the start position after the position of
// last search string
start = startindex + endindex;
}
}
public int FindMyText(string txtToSearch, int searchStart, int searchEnd)
{
// Unselect the previously searched string
if (searchStart > 0 && searchEnd > 0 && indexOfSearchText >= 0)
{
rtb.Undo();
}
// Set the return value to -1 by default.
int retVal = -1;
// A valid starting index should be specified.
// if indexOfSearchText = -1, the end of search
if (searchStart >= 0 && indexOfSearchText >=0)
{
// A valid ending index
if (searchEnd > searchStart || searchEnd == -1)
{
// Find the position of search string in RichTextBox
indexOfSearchText = rtb.Find(txtToSearch, searchStart, searchEnd, RichTextBoxFinds.None);
// Determine whether the text was found in richTextBox1.
if (indexOfSearchText != -1)
{
// Return the index to the specified search text.
retVal = indexOfSearchText;
}
}
}
return retVal;
}
// Reset the richtextbox when user changes the search string
private void textBox1_TextChanged(object sender, EventArgs e)
{
start = 0;
indexOfSearchText = 0;
}
This will show all the searched criteria at the same time.
Using: 1 Textbox (to enter the text to search for) and 1 Button (to Run the Search).
Enter your search criteria inside the textbox and press search button.
// On Search Button Click: RichTextBox ("rtb") will display all the words inside the document
private void btn_Search_Click(object sender, EventArgs e)
{
try
{
if (rtb.Text != string.Empty)
{// if the ritchtextbox is not empty; highlight the search criteria
int index = 0;
String temp = rtb.Text;
rtb.Text = "";
rtb.Text = temp;
while (index < rtb.Text.LastIndexOf(txt_Search.Text))
{
rtb.Find(txt_Search.Text, index, rtb.TextLength, RichTextBoxFinds.None);
rtb.SelectionBackColor = Color.Yellow;
index = rtb.Text.IndexOf(txt_Search.Text, index) + 1;
rtb.Select();
}
}
}
catch (Exception ex) { MessageBox.Show(ex.Message, "Error"); }
}
}
}
If you only want to match the whole word you can use this, note that this ignores case and also the |s\b means that plurals get highlighted e.g. Cat matches cats but not caterpiller :
public static void HighlightText(RichTextBox myRtb, string word, Color color)
{
if (word == string.Empty)
return;
var reg = new Regex(#"\b" + word + #"(\b|s\b)",RegexOptions.IgnoreCase);
foreach (Match match in reg.Matches(myRtb.Text))
{
myRtb.Select(match.Index, match.Length);
myRtb.SelectionColor = color;
}
myRtb.SelectionLength = 0;
myRtb.SelectionColor = Color.Black;
}
private void button3_Click(object sender, EventArgs e)
{
if (textBox1.Text != "")
{
for (int i = 0; i < richTextBox1.TextLength; i++)
{
richTextBox1.Find(textBox1.Text, i, RichTextBoxFinds.None);
richTextBox1.SelectionBackColor = Color.Red;
}
}
else
{
for (int i = 0; i < richTextBox1.TextLength; i++)
{
richTextBox1.SelectAll();
richTextBox1.SelectionBackColor = Color.White;
}
}
}[lets make it!][1]
I would do it like that because all the other answers highlight the text, but doesnt change it back after you searched again.
Use the RichText Find Method to find the starting index for the searching word.
public int FindMyText(string searchText, int searchStart, int searchEnd)
{
int returnValue = -1;
if (searchText.Length > 0 && searchStart >= 0)
{
if (searchEnd > searchStart || searchEnd == -1)
{
int indexToText = richTextBox1.Find(searchText, searchStart, searchEnd, RichTextBoxFinds.MatchCase);
if (indexToText >= 0)
{
returnValue = indexToText;
}
}
}
return returnValue;
}
Use a Button or TextChangeListener and Search for your word.
private void button1_Click(object sender, EventArgs e)
{
// Select the first char in your Richtextbox
richTextBox1.SelectionStart = 0;
richTextBox1.SelectionLength = richTextBox1.TextLength;
// Select until the end
richTextBox1.SelectionColor = Color.Black;
// Make the Text Color black
//Use an Inputfield to add the searching word
var word = txtSearch.Text;
//verify the minimum length otherwise it may freeze if you dont have text inside
if (word.Length > 3)
{
int s_start = richTextBox1.SelectionStart, startIndex = 0, index;
while ((index = FindMyText(word, startIndex, richTextBox1.TextLength)) != -1)
{
// goes through all possible found words and color them blue (starting index to end)
richTextBox1.Select(index, word.Length);
richTextBox1.SelectionColor = Color.Blue;
startIndex = index + word.Length;
}
// Color everything between in color black to highlight only found words
richTextBox1.SelectionStart = startIndex;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectionColor = Color.Black;
}
}
I would highly recommend to set a minimum word length to avoid freezing and high memory allocation.
I was wondering how I would make a picture box become invisible or visible when a certain integer matches.
My program revolves around 2 players going around a board, and when they add there 2 Di up, they will move the amount of spaces.
My problem being, My friend and I have no idea what is wrong with the current code we have, it throws no errors which baffles him, especially myself.
I've made it so my program add's the Di up on every roll, and add's it to the integer.
Anyone have any idea's on whats wrong? If not, a better approach?
Code
private void SelectPos(PictureBox pic)
{
PictureBox[] numbers = { P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, P1_32, P1_33, P1_34, P1_35, P1_36, P1_37, P1_38, P1_39, P1_40, P1_41, P1_42, P1_43, P1_44, P1_45, P1_46, P1_47, P1_48, P1_49 };
for (int i = 0; i < numbers.Length; i++)
{
if (pic == numbers[i])
{
numbers[i].Visible = true;
MessageBox.Show("k");
}
{
numbers[i].Visible = false;
MessageBox.Show("l");
}
}
}
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
Roll();
System.Threading.Thread.Sleep(100);
Roll2();
Goes_Num.Text = (int.Parse(Goes_Num.Text) + 1).ToString();
if (Convert.ToInt32(Goes_Num.Text) % 2 == 0)
{
WhichPlayer.Text = "Player 2";
P2_Number.Text = (int.Parse(P2_Number.Text) + 1).ToString();
int p2Int = Convert.ToInt32(P2_Pos.Text);
P2_Pos.Text = (p2Int + dice + dice2).ToString();
}
else if (Convert.ToInt32(Goes_Num.Text) % 2 != 0)
{
WhichPlayer.Text = "Player 1";
P1_Number.Text = (int.Parse(P1_Number.Text) + 1).ToString();
int p1Int = Convert.ToInt32(P1_Pos.Text);
P1_Pos.Text = (p1Int + dice + dice2).ToString();
int P1 = (Convert.ToInt32(P1_Pos.Text));
SelectPos(P1_1);
/*switch (P1)
{
case 1:
P1_1.Visible = true;
break;
case 2:
P1_2.Visible = true;
break;
}*/
/*String[] hi = { "1", "2" };
for (int i = 0; i < hi.Length; i++)
{
var visible = p1
if(visible == hi[i])
{
hi[i].Visible = true;
}
else
{
hi[i].Visible = false;
}
}*/
}
}
(P1-1 all the way to P1-49 are images)
Thanks,
James
It looks like you're trying to pass an int to your SelectPos function but it expects a PictureBox. You could fix this doing something similar to the following:
private void SelectPos(int pic)
{
PictureBox[] numbers = { P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, P1_32, P1_33, P1_34, P1_35, P1_36, P1_37, P1_38, P1_39, P1_40, P1_41, P1_42, P1_43, P1_44, P1_45, P1_46, P1_47, P1_48, P1_49 };
//Set all picture boxes to be not visible
for (int i = 0; i < numbers.Length; i++)
{
numbers[i].Visible = false;
}
//Set the picture at the given index to visible
numbers[pic].Visible = true;
}
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
Roll();
System.Threading.Thread.Sleep(100);
Roll2();
Goes_Num.Text = (int.Parse(Goes_Num.Text) + 1).ToString();
if (Convert.ToInt32(Goes_Num.Text) % 2 == 0)
{
WhichPlayer.Text = "Player 2";
P2_Number.Text = (int.Parse(P2_Number.Text) + 1).ToString();
int p2Int = Convert.ToInt32(P2_Pos.Text);
P2_Pos.Text = (p2Int + dice + dice2).ToString();
}
else if (Convert.ToInt32(Goes_Num.Text) % 2 != 0)
{
WhichPlayer.Text = "Player 1";
P1_Number.Text = (int.Parse(P1_Number.Text) + 1).ToString();
int p1Int = Convert.ToInt32(P1_Pos.Text);
P1_Pos.Text = (p1Int + dice + dice2).ToString();
int P1 = (Convert.ToInt32(P1_Pos.Text));
SelectPos(P1);
}
}
You may have to manipulate the value of pic so that it is within the bounds of the array (0-48). For example if pic is between 1 and 49 you would need to subtract 1: numbers[pic-1]. Without seeing your whole program I can't tell you exactly how that part of the code would look but it should be pretty easy to figure out. If you aren't familiar with arrays and indexing check out this link or just Google C# Arrays.
As a side note it would be better to the numbers array as a private member of the class this code is in. Unless the values in the array change there's no point in building the array every time the method is called.
Complete code:
private void SelectPos(int pic)
{
PictureBox[] numbers = { P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, P1_32, P1_33, P1_34, P1_35, P1_36, P1_37, P1_38, P1_39, P1_40, P1_41, P1_42, P1_43, P1_44, P1_45, P1_46, P1_47, P1_48, P1_49 };
//Set all picture boxes to be not visible
for (int i = 0; i < numbers.Length; i++)
{
numbers[i].Visible = false;
}
//Set the picture at the given index to visible
numbers[pic].Visible = true;
}
private void SelectPos2(int pic2)
{
PictureBox[] numbers2 = { P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31, P2_32, P2_33, P2_34, P2_35, P2_36, P2_37, P2_38, P2_39, P2_40, P2_41, P2_42, P2_43, P2_44, P2_45, P2_46, P2_47, P2_48, P2_49 };
//Set all picture boxes to be not visible
for (int i = 0; i < numbers2.Length; i++)
{
numbers2[i].Visible = false;
}
//Set the picture at the given index to visible
numbers2[pic2].Visible = true;
}
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
Roll();
System.Threading.Thread.Sleep(100);
Roll2();
Goes_Num.Text = (int.Parse(Goes_Num.Text) + 1).ToString();
if (Convert.ToInt32(Goes_Num.Text) % 2 == 0)
{
WhichPlayer.Text = "Player 2";
P2_Number.Text = (int.Parse(P2_Number.Text) + 1).ToString();
int p2Int = Convert.ToInt32(P2_Pos.Text);
P2_Pos.Text = (p2Int + dice + dice2).ToString();
int P2 = (Convert.ToInt32(P2_Pos.Text));
SelectPos2(P2);
}
else if (Convert.ToInt32(Goes_Num.Text) % 2 != 0)
{
WhichPlayer.Text = "Player 1";
P1_Number.Text = (int.Parse(P1_Number.Text) + 1).ToString();
int p1Int = Convert.ToInt32(P1_Pos.Text);
P1_Pos.Text = (p1Int + dice + dice2).ToString();
int P1 = (Convert.ToInt32(P1_Pos.Text));
SelectPos(P1);
}
}
I'm trying to add numbered list functionality to a text editor. RichTextbox already provides the SelectionBullet property to change a selection to a bulleted list. But i was unable to find a similar property to generate numbered list. Is there any standard way to create a numbered list on Richtextbox. If not, i would have to implement it myself so code snips that could help me do that will help, Thank you.
I know that a link is not gernerally accepted as a good answer, however the article RichTextBox with Search Line Numbering, Bulleting, Printing, Searching Support on CodeProject could probably help you out quite a bit with what you are looking for.
In this article, the author extends the RichTextBox control into something that can do what you are asking (and more), plus the code is posted there for all to see.
Well, i implemented it as follows.
private void btnNumbers_Click(object sender, EventArgs e)
{
string temptext = rtbMain.SelectedText;
int SelectionStart = rtbMain.SelectionStart;
int SelectionLength = rtbMain.SelectionLength;
rtbMain.SelectionStart = rtbMain.GetFirstCharIndexOfCurrentLine();
rtbMain.SelectionLength = 0;
rtbMain.SelectedText = "1. ";
int j = 2;
for( int i = SelectionStart; i < SelectionStart + SelectionLength; i++)
if (rtbMain.Text[i] == '\n')
{
rtbMain.SelectionStart = i + 1;
rtbMain.SelectionLength = 0;
rtbMain.SelectedText = j.ToString() + ". ";
j++;
SelectionLength += 3;
}
}
private void rtbMain_KeyDown(object sender, KeyEventArgs e)
{//this piece of code automatically increments the bulleted list when user //presses Enter key
int tempNum;
if (e.KeyCode == Keys.Enter)
try
{
if (char.IsDigit(rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine()]))
{
if (char.IsDigit(rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 1]) && rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 2] == '.')
tempNum = int.Parse(rtbMain.Text.Substring(rtbMain.GetFirstCharIndexOfCurrentLine(),2));
else tempNum = int.Parse(rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine()].ToString());
if (rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 1] == '.' || (char.IsDigit(rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 1]) && rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 2] == '.'))
{
tempNum++;
rtbMain.SelectedText = "\r\n" + tempNum.ToString() + ". ";
e.SuppressKeyPress = true;
}
}
}
catch{}
}
Here is my answer... which is easily readable and refineable. I took a much different approach but added the ability to remove the numbered list within the selection if it already exists. Please note that so far I have only lightly tested it and it seems to work good... but it may need further refinement.
private void btnOrdered_Click(object sender, EventArgs e)
{
string[] splitSelection = null;
// If selection split selection else split everything
if (this.txtCaptionEditor.SelectionLength > 0)
{
splitSelection = this.txtCaptionEditor.SelectedText.Replace("\r\n", "\n").Split("\n".ToCharArray());
}
else
{
splitSelection = this.txtCaptionEditor.Text.Replace("\r\n", "\n").Split("\n".ToCharArray());
}
bool Exists = false;
for (int i = 0; i < splitSelection.GetLength(0); i++)
{
// If Ordered List Allready exists in selection then remove else add
if (!string.IsNullOrEmpty(splitSelection[i]))
{
if (splitSelection[i].Substring(0, 2) == "1.") { Exists = true; }
}
}
for (int i = 0; i < splitSelection.GetLength(0); i++)
{
int lineCount = (i + 1);
if (Exists)
{
this.txtCaptionEditor.Text = this.txtCaptionEditor.Text.Replace(Convert.ToString(lineCount) + ". ", "");
}
else
{
if(!string.IsNullOrEmpty(splitSelection[i]))
{
this.txtCaptionEditor.Text = this.txtCaptionEditor.Text.Replace(splitSelection[i], Convert.ToString(lineCount) + ". " + splitSelection[i]);
}
}
}
}
private void txtCaptionEditor_KeyDown(object sender, KeyEventArgs e)
{
string[] splitSelection = this.txtCaptionEditor.Text.Replace("\r\n", "\n").Split("\n".ToCharArray());
if (e.KeyCode == Keys.Enter)
{
// Get Current Line Position
int currentLine = this.txtCaptionEditor.GetLineFromCharIndex(this.txtCaptionEditor.SelectionStart);
// Only Run if the previous line is greater than zero
if ((currentLine) >= 0)
{
// Loop through 100 possible numbers for match you can go higher
// If you think your numbered list could go above 100
for (int i = 0; i < 100; i++)
{
if (splitSelection[(currentLine)].Substring(0, 2) == Convert.ToString((i + 1)) + ".")
{
// If the substring of the current line equals a numbered list value.. enumerate next line
this.txtCaptionEditor.SelectedText = "\n" + (i + 2) + ". ";
e.SuppressKeyPress = true;
}
}
}
}
}