RichTextBox caret position when inserting rtf string - c#

I am trying to insert rtf string into a RichTextBox. This is the KeyUp event form RichTextBox:
private void richTextBox1_KeyUp(object sender, KeyEventArgs e)
{
string st = richTextBox1.Rtf;
st=st.Insert(750, "void");
richTextBox1.Rtf = st;
}
The problem is that, after each update, the caret goes before the inserted text and I want to keep it at the end. I noticed that this is happening only when I modify the length of st.

I can't fathom how your code is supposed to work for the end user. How would you even know that at index 750 you have text versus an rtf control character?
The quick solution is to just set the caret position to the end yourself:
private void richTextBox1_KeyUp(object sender, KeyEventArgs e)
{
string st = richTextBox1.Rtf;
st=st.Insert(750, "void");
richTextBox1.Rtf = st;
richTextBox1.SelectionStart = richTextBox1.TextLength;
}
Of course, if you are trying to put the caret at the position where void is inserted, that wouldn't work with your rtf property, since the rtf and text properties are different things.
If trying to insert text in the text property, then it would look something like this:
private void richTextBox1_KeyUp(object sender, KeyEventArgs e)
{
string st = richTextBox1.Text;
st=st.Insert(750, "void");
richTextBox1.Text = st;
richTextBox1.SelectionStart = 750 + 4;
}

Related

How can i read the text from richTextbox and keep the format of the text?

For example inside the richTextBox I have the text:
Hello world
Hello hi
Hi all
Now I want to read this text with this format including the empty line/s and then to write back to the same file the same text with or without changes like deleted text or added text.
For example, if I delete the all then the text to write back will be in this format:
Hello world
Hello hi
Hi
Just without the all
Or
Hello world
Hello hi
Hi all everyone
So now it will write the same text but with the everyone but will keep the format.
I tried this but this adding too many empty lines and spaces that was not before:
var lines = richTextBox1.Text.Split('\n');
File.WriteAllLines(fileName, lines);
Then i tried:
var text = richTextBox1.Text;
File.WriteAllText(fileName, text);
This wrote to the file the same text with the changes but it didn't keep the format it wrote the text to the file as one line.
You have to replace "\n" with "\r\n"
var text = richTextBox1.Text;
text = text.Replace("\n", "\r\n");
File.WriteAllText(fileName, text);
Well, there are a several options here, none of which involve splitting the text.
Note: All the code below is using a private variable that has the file path as a string:
public partial class Form1 : Form
{
private const string filePath = #"f:\public\temp\temp.txt";
The first one is to simply save all the text (including the \r\n characters) using the Text property, along with File.ReadAllText and File.WriteAllText:
// Load text on Form Load
private void Form1_Load(object sender, EventArgs e)
{
if (File.Exists(filePath))
{
richTextBox1.Text = File.ReadAllText(filePath);
}
}
// Save text on button click
private void button1_Click(object sender, EventArgs e)
{
File.WriteAllText(filePath, richTextBox1.Text);
}
If you want to do it line by line, you can use File.ReadAllLines and File.WriteAllLines along with the Lines property of the RichTextBox:
// Load text on Form Load
private void Form1_Load(object sender, EventArgs e)
{
if (File.Exists(filePath))
{
richTextBox1.Lines = File.ReadAllLines(filePath);
}
}
// Save text on button click
private void button1_Click(object sender, EventArgs e)
{
File.WriteAllLines(filePath, richTextBox1.Lines);
}
Finally, you could use the built-in SaveFile and LoadFile methods of the RichTextBox class. This method will write metadata to the file, so if you open it in notepad you will see some additional characters that include all kinds of format information. Because of this, I added a try/catch block around the call to LoadFile, since it will throw and exception if the file does not have the correct format, and I fall back to loading it with ReadAllText:
// Load text on Form Load
private void Form1_Load(object sender, EventArgs e)
{
if (File.Exists(filePath))
{
try
{
richTextBox1.LoadFile(filePath);
}
catch (ArgumentException)
{
// Fall back to plain text method if the
// file wasn't created by the RichTextbox
richTextBox1.Text = File.ReadAllText(filePath);
}
}
}
// Save text on button click
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.SaveFile(filePath);
}

How to get the correct and clean path while doing drag and drop in C#?

I am developing a small application which takes in a csv file, removes all rows except those which have "critical" in their second column. You simply type in the input path and the output path and the manipulation is done. All was fine until I decided to do it as drag and drop. I drag the input file into the Windows Form, and the textbox automatically fills with the path I need. Great. Then I fill the output path. However, when I press the execute button, I get "illegal character in path" error. But when I type the same exact path that came up upon dragging, the program works! Any idea if their is something like a hidden character I cannot see? Here is my code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.AllowDrop = true;
}
private void button1_Click(object sender, EventArgs e)
{
String inputpath = textBox1.Text;
String outputpath = textBox2.Text;
MessageBox.Show(inputpath, outputpath);
var retainedLines = File.ReadAllLines(#inputpath)
.Where((x, i) => i == 0 || (x.Split(',')[1]).Contains("critical"));
if (inputpath.Equals(outputpath))
{
File.Delete(#inputpath);
}
File.WriteAllLines(#outputpath, retainedLines);
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] fileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);
foreach (string s in fileList)
{
String k= String.Format("{0}{1}", s, Environment.NewLine);
k = k.Replace("\n", String.Empty);
textBox1.Clear();
textBox1.Text = k;
}
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop, false))
e.Effect = DragDropEffects.All;
}
}
I think that your problem is in these two lines
String k= String.Format("{0}{1}", s, Environment.NewLine);
k = k.Replace("\n", String.Empty);
Here you add Environment.NewLine (that Windows OS defines as a couple of chars \r\n) and then the code removes the \n but leaves the \r.
So when you try to read that file name you get an invalid character in path.
A simple workaround is
private void button1_Click(object sender, EventArgs e)
{
String inputpath = textBox1.Text.Trim();
....
}
but probably you need to revise a bit how do you add the files in the TextBox1.
For example, your code ignore if the Drop operation has more than one file, just the last one in the list is used. (If this is intentional then disregard this note)
The \r character is just the escaped representation in C# (and other C derived languages) of the CARRIAGE RETURN char (CR U+000D)
For more details about the Carriage Return And Line Feed characters see this article on Wikipedia

How to make text display in a textbox multiple times in C#?

I want to display something multiple times in a textbox. For example if you use this code and replace richtextbox with messagebox, it will keep displaying the text until the loop ends. I want to display the text from textBox1 into richTextBox1, and then have the program hit enter, and then type it out again in the richtextbox. It's kind of confusing sorry, but if you have any questions just comment them and i'll be more clear. This is my code:
private void button1_Click(object sender, EventArgs e)
{
Clipboard.SetText(textBox1.Text);
int text = 0;
int end = int.Parse(textBox2.Text);
while (text<=end)
{
richTextBox1.Text=(Clipboard.GetText());
text++;
}
Thanks in advance!
In your code you have:
richTextBox1.Text=(Clipboard.GetText());
The reason that your code is not working is because in every loop, you are setting the text to whatever is on the clipboard, so at the end of the loop it will only have it in there once. You need to 'append' or add onto the end of the text so it will have it multiple times:
richTextBox1.Text += richTextBox1.Text + (Clipboard.GetText());
Or:
richTextBox1.Text += (Clipboard.GetText());
This will add the clipboard text onto the end of the RichTextBox, so you will have the same text multiple times, but all on the same line. If you want to make the text appear on multiple lines, you have to add a new line after appending the text:
richTextBox1.Text += (Clipboard.GetText())+"\r\n";
Or:
richTextBox1.Text += (Clipboard.GetText())+Enviroment.NewLine;
Hope this Helps!
Use Timer instead of using loop and keep its interval time like for 2 second. and on button click start timer and declare end as class variable , when condition is met for "end" variable , stop timer.
private void button1_Click(object sender, EventArgs e)
{
end = int.Parse( textBox2.Text);
timer1.Start();
}
private int end = 0;
private int start = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (start == end)
{
timer1.Stop();
}
else
{
start++;
textBox1.Text = start.ToString();
}
}

WPF (with C#) TextBox Cursor Position Problem

I have a WPF C# program where I attempt to delete certain characters from a text box at TextChanged event. Say, for instance, the dollar sign. Here is the code I use.
private void txtData_TextChanged(object sender, TextChangedEventArgs e)
{
string data = txtData.Text;
foreach( char c in txtData.Text.ToCharArray() )
{
if( c.ToString() == "$" )
{
data = data.Replace( c.ToString(), "" );
}
}
txtData.Text = data;
}
The problem I have is that whenever the user enters $ sign (Shift + 4), at the TextChanged event it removes the $ character from the textbox text alright, but it also moves the cursor to the BEGINNING of the text box which is not my desired functionality.
As a workaround I thought of moving the cursor the the end of the text in the text box, but the problem there is that if the cursor was positioned at some middle position then it would not be very user friendly. Say, for instance the text in the textbox was 123ABC and if I had the cursor after 3, then moving the cursor to the end of the text would mean that at the next key stroke user would enter data after C, not after 3 which is the normal functionality.
Does anybody have an idea why this cursor shift happens?
Its not an answer to your question, but probably a solution for your problem:
How to define TextBox input restrictions?
If it is overkill for you, set e.Handled = true for all characters you want to avoid in PreviewKeyDown (use Keyboard.Modifiers for SHIFT key) or PreviewTextInput.
Try TextBox.CaretIndex for restoring cursor position in TextChanged event.
Hope it helps.
You can use the Select function of TextBox to change the cursor position.
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
textBox1.Text = textBox1.Text.Replace("$", "");
textBox1.Select(textBox1.Text.Length, 0);
}
You can see more about Position the Cursor on the MSDN
You can use the SelectionStart property of the textbox. Probably something along these lines should work:
private void txtData_TextChanged(object sender, TextChangedEventArgs e)
{
var pos = txtData.SelectionStart;
string data = txtData.Text.Replace("$", "");
txtData.Text = data;
txtData.SelectionStart = pos;
}
You can try Regular Expression
Sample
1) Use PreviewTextInput="CursorIssueHandler" in .xaml file
2) In your .cs file ,write the below code:
private void CursorIssueHandler(object sender, TextCompositionEventArgs e)
{
var TB = (sender as TextBox);
Regex regex = new Regex("[^0-9a-zA-Z-]+");
bool Valid = regex.IsMatch(e.Text);
//System.Diagnostics.Debug.WriteLine(Valid); // check value for valid n assign e.Handled accordingly your requirement from regex
e.Handled = Valid;
}

how to restrict the length of entries in text box to its width

c#:
By default text box accepts n number of entries,
I want to restrict the entries to its width
Is there any property in text box through which i can achive this,
You could compute the width of the text to be drawn and if it exceeds the textbox width then return.
HERE you can find a great example.
default it accepts only 32767 of chars.
You can set the MaxLength property of the textbox in the textbox property
Hope you are using windows forms
Assuming WinForms, try this:
private bool textExceedsWidth;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
textExceedsWidth = false;
if (e.KeyCode == Keys.Back)
return;
Size textSize = TextRenderer.MeasureText(textBox1.Text, textBox1.Font);
if (textBox1.Width < textSize.Width)
textExceedsWith = true;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (textExceedsWidth)
e.Handled = true;
}
No, to do this you will have to calculate the maximium number of characters they can enter by the text box width manually I'm afraid. You'll also have to take into consideration the font and font size too
I know this question is a bit old but to any one looking this is an expansion of George answer. It works with Ctrl + v, context menu paste and typing from key board.
private string oldText;
private void txtDescrip_KeyPress(object sender, KeyPressEventArgs e)
{
oldText = txtDescrip.Text;
}
private void txtDescrip_TextChanged(object sender, EventArgs e)
{
Size textSize = TextRenderer.MeasureText(txtDescrip.Text, txtDescrip.Font);
if (textSize.Width > txtDescrip.Width)//better spacing txtDescrip.Width - 4
txtDescrip.Text = oldText;
else
oldText = txtDescrip.Text;
}

Categories