Limit line length in multiline textbox - c#

I need to limit the number of characters on a single line that a user can enter into a multiline textbox. I have a function that can do that for data typed in, but not for data cut and pasted in.
I've tried reading the textbox into an array, using substring, and copying back to the text string, but this code (posted) throws an exception.
private void LongLine_TextChanged(object sender, TextChangedEventArgs e)
{
int lineCount =
((System.Windows.Controls.TextBox)sender).LineCount;
//string newText = "";
for (int i = 0; i < lineCount; i++)
{
if
(((System.Windows.Controls.TextBox)sender).GetLineLength(i) > 20)
{
string textString = ((System.Windows.Controls.TextBox)sender).Text;
string[] textArray = Regex.Split(textString, "\r\n");
textString = "";
for (int k =0; k < textArray.Length; k++)
{
String textSubstring = textArray[k].Substring(0, 20);
textString += textSubstring;
}
((System.Windows.Controls.TextBox)sender).Text = textString;
}
}
e.Handled = true;
}

This does what you seem to be asking for:
It truncates the end of any line that is longer than 20 as you type and when you paste or otherwise change the text.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
const int MAX_LINE_LENGTH = 20;
var textbox = sender as TextBox;
var exceedsLength = false;
// First test if we need to modify the text
for (int i = 0; i < textbox.LineCount; i++)
{
if (textbox.GetLineLength(i) > MAX_LINE_LENGTH)
{
exceedsLength = true;
break;
}
}
if (exceedsLength)
{
// Split the text into lines
string[] oldTextArray = textbox.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
var newTextLines = new List<string>(textbox.LineCount);
for (int k = 0; k < oldTextArray.Length; k++)
{
// truncate each line
newTextLines.Add(string.Concat(oldTextArray[k].Take(MAX_LINE_LENGTH)));
}
// Save the cursor position
var cursorPos = textbox.SelectionStart;
// To avoid the text change calling back into this event, detach the event while setting the Text property
textbox.TextChanged -= TextBox_TextChanged;
// Set the new text
textbox.Text = string.Join(Environment.NewLine, newTextLines);
textbox.TextChanged += TextBox_TextChanged;
// Restore the cursor position
textbox.SelectionStart = cursorPos;
// if at the end of the line, the position will advance automatically to the next line, supress that
if (textbox.SelectionStart != cursorPos)
{
textbox.SelectionStart = cursorPos - 1;
}
}
e.Handled = true;
}

Related

Is it possible to write into a RichTextBox at a given line, column?

I have a WinForm with a RichTextBox.
I am trying to write into the RichTextBox at a given line and column:
Here is the code:
public Form1()
{
InitializeComponent();
richTextBox1 = new RichTextBoxWithMouseSelectionFixed();
richTextBox1.Location = new System.Drawing.Point(62, 46);
richTextBox1.Name = "richTextBox1";
richTextBox1.Size = new System.Drawing.Size(461, 391);
richTextBox1.TabIndex = 0;
richTextBox1.Text = "";
richTextBox1.HideSelection = false;
Controls.Add(richTextBox1);
int line = 3;
int column = 5;
GoToLineAndColumn(richTextBox1, line, column);
}
private RichTextBoxWithMouseSelectionFixed richTextBox1;
private void GoToLineAndColumn(RichTextBox richTextBox1, int line, int column)
{
int offset = 0;
for (int i = 0; i < line - 1 && i < richTextBox1.Lines.Length; i++)
{
offset += richTextBox1.Lines[i].Length + 1;
}
richTextBox1.Focus();
richTextBox1.Select(offset + column, 0);
}
I tryed to write with:
richTextBox1.AppendText("currentWord");
and also with:
richTextBox1.Text = "currentWord";
but in both cases the currentWord is written in the first line at column 0.
public Form1()
{
InitializeComponent();
int line = 6;
int column = 30;
RichTextBox richTextBox1 = new RichTextBox();
richTextBox1.Location = new System.Drawing.Point(62, 46);
richTextBox1.Name = "richTextBox1";
richTextBox1.Size = new System.Drawing.Size(461, 391);
richTextBox1.TabIndex = 0;
richTextBox1.Text = "";
richTextBox1.HideSelection = false;
Controls.Add(richTextBox1);
for (int i = 0; i < line - 1; i++)
richTextBox1.Text += "\n";
for (int i = 0; i < column - 1; i++)
richTextBox1.Text += " ";
richTextBox1.Text += "Just Text";
}
The RichTextBox class has properties you can use to write text to a specific index in it. first you define the zero based index of the line and column you would like to write to and then you get the index of the first character in that line like below
// define the index of the line and the column of the line you want to write to in the rich text box
int lineIndex = 2;
// zero-based index of the line
int columnIndex = 10;
// Get the index of the first character in that line you specified above
int index = richTextBox.GetFirstCharIndexFromLine(lineIndex) + columnIndex;
//declare the string you wish to paste
string mytext = "Write to this section only";
//Use the SelectionStart and SelectionLength properties to write the text
richTextBox.SelectionStart = index;
richTextBox.SelectionLength = mytext.Length;
// clear any previous selection
richTextBox.SelectedText = mytext;
The only solution I found is by adding empty lines before the text and blank characters before the text:
private void WriteAtLineAndColumn(RichTextBox richTextBox1, string text, int line, int column)
{
// Insert blank lines at the beginning of the RichTextBox.
for (int i = 0; i < line - 1; i++)
{
richTextBox1.AppendText(Environment.NewLine);
}
int index = richTextBox1.GetFirstCharIndexFromLine(line - 1);
richTextBox1.Select(index, 0);
string spaces = new string(' ', column);
richTextBox1.SelectedText = spaces + "This is a sample text";
// Insert the text at the desired position.
richTextBox1.Select(richTextBox1.GetFirstCharIndexFromLine(line - 1) + column, 0);
richTextBox1.SelectedText = text;
}

Do not count the white space in the text box

I have written a program that calculates the number of characters in a word entered in the text box, but I do not want to count the number of whitespaces.
What code should I write? For example, when Max is written inside the text box, the number of letters is 3 and 3 appears in other textbox, then if whitespace is used in textbox, the number of letters remains the same as 3 and does not change.
private void textBox1_TextChanged(object sender, EventArgs e)
{
string a;
int asc , j=0;
kabir = 0;
vasit = 0;
textBox2.Text =" ";
for (int i = 0; i < textBox1.Text.Length; i++)
{
int t = abjad_kabir(Char.ConvertToUtf32(textBox1.Text.Substring(i, 1), 0));
textBox2.Text = Convert.ToString(t);
j++;
// I want to do not appear number of white spaces in textbox3 and just count number of letters
textBox3.Text = Convert.ToString(j);
}
}
Remove all the characters that you don't want with a regular expression and count the remaining characters:
var text = "Max Length";
Console.WriteLine("Length={0}", Regex.Replace(text, #"\W+", "").Length);
You could also use Linq for this:
var count = text.Count(c => c != ' ');
I could delete white spaces by Trim() method.
private void textBox1_TextChanged(object sender, EventArgs e)
{
string a;
int asc, j = 0;
kabir = 0;
vasit = 0;
textBox2.Text = " ";
string s, m;
for (int i = 0; i < textBox1.Text.Length; i++)
{
int p = Char.ConvertToUtf32(textBox1.Text.Substring(i, 1), 0);
int t = abjad_kabir(p);
textBox2.Text = Convert.ToString(t);
s = textBox1.Text;
m = s.Trim();
textBox3.Text = Convert.ToString(m.Length);
}
}

Counting the number of highlighted words in richtextbox using c#

private void button2_Click(object sender, EventArgs e)
{
string[] show = richTextBox1.Text.Split(' ');
string type = textBox1.Text;
for (int i = 0; i < show.Length; i++)
{
int num = 0;
if (show[i] == textBox1.Text)
num++;
}
Label1.Text = num.ToString();
}
Im using richTextBox1 to display the file and the textBox1 to search for a word and highlight it. I want to display how many words are highlighted in the label box but it always shows zero. Any help is appreciated.
You should move int num = 0; out of your loop, since in each iteration it will be set to 0;
You need to consider the new line character condition.
In my example, I remove Chr(13) and replace Chr(10) with a space, so it behaves the same way as a space character:
string[] show = richTextBox1.Text.Replace(Convert.ToChar(13).ToString(), " ").Replace(Convert.ToChar(10).ToString(), " ").Split(' ');
string type = textBox1.Text;
int num = 0;
for (int i = 0; i < show.Length; i++)
{
if (show[i].Trim() == textBox1.Text)
num++;
}
textBox1.Text = num.ToString();

To get text from two textboxs and add the elements to an array

I want to add the elements from the textboxes to the array but every time I try adding the names it throws an exception. I want to add the elements after the button is clicked.
private void Grade_Click(object sender, EventArgs e)
{
string name;
double grade;
nametextbox.Text = "";
gradetextbox.Text = "";
for (int i = 0; i < 10; i++)
{
grade = Convert.ToDouble(gradetextbox.Text);
grades[i] += grade;
name = nametextbox.Text;
names[i] += name;
}
}
You do this:
gradetextbox.Text = "";
Which sets the Text property to an empty string. Then you do this:
grade = Convert.ToDouble(gradetextbox.Text);
which is trying to convert the empty string to a double, which clearly does not work so it throws an exception.
What you probably need is this:
private double[] grades = new double[10]; // 10 grades
private string[] names = new string[10]; // 10 names
private int currentIndex = 0;
private void Grade_Click(object sender, EventArgs e)
{
if (currentIndex > 10)
{
MessageBox.Show("No more enteries allowed");
}
string name;
double grade;
if (double.TryParse(gradetextbox.Text, out grade))
{
grades[currentIndex] += grade;
}
else
{
MessageBox.Show("Grade enterd is not a valid grade");
return;// do nothing else
}
name = nametextbox.Text;
names[i] += name;
// now clear the textboxes so user can enter another value
nametextbox.Text = "";
gradetextbox.Text = "";
currentIndex = currentIndex + 1;
}

How can i use a numericUpDown to move to specific location text in richTextBox?

In the listView selected index i select item and display the file content in richTextBox:
void lvnf_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListViewCostumControl.lvnf.SelectedItems.Count > 0)
{
richTextBox1.Text = File.ReadAllText(ListViewCostumControl.lvnf.Items[ListViewCostumControl.lvnf.SelectedIndices[0]].Text);
int resultsnumber = 0;
int start = richTextBox1.SelectionStart;
int startIndex = 0;
int index = 0;
string word = textBox1.Text;
Color selectionColor = richTextBox1.SelectionColor;
word = textBox1.Text.Replace("\r\n", "\n");
while ((index = richTextBox1.Text.IndexOf(word, startIndex)) != -1)
{
richTextBox1.Select(index, word.Length);
richTextBox1.SelectionColor = Color.Yellow;
startIndex = index + word.Length;
resultsnumber ++;
}
richTextBox1.SelectionStart = start;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectionColor = selectionColor;
label16.Text = resultsnumber.ToString();
label16.Visible = true;
numericUpDown1.Maximum = resultsnumber;
numericUpDown1.Enabled = true;
}
}
And i have the numericUpDown changedvalue event
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
}
for example if i have in the numericUpDown the maximum value of 4 that's 4 results in the richTextBox text.
Each result is in another place in the text.
What i want to do is when i move up down with the numericUpDown it will jump in the richTextBox to the result location in the text.
I think it should be that if the first result started in index 0 and ended in index 20 then jump to this result show this result.
If the third result is started in index 76 and ended in index 83 so if i selected in the numericUpDown the value 3 jump to this result location.
Ok this is what i did now it was quite easy but i have a problem reseting the variable:
It was easy to do it but i have a problem reseting the variables when selecting another item each time in the listView. I want to reset the List and also to set the numericUpDown1 to value 0 when selecting other item. But then it's going to the numericUpDown1_ValueChanged item before it's adding items to the List and throw exception since the List Count and the numericUpDown1 value are 0.
In top of form1 created a new List
private List<int> results = new List<int>();
In the listView selectedindex event:
void lvnf_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListViewCostumControl.lvnf.SelectedItems.Count > 0)
{
richTextBox1.Text = File.ReadAllText(ListViewCostumControl.lvnf.Items[ListViewCostumControl.lvnf.SelectedIndices[0]].Text);
results = new List<int>();
numericUpDown1.Value = 0;
int resultsnumber = 0;
int start = richTextBox1.SelectionStart;
int startIndex = 0;
int index = 0;
string word = textBox1.Text;
Color selectionColor = richTextBox1.SelectionColor;
word = textBox1.Text.Replace("\r\n", "\n");
while ((index = richTextBox1.Text.IndexOf(word, startIndex)) != -1)
{
richTextBox1.Select(index, word.Length);
richTextBox1.SelectionColor = Color.Yellow;
startIndex = index + word.Length;
resultsnumber ++;
results.Add(startIndex);
}
richTextBox1.SelectionStart = start;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectionColor = selectionColor;
label16.Text = resultsnumber.ToString();
label16.Visible = true;
numericUpDown1.Maximum = results.Count -1;
numericUpDown1.Enabled = true;
richTextBox1.SelectionStart = results[(int)numericUpDown1.Value];
richTextBox1.ScrollToCaret();
}
}
In the numericupdown1 valuechanged event
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
if (results.Count == 0)
{
MessageBox.Show("Results Count Value is 0 Check It !!!!!");
}
else
{
richTextBox1.SelectionStart = results[(int)numericUpDown1.Value];
richTextBox1.ScrollToCaret();
}
}
When selecting first item in the listView it's fine.
But then when selecting any other item i want that the results List and the numericUpDown will be reset to empty and 0.
The problem is when i set the numericUpDown1 Value to 0 it's jumping to the valuechanged event before it's adding the results to the List so it's giving the exception.

Categories