I got a code for line numbering, it works perfectly fine for numbering lines the regular way but I'm looking for something a little bit different. I want my code to only count line breaks when i press enter(the program receives an return keycode) and not then the textbox automatically cut the lines with word wrapping. This is the code i'm using right now:
//Instructions
int maxLC = 1; //maxLineCount - should be public
private void InstructionsSyncTextBox_KeyUp(object sender, KeyEventArgs e)
{
int linecount = InstructionsSyncTextBox.GetLineFromCharIndex(InstructionsSyncTextBox.TextLength) + 1;
if (linecount != maxLC)
{
InstructionsLineNumberSyncTextBox.Clear();
for (int i = 1; i < linecount + 1; i++)
{
InstructionsLineNumberSyncTextBox.AppendText(Convert.ToString(i) + "\n");
}
maxLC = linecount;
}
}
How i think i would be done easiest is by saving the line count every time someone presses enter to a list and also everytime someone presses enter it updates the line number texbox with every line number at positions said in list. But i have no idea how to detect when an return is removed. Anybody knows how to solve this?
Extremely basic example that counts the lines in your code you posted:
class Program
{
static void Main(string[] args)
{
string stringFromTextBox =
#" int maxLC = 1; //maxLineCount - should be public
private void InstructionsSyncTextBox_KeyUp(object sender, KeyEventArgs e)
{
int linecount = InstructionsSyncTextBox.GetLineFromCharIndex(InstructionsSyncTextBox.TextLength) + 1;
if (linecount != maxLC)
{
InstructionsLineNumberSyncTextBox.Clear();
for (int i = 1; i < linecount + 1; i++)
{
InstructionsLineNumberSyncTextBox.AppendText(Convert.ToString(i) + ""\n"");
}
maxLC = linecount;
}
}";
Regex r = new Regex("\r", RegexOptions.Multiline);
int lines = r.Matches(stringFromTextBox).Count;
//You'll need to run this line every time the user presses a key
}
}
Related
My Professor gave us this question
Write a method called Drawline that accepts as input an integer n and generates a line of output in lstOutput with n hyphens. That is, if n = 5 we have a line of ‘-----‘ displayed in the list box.
Basically he wants me to type a number in a text box and when i click the button it should display that many hyphens in a list box. Using visual Studio C# WindowsFormApp.
Here's my code:
private void btn3_Click(object sender, EventArgs e)
{
double n;
Drawline(out n);
}
private void Drawline(out double n)
{
n = double.Parse(textBox1.Text);
string strline = "";
for (n = 1; n <= 5; n++);
strline += '-';
lstOutput.Items.Add(String.Format(strline, n));
}
It works but no matter what number i put in the text box only one hyphen shows up. Can anyone help me?
The problem is with your for loop in DrawLine method.
You need to remove the semi-colon at the end of the for statement, so the strLine += '-'; will belong to the loop, not just be executed once.
private void Drawline(out double n)
{
n = double.Parse(textBox1.Text);
string strline = "";
for (i = 1; i <= 5; i++)
strline += '-';
lstOutput.Items.Add(String.Format(strline, n));
}
It appears you may be making this more complicated than it has to be.
It is unclear “why” the DrawLine method returns a double value using the out property? Is this a requirement? If it is not a requirement, then it is unnecessary.
Also, as per the requirement… ”Write a method called Drawline that accepts as input an integer n” … if this is the requirement, I have to ask why is the method accepting a double value? This would not fit with the requirement.
Below is a simplified version and should fit your requirements. First in the button click event, we want to get the integer value from the text box. We need to assume the user typed in a value that is NOT a valid integer. If the value is NOT a valid integer greater than zero (0), then we will display a message box indicating such.
private void button1_Click(object sender, EventArgs e) {
if ((int.TryParse(textBox1.Text, out int value)) && value > 0) {
Drawline(value);
}
else {
MessageBox.Show("String is not a number or is less than 1 : " + textBox1.Text);
}
}
Next the DrawLine method that simply adds a string of “-“ character(s) to the list box. Note the passed-in/accepted value of n has already been verified as a valid integer number greater than 0.
private void Drawline(int n) {
lstOutput.Items.Add(new string('-', n));
}
If you MUST use a for loop to generate the string, it may look something like…
private void Drawline(int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.Append("-");
}
lstOutput.Items.Add(sb.ToString());
}
I am trying to set the position of caret in richtextbox based on index position of a word. Even though I am able to change the caret position, the caret does not move to the correct location.
Here is my sample code:
private void Button_Click(object sender, RoutedEventArgs e)
{
RTB_Main.Document.Blocks.Clear();
for (int i = 0; i < 10; i++)
{
Paragraph para = new Paragraph(new Run(i + ""));
RTB_Main.Document.Blocks.Add(para);
}
TextRange richText = new TextRange(RTB_Main.Document.ContentStart, RTB_Main.Document.ContentEnd);
string searchText = tb_Search.Text; // 1 to 9
int position = Regex.Match(richText.Text, searchText).Index;
RTB_Main.CaretPosition = RTB_Main.Document.ContentStart;
RTB_Main.CaretPosition = RTB_Main.CaretPosition.GetPositionAtOffset(position);
RTB_Main.Focus();
}
What is wrong with this approach?
Also, Please let me know if there is a better way to set the caret position to an index?
The problem in my case was caused by new line characters \r\n. I just replaced these with another characters and it worked for me. Note that I am replacing them with not 2 characters but 4.
private void Button_Click(object sender, RoutedEventArgs e)
{
RTB_Main.Document.Blocks.Clear();
for (int i = 0; i < 10; i++)
{
Paragraph para = new Paragraph(new Run(i + ""));
RTB_Main.Document.Blocks.Add(para);
}
TextRange richText = new TextRange(RTB_Main.Document.ContentStart, RTB_Main.Document.ContentEnd);
string searchText = tb_Search.Text; // 1 to 9
string tmpStr = richText.Text.Replace("\r\n", "....");
int position = Regex.Match(tmpStr, searchText).Index;
RTB_Main.CaretPosition = RTB_Main.Document.ContentStart;
RTB_Main.CaretPosition = RTB_Main.CaretPosition.GetPositionAtOffset(position);
RTB_Main.Focus();
}
As Maciek noted, there are invisible formatting items that affects the count. My code adds a feedback loop because we are able to ask what the true caret position is. It feels hacky but I could not find anything better.
public static void SetCaretPositionOfRichTextBoxToCharIndex(
System.Windows.Controls.RichTextBox box, int charIndex)
{
// RichTextBox contains many formattings, and they, although invisible, count
// when setting CaretPosition. Calling GetPositionAtOffset with charIndex from
// DocumentStart can be less than the necessary CaretPosition. This code
// therefore has a feedback loop to see how much more offset is necessary.
box.CaretPosition = box.CaretPosition.DocumentStart;
int attemptedCharIndex = 0;
int fixerInc = 0;
while (attemptedCharIndex < charIndex)
{
box.CaretPosition = box.CaretPosition.GetPositionAtOffset(charIndex - attemptedCharIndex + fixerInc);
int temp = new TextRange(box.Document.ContentStart, box.CaretPosition).Text.Length;
if (attemptedCharIndex == temp)
{
fixerInc++;
}
else
{
fixerInc = 0
}
attemptedCharIndex = temp;
}
}
So basically I have a button that takes the strings delimited by line breaks in one text box that then formats them a particular way and puts them in a different text box. Everything looks fine when I run the code, however, when I copy and paste the text from the second textbox to a different place, it adds a line break after everything that I took from the original box.
private void ToTableButton_Click(object sender, EventArgs e)
{
StringBuilder tableText = new StringBuilder();
string[] lines = BasicTextBox.Text.Split('\n');
TableTextBox.Clear();
try
{
for (int i = 0; i < columnsUpDown.Value; i++)
{
if (i == columnsUpDown.Value - 1)
{
tableText.Append(lines[i]);
}
else
{
tableText.Append(lines[i] + " | ");
}
}
tableText.Append(Environment.NewLine);
for (int i = 0; i < columnsUpDown.Value; i++)
{
if (i == columnsUpDown.Value - 1)
{
tableText.Append("--");
}
else
{
tableText.Append("--|");
}
}
int currentPos = Convert.ToInt32(columnsUpDown.Value);
while (currentPos <= lines.Length)
{
tableText.Append(Environment.NewLine);
for (int i = 0; i < columnsUpDown.Value; i++)
{
if (i == columnsUpDown.Value - 1)
{
tableText.Append(lines[currentPos]);
}
else
{
tableText.Append(lines[currentPos] + " | ");
}
currentPos++;
}
}
}
catch
{
}
TableTextBox.Text = tableText.ToString();
}
I thought maybe this be because the split doesn't remove the \n but I wasn't sure how to remove it afterwards. Any advice would be greatly appreciated.
I would think that trimming the lines[currentPos] would be the correct way...
tableText.Append(lines[currentPos].ToString().Trim());
I have a problem while trying to replace all text matching a particular word in a rich text box. This is the code i use
public static void ReplaceAll(RichTextBox myRtb, string word, string replacer)
{
int index = 0;
while (index < myRtb.Text.LastIndexOf(word))
{
int location = myRtb.Find(word, index, RichTextBoxFinds.None);
myRtb.Select(location, word.Length);
myRtb.SelectedText = replacer;
index++;
}
MessageBox.Show(index.ToString());
}
private void btnReplaceAll_Click(object sender, EventArgs e)
{
Form1 text = (Form1)Application.OpenForms["Form1"];
ReplaceAll(text.Current, txtFind2.Text, txtReplace.Text);
}
This works well but i have noticed a little malfunction when i try to replace a letter with itself and another letter.
For example i want to replace all the e in Welcome to Nigeria with ea.
This is what i get Weaalcomeaaaaaaa to Nigeaaaaaaaaaaaaaaria.
And the message box shows 23 when there are only three e. Pls what am i doing wrong and how can i correct it
Simply do this:
yourRichTextBox.Text = yourRichTextBox.Text.Replace("e","ea");
If you want to report the number of matches (which are replaced), you can try using Regex like this:
MessageBox.Show(Regex.Matches(yourRichTextBox.Text, "e").Count.ToString());
UPDATE
Of course, using the method above has expensive cost in memory, you can use some loop in combination with Regex to achieve some kind of advanced replacing engine like this:
public void ReplaceAll(RichTextBox myRtb, string word, string replacement){
int i = 0;
int n = 0;
int a = replacement.Length - word.Length;
foreach(Match m in Regex.Matches(myRtb.Text, word)){
myRtb.Select(m.Index + i, word.Length);
i += a;
myRtb.SelectedText = replacement;
n++;
}
MessageBox.Show("Replaced " + n + " matches!");
}
I'm in trouble, today I tried to color some diffents words in differents lines clicked on a button. Can You explain me how to do this? I was able to do only this:
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.Select(int start , int length); //It's wrong but It explains How to use .Select if you know start and length...
richTextBox1.SelectionColor = Color.Blue;
}
But how can I work on a line I know the number of, having already the text into the RichTextBox?
Thanks.
If lines are separated by \n, your problem is then to count the number of \n characters before getting to the wanted line.
For that, you can use an extension method:
public static int NthIndexOf(this String str, String match, int occurence) {
int i = 1;
int index = 0;
while (i <= occurence && ( index = str.IndexOf(match, index + 1) ) != -1) {
if (i == occurence) {
// Occurence match found!
return index;
}
i++;
}
// Match not found
return -1;
}
Now, you can find start and end values to color the selection:
private void button1_Click(object sender, EventArgs e) {
int lineNb = 13; // I assume you get this value initialized somewhere,
// I wrote 13 for the example
int start = richTextBox1.Text.NthIndexOf("\n", lineNb);
int length = richTextBox1.Text.NthIndexOf("\n", lineNb + 1);
richTextBox1.Select(start , length);
richTextBox1.SelectionColor = Color.Blue;
}