I am trying to have a multi line textbox that when you type in it streams it to the label, BUT the label has to have a max length of 15 so like once it reaches 15 characters in the textbox it should start overwriting the label since it reached it's max length
thanks to anyone who can help
Add onchange event on text box :
if (textBox1.Text.Length<=15)
{
label1.Caption=textBox1.Text;
}
For example
I'm not sure what kind of overwriting You want to achieve.
There are at least three methods you can use:
displaying always the last 15 characters from the textbox, as described in the Olivier's answer
clearing the label's text each 15 characters inserted and start filling in the label over again, you can use this code to achieve this:
private void textBox1_TextChanged(object sender, EventArgs e)
{
String text = textBox1.Text.Replace("\r\n", "|");
int startIndex = ((text.Length - 1) / 15) * 15;
label1.Text = text.Substring(Math.Max(0, startIndex));
}
you can also overwrite char by char when text length is over 15 characters, however, I suppose it's not what you would like to achieve, because it would cause a mess in the textbox ;), however, it can be used as a kind of visual effect :). If you want code snippet for this, let me know :).
Update
Here's the code for the third overwriting method:
String lastText = "";
private void textBox1_TextChanged(object sender, EventArgs e)
{
String textBoxText = textBox1.Text.Replace("\r\n", "|");
if (textBoxText.Length > lastText.Length)
{
int charIndex = (textBoxText.Length - 1) % 15;
if (charIndex >= 0)
{
label1.Text = label1.Text.Insert(charIndex, textBoxText.Substring(textBoxText.Length - 1));
if (charIndex < textBoxText.Length - 1)
{
label1.Text = label1.Text.Remove(charIndex + 1, 1);
}
}
}
else
{
int charIndex = textBoxText.Length % 15;
if (textBoxText.Length >= 15)
{
label1.Text = label1.Text.Insert(charIndex, textBoxText[textBoxText.Length - 15].ToString());
if (charIndex < textBoxText.Length - 1)
{
label1.Text = label1.Text.Remove(charIndex + 1, 1);
}
}
else
{
label1.Text = label1.Text.Remove(label1.Text.Length - 1, 1);
}
}
lastText = textBoxText;
}
Add a handler to the TextChanged event of the TextBox that sets the Label's content based on the text. E.g. (untested, might have your concept wrong or be off by one somewhere)
int startIndex = Math.Max(0, myTextBox.Text.Length - 15);
int endIndex = Math.Min(myTextBox.Text.Length - 1, startIndex);
myLabel.Text = myTextBox.Text.Substring(startIndex, endIndex - startIndex);
Also, though it doesn't change your question/answer, you might want to look at using a TextBlock instead of a Label. It allows things like line wrapping. See some of the differences here: http://joshsmithonwpf.wordpress.com/2007/07/04/differences-between-label-and-textblock/ (in WPF, should be similar whatever you're doing, though)
My solution always displays the last 15 characters in the label
private void textBox1_TextChanged(object sender, EventArgs e)
{
string s = textBox1.Text.Replace("\r\n", "|");
int length = s.Length;
if (length > 15) {
label1.Text = s.Substring(length - 15);
} else {
label1.Text = s;
}
}
I also replace the line-breaks with |. Since your textbox is in multiline mode, line-breaks are entered when you hit <Enter>.
Related
I am looking a way to create a HyperLink in a RichTextBox pointing to a line of the text of the same RichTextBox.
I just found how to do that with Internet Links but I don't find a way to do it with the same text inside of the control (It's like Hyperlinks in MS Word pointing to a header or bookmark).
Thanks in Advance. - CCB
No, this will not work unless you code the necessary stuff yourself.
Two suggestions:
A simple workaround with links always starting with www.
The nicer solution with arbitrary link text
Let's have a look at both options..:
Using the built-in functionality of recognizing an URL seems the right way to start, but the link will always have to look like a URL, not like a hyperlink to an anchor.. If you can live with a solution that has, say, links like this: www.goto.234 and anchors like this: #234# this is really rather simple..
A working example can be as simple as this:
private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
{
var s = e.LinkText.Split('.');
string anchor = s[2];
int a = richTextBox1.Text.IndexOf("#" + anchor + "#" );
if (a >= 0) richTextBox1.SelectionStart = a; else return; // do add more checks!
richTextBox1.SelectionLength = 0;
Text = anchor + " # " + a;
//richTextBox1.ScrollToCaret(); <<--- this crashes on my machine!
// so I take the jump out of the click event and it works:
Timer ttt = new Timer() { Interval = 100 };
ttt.Tick += (ss, ee) => { richTextBox1.ScrollToCaret(); ttt.Stop(); };
}
Option two: If you'd rather have more choice of how the links should read you can do this:
Start by formatting each to
Start with a special character, say a tilde '~'
format it to look blue and underlined if you want to
Either make it one word or replace space by underlines and format those to have the forecolor equal to the backcolor
Now this can do the job:
public string delimiters = " ()[]{}!&?=/\\,;.\r\n";
private void richTextBox2_Click(object sender, EventArgs e)
{
int sstart = -1;
string s = getWordAt(richTextBox2.Text,
richTextBox2.SelectionStart, delimiters, out sstart);
if (s.Length < 3) return;
string char1 = s.Substring(0, 1);
if (char1 == "~")
{
int p = richTextBox2.Text.IndexOf("#" + s.Substring(1));
if (p >= 0) { richTextBox2.SelectionStart = p; richTextBox2.ScrollToCaret(); }
}
}
public static string getWordAt(string text, int cursorPos,
string delimiters, out int selStart)
{
int startPos = 0;
selStart = startPos;
if ((cursorPos < 0) | (cursorPos > text.Length) | (text.Length == 0)) return "";
if ((text.Length > cursorPos) & (delimiters.Contains(text[cursorPos]))) return "";
int endPos = text.Length - 1;
if (cursorPos == text.Length) endPos = text.Length - 1;
else { for (int i = cursorPos; i < text.Length; i++)
{ if (delimiters.Contains(text[i])) { endPos = i - 1; break; } } }
if (cursorPos == 0) startPos = 0;
else { for (int i = cursorPos; i > 0; i--)
{ if (delimiters.Contains(text[i])) { startPos = i + 1; break; } } }
selStart = startPos;
return text.Substring(startPos, endPos - startPos + 1);
}
Here are the two versions side by side, once at the top then after clicking on a link:
Both versions work fine, although both could do with some more checks.
Note that I was too lazy to format the pseudo-links in the second example, so they show their tildes and hashes..
Not hard to write a helper function that can insert the formatting; the search will still work as it searches in the Text, not the Rtf property..
I have almost designed a notepad using c#. But only problem I'm facing now is in my statusstrip.
My need- I want to display character count per each line.
When user press enter key it should come to new line and now character count should start from 1.
Technically - Col=1, Ln=1; //(initially)Col=no of character per line Ln=line count
When user press enter key-
Ln=2 and goes on and Col=No of characters we have typed in that specific line
I've tried these lines of code -
private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
int count = Convert.ToInt32(e.KeyChar);
if (Convert.ToInt32(e.KeyChar) != 13)
{
Col = richTextBox1.Text.Length;
toolStripStatusLabel1.Text = "Col:" + Col.ToString() + "," + "Ln:" + Ln;
}
if (Convert.ToInt32(e.KeyChar) == 13)
{
//richTextBox1.Clear();
Ln = Ln + 1;
toolStripStatusLabel1.Text = "Col:" + Col.ToString() + "Ln:" + Ln;
}
}
Supposing you are using Windows Forms, you can use the following solution (but you have to subscribe to the SelectionChanged event instead of the KeyPress event of the rich text box control):
private void richTextBox1_SelectionChanged(object sender, EventArgs e)
{
int currentIndex = richTextBox1.SelectionStart;
// Get the line number of the cursor.
Ln = richTextBox1.GetLineFromCharIndex(currentIndex);
// Get the index of the first char in the specific line.
int firstLineCharIndex = richTextBox1.GetFirstCharIndexFromLine(Ln);
// Get the column number of the cursor.
Col = currentIndex - firstLineCharIndex;
// The found indices are 0 based, so add +1 to get the desired number.
toolStripStatusLabel1.Text = "Col:" + (Col + 1) + " Ln:" + (Ln + 1);
}
I'm using .NET 3.5 CF and trying to create a textbox which should hide the character written inside it. This works by setting the parameter PasswordChar to = "*". However this change the char to a * directly.
What I want is a "smart" textbox who change the character to a * after a delay (approximate 1 second) which will make the user to get some feedback that correct character was written.
I tried this by creating another thread that should handle this since the user should still be able to write more characters and not wait this delay. I did something like this:
if (UseModernPasswordScreenMaskning)
{
this.Invoke(new UpdateTextCallback(this.UpdateText), new object[]{"*"});
}
private void UpdateText(string text)
{
int k = this.Text.Length;
System.Threading.Thread.Sleep(1000);
this.Text = this.Text.Remove(k - 1, 1);
this.Text = this.Text.Insert(k - 1, "*");
}
It works but the sleep is on my current thread which make next letter written delay by 1 second before it shows up. I want each letter to show directly and change to a *, 1 second after that particular char was written.
As i understand, a "smart" password textbox is
the last character will become * within 1s
if user type a new character, the older one will become * (although it doesn't last 1s)
So
Create a timer callback with 1s interval to change last character to *
In smartTextBox_TextChanged event, change the previous character to *
Here is my code
public void Do(object state)
{
int num = this.textBox1.Text.Count();
if (num > 0)
{
StringBuilder s = new StringBuilder(this.textBox1.Text);
s[num - 1] = '*';
this.Invoke(new Action(() =>
{
this.textBox1.Text = s.ToString();
this.textBox1.SelectionStart = this.textBox1.Text.Count();
timer.Dispose();
timer = null;
}));
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (timer == null)
{
timer = new System.Threading.Timer(timerCallback, null, 1000, 1000);
}
int num = this.textBox1.Text.Count();
if (num > 1)
{
StringBuilder s = new StringBuilder(this.textBox1.Text);
s[num - 2] = '*';
this.textBox1.Text = s.ToString();
this.textBox1.SelectionStart = num;
}
}
In initialize
timerCallback = new TimerCallback(Do);
I managed to solve it by adding since the line "int num = this.textBox1.Text.Count();" could not be used before that statement:
public void Do(object state)
{
if (this.logonPwTxtBox.InvokeRequired)
{ .. }
}
I want to write the event handler method button1_Click to calculate whether student’s Grade is “PASS” or “FAIL”. The student passes the course if the total score is greater than or equal to 50. The total score is Midterm(textbox1) + Final(textbox2) scores. However, teacher can give student Extra Credit(checkbox1) which is worth 10 points. The result will present in the textBox3
Here's my code:
private void button1_Click(object sender, EventArgs e)
{
int midtermInt = int.Parse(textBox1.Text);
int finalInt = int.Parse(textBox2.Text);
if (checkBox1.Checked)
{
if ((midtermInt + finalInt) + 10 >= 50)
{
grade.Text = "PASS";
}
else if ((midtermInt + finalInt) + 10 < 50)
{
grade.Text = "FAIL";
}
}
else if (!checkBox1.Checked)
{
if ((midtermInt + finalInt) >= 50)
{
grade.Text = "PASS";
}
else if ((midtermInt + finalInt) < 50)
{
grade.Text = "FAIL";
}
}
When I run it, it says "Inut string was not in a correct format.. :(
I'm very new to C# please advise me if my code is wrong anywhere
The input will only be integers never texts..
You should use int.TryParse insted int.Parse, it's check is specified string is in correct format.
You code may looks like this:
int midtermInt;
if (!int.TryParse(textBox1.Text, out midtermInt))
{
labelError.Text = "Icorrect value in field 'textBox1'".
return;
}
If you type non-numeric characters in your textbox and try to parse the text, it will throw you this exception. Try trimming the input and definitely consider adding UI validation to your forms.
You can add checking, if text in text box is in correct format in TextChanged event:
private void textBox_TextChanged(object sender, EventArgs e)
{
int val;
if (textBox.Text.Length == 0 || !int.TryParse(textBox.Text, out val))
tsPassingScore.Text = "0";
}
And in your click you can check if there is number in textBox again with int.TryParse
Also you can improve your code:
If final summ is not bigger then 50 - it is automatically smaller! And it would be more readable, if you introduce extra variable - for teachers extra credit:
int extraCredit = checkBox1.Checked ? 10 : 0;
int finalScore = midtermInt + finalInt + extraCredit;
if (finalScore >= 50)
grade.Text = "PASS";
else
grade.Text = "FAIL";
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;
}