I've got a simple form with RichTextBox on it. In Load event, I write some text to RichTextBox and now I want to set cursor location to the end of this text so I can add something. I've tried Focus() but it doesn't work
Try :
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.Focus();
You can either use the CaretPosition property or use the Select(pos, pos) method to achieve the desired result.
Edit:
The Focus method just moves the keyboard focus to your RichTextBox, but it doesn't alter the current position of the cursor inside the control.
For winform application simple add this command SendKeys.Send("{RIGHT}"); after richTextBox1.AppendText("foo"); or richTextBox1.Paste(); then `richTextBox1.Focus();'
Related
after a long search on the net, I hope you can help me.
My Problem:
I want to select the complete text in a TextBox
and will show the caret (blinking cursor) after the last character.
Always I have found information about one problem or information to hide the caret.
The separate things are no problems but the combination of it don't work.
// Set the focus to the TextBox
myTextBox.Focus();
// Select the complete text, but hide the caret (blinking cursor)
myTextBox.SelectAll();
// or
// myTextBox.Select(0, myTextBox.Text.Length);
// Set the caret after the last character, but loss the selection from the text
myTextBox.CaretIndex = myTextBox.Text.Length;
So, I see the caret after the last character, but the text is not selected
myTextBox.Focus();
myTextBox.SelectAll();
myTextBox.CaretIndex = myTextBox.Text.Length;
And so, the text is selected, but no caret is shown.
myTextBox.Focus();
myTextBox.CaretIndex = myTextBox.Text.Length;
myTextBox.SelectAll();
And that's the problem: one of them deactivate the another one, but I need these two things at the same time
I using WPF and .Net 4.0
Thanks for helping :-)
The problem is the strong internal connection in the TextBox between CaretIndex and the Selection.
Whenever you modify the selection with Select() or SelectAll(), the TextBox automatically places the CaretIndex at the beginning of the selection. In reverse, the TextBox clears the selection when you manually modify the CaretIndex. You can make this behavior visible, if you register for SelectionChanged in the TextBox and output the current CaretIndex to Console.
This is for a good reason, as Okuma.Scott already mentioned in his comment.
So if your desired behaviour is really required, you probably need to implement your own CustomTextBox.
This worked for me:
TextBox.Text = _Text;
System.Windows.Input.Keyboard.Focus(TextBox);
TextBox.GotFocus += (sender, e) => {
if (_selectAll)
{
//I think Caret can be set here but I didn't try it
TextBox.SelectAll();
}
};
In my WinForm application I have a multiline TextBox control (uiResults) which is used for reporting progress while processing a large number of items. Using AppendText works great for automatically scrolling to the bottom at every update, but if the user scrolls back to read some older data I need to turn off the autoscroll. I would rather stay away from P/Invoke calls if possible.
Is it possible to detect if the user has scrolled back without using P/Invoke? For now, I just check SelectionStart which works but requires the user to move the caret from the end of the textbox to stop the autoscroll:
if(uiResults.SelectionStart == uiResults.Text.Length)
{
uiResults.AppendText(result + Environment.NewLine);
}
My main problem is that when appending a string using the Text property, the textbox is scrolled to the beginning. I tried to solve this by storing the caret position and resetting and scrolling to it after the update, but this causes the current line to move to the bottom (of course, since ScrollToCaret scrolls no more than the necessary distance to bring the caret into view).
[Continued from above]
else
{
int pos = uiResults.SelectionStart;
int len = uiResults.SelectionLength;
uiResults.Text += result + Environment.NewLine;
uiResults.SelectionStart = pos;
uiResults.SelectionLength = len;
uiResults.ScrollToCaret();
}
Auto-scrolling text box uses more memory than expected
The code in the question implements exactly what you are looking for. Text is added, but scrolling only occurs if the scroll bar is at the very bottom.
I have had the same problem.
And finally, I made an easy way.
(Sorry, I'm not good at English.)
key point is get the first displayed char index using GetCharIndexFromPosition method.
//Get current infomation
int selStart = textBox.SelectionStart;
int selLen = textBox.SelectionLength;
int firstDispIndex = textBox.GetCharIndexFromPosition(new Point(3, 3));
//Append Text
textBox.AppendText(...);
//Scroll to original displayed position
textBox.Select(firstDispIndex, 0);
text.ScrolltoCaret();
//Restore original Selection
textBox.Select(selStart, selLen);
And, if textbox is flicking, use this extention.
Call textBox.Suspend() before adding text, and call textBox.Resume() after adding text.
namespace System.Windows.Forms
{
public static class ControlExtensions
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool LockWindowUpdate(IntPtr hWndLock);
public static void Suspend(this Control control)
{
LockWindowUpdate(control.Handle);
}
public static void Resume(this Control control)
{
LockWindowUpdate(IntPtr.Zero);
}
}
}
Hope this will help you.
Thank you~
Are you open to another approach, because you are bound to get into trouble this way and the solutions will get complex (pinvoke etc. that you want to avoid). For eg. suppose you find a way to "detect if the user has scrolled back" and you stop scrolling to bottom. But after reading the line user might want the scroll to bottom feature to resume. So why not give user a way to control Auto-Scrolling. Here's how I would do it...
Use a RichTextBox to show data and a Checkbox to control AutoScrolling, then your code might be something like this:
richTextBox1.AppendText(result + Environment.NewLine);
if (checkBoxAutoScroll.Checked)
{
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.ScrollToCaret();
}
RichTextBox by default will not automatically scroll to bottom on AppendText, so the first line would always be visible (and not the newly appended line). But if user checks this checkbox called AutoScroll, our code will then scroll the richtextbox to the bottom where new lines are shown. If user wants to manually scroll to read a line he will first need to uncheck the checkbox.
This was hard to explain, but say I have a form with a numeric up down. When the form starts, I want the number in the numeric up down to be highlighted meaning you can just press and number without clicking in the box and it will put it in there. How would I go about doing this?
EDIT: For some reason, doing .select() on the control with no parameters does select the control which is what I want. But using .select(0, 3) doesn't highlight the default "1" that is in the box. How do I highlight it?
You can Focus() the control and make the IsDefault property true to fires when pressing enter or returns (from another controls, as you need).
Just set the control's focus in the form's OnLoad event.
This should do the trick:
myNumericUpDown.TabIndex = 0;
myNumericUpDown.Focus();
myNumericUpDown.Select(0, myNumericUpDown.Value.ToString().Length);
Or swap out the select with:
myNumericUpDown.Select(0, 99);
Just put it in your form load :-)
EDIT:
The control also needs to have TabIndex set to 0
Just make sure no other control have TabIndex set to 0 :-)
You can start by putting focus on the numeric up down, that should let you do what you want.
Yes, you can call the Focus() method to set focus to a specific control.
E.g. in the constructor call myNumericUpDown.Focus();
I think you can just use the .Focus() method on the button in your code behind.
During the form load event try something like this ...
yourControl.Focus();
After InitializeComponents() you can call numericUpDown.Focus().
Set the ActiveControl property of the form and you should be fine.
this.ActiveControl = numericUpDown1
Inorder to get the text selected within the control, add this part
numericUpDown1.Select(0, numericUpDown1.Text.Length);
I have a multiline TextBox called Console. While running, this textbox is being filled up with some communications data. I use
TextBox.AppendText("txt\r\n");
to add a line to it and that allows me to have it autoscroll down. My problem is I want to be able to not have it autoscroll down. So I thought I would try
TextBox.Text += "text";
But that scrolls you to the beginning of the box. My latest attempt was to use TextBox.SelectionStart to save the position before I wrote and restore it back to that after, but that didn't seem to make a difference and still brings me back to the beginning of the text.
int txtPosition = Console.SelectionStart;
Console.Text += "TextToAdd";
Console.SelectionStart = txtPosition;
Ideally I want to just be able to have the box stay where ever it happens to be and not scroll to the beginning or end of the text.
I think you need to you a richtextbox instead of a generic textbox and this will provide you with the functionality you desire.
Enjoy!
For a WinForms textbox, you may should able to do this:
textBox.SelectionStart = 0;
textBox.ScrollToCaret(); // force current position back to top
I need to be able to scroll a RichTextBox to the bottom, even when I am not appending text. I know I can append text, and then use that to set the selection start. However I want to ensure it is at the bottom for visual reasons, so I am not adding any text.
You could try setting the SelectionStart property to the length of the text and then call the ScrollToCaret method.
richTextBox.SelectionStart = richTextBox.Text.Length;
richTextBox.ScrollToCaret();
The RichTextBox will stay scrolled to the end if it has focus and you use AppendText to add the information. If you set HideSelection to false it will keep its selection when it loses focus and stay auto-scrolled.
I designed a Log Viewer GUI that used the method below. It used up to a full core keeping up. Getting rid of this code and setting HideSelection to false got the CPU usage down to 1-2%.
//Don't use this!
richTextBox.AppendText(text);
richTextBox.ScrollToEnd();
In WPF you can use ScrollToEnd:
richTextBox.AppendText(text);
richTextBox.ScrollToEnd();
Code should be written in the rich text box's TextChanged event like :
private void richTextBox_TextChanged(object sender, EventArgs e) {
richTextBox.SelectionStart = richTextBox.Text.Length;
richTextBox.ScrollToCaret();
}