I have a RichTextBox and it scrolls with every AppendText, but it shall only scroll if the scrollbar is at bottom. I would like for example to easily select and copy something from the middle of the richtextbox while text is appended to the RichTextBox. Tried many solutions, but nothing really worked correct. Is this even possible?
It depends how you are Appending, but you can tell it to focus back to where the selection (or just cursor) is after appending.
eg (untested, assuming WinForms):
int selStart = rtb.SelectionStart
int selLength = rtb.SelectionLength
rtb.AppendText("test")
rtb.SelectionStart = selStart
rtb.SelectionLength = selLength
That will always push the selection back to where it was before the append - but won't scroll down if it was at the bottom previously. To me, that seems like expected behaviour.
Related
I am redirecting CMD output to a multi-line textbox, I'm trying to auto-scroll down using the following code:
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
textBox1.Refresh();
However it's really choppy looking, by that I mean, each time a line comes in, it positions the scroll bar at the top of the textbox, then to the bottom, it's hard to describe so I made a .gif of it happening: http://i.imgur.com/mudqrZy.gif
Is there any way to fix it?
For the same purpose I use RichTextBox:
richTextBox1.AppendText(cmdOutputMsg + "\r\n");
richTextBox1.ScrollToCaret();
In this way the new text is always added at the end of the existing text, and with ScrollToCaret the focus remains on the last inserted text.
I think with normal TextBox will work in the same way.
I have a path selector in my Visual C# Express 2010 form application.
I do it using a FolderBrowserDialog and a (single line) TextBox, to show the selected path. Using the following line in my UI refresh code.
this.textBoxFolder.Text = this.folderBrowserDialog1.SelectedPath;
The ReadOnly property is set to true and TextAlign property is set to Right using the form designer, because the selected path is often longer than the TextBox, and I prefer to show the right-side of the path. The forms designer generates this:
//
// textBoxFolder
//
this.textBoxFolder.Location = new System.Drawing.Point(40, 72);
this.textBoxFolder.Name = "textBoxFolder";
this.textBoxFolder.ReadOnly = true;
this.textBoxFolder.Size = new System.Drawing.Size(160, 20);
this.textBoxFolder.TabIndex = 13;
this.textBoxFolder.TabStop = false;
this.textBoxFolder.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
Whenever the chosen path is shorter than the textbox size, the Right alignment works. (But this is not really important)
Whenever the chosen path is longer than the textbox size, the Right alignment has no effect, the string in the textbox is displayed such that the left-most character is visible, and right-most are hidden.
I know that in a normal single line TextBox (ReadOnly = false), when an overly-long string is typed in by hand, the right most chars are visible, even when focus goes away, regardless of whether TextAlign is set to Left / Right / Center!
In other words, my goal is, when TextBox.Text is programmatically set (as opposed to typed in), and the string is longer than the width of the TextBox, how do I get the right-most chars to be visible?
Instead of setting the TextAlign property, you should move the caret to the last character:
textBoxFolder.Text = this.folderBrowserDialog1.SelectedPath;
textBoxFolder.SelectionStart = textBox1.Text.Length - 1;
Setting SelectionStart actually moves the caret to the specified position. And that makes the character at that position visible in the TextBox.
If you can use a Label instead of a text box, you can use the one created by Hans Passant here that uses TextFormatFlags.PathEllipses flag while drawing the text.
Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows CE Platform Note: In Pocket PC-based applications, a single-line text box supports only left alignment. A multiline text box can be aligned on the left, right, or center.
The WPF RichtTextBox has a method to scroll:
RichTextBox.ScrollToVerticalOffset(double)
I want to scroll in such a way, that a certain range or at least the start of it comes into view. How can I convert a TextPointer to double in a meaningful way?
Have a look at the FrameworkElement.BringIntoView Method. I'm using something like this:
public void Foo(FlowDocumentScrollViewer viewer) {
TextPointer t = viewer.Selection.Start;
FrameworkContentElement e = t.Parent as FrameworkContentElement;
if (e != null)
e.BringIntoView();
}
I'm somewhat late, but here is a more complete answer. The current scroll offsets need to be combined with the character position. Here is an example that scrolls RichTextBox text pointer to the center of the view:
var characterRect = textPointer.GetCharacterRect(LogicalDirection.Forward);
RichTextBox.ScrollToHorizontalOffset(RichTextBox.HorizontalOffset + characterRect.Left - RichTextBox.ActualWidth / 2d);
RichTextBox.ScrollToVerticalOffset(RichTextBox.VerticalOffset + characterRect.Top - RichTextBox.ActualHeight / 2d);
You don't need to check for negative numbers, as the scrolling accounts for this.
Use GetCharacterRect to get position of TextPointer in RichTextBox:
Rect r = textPointer.GetCharacterRect(LogicalDirection.Backward);
rtb.ScrollToVerticalOffset(r.Y);
So if you're wondering why BringIntoView() isn't working or it scrolls to the top of your textbox, it's likely because you are attempting to "bring into view" the Inline that comprises your entire scrollable text content - it "brings to view" this inline, which starts at (you guessed it) the "start" TextPosition at the top.
Solution is to use ScrollToVerticalOffset() per Miroslav's answer.
I have a C# Windows Forms program that has a RichTextBox control. Whenever the text inside the box is changed (other than typing that change), the cursor goes back to the beginning.
In other words, when the text in the RichTextBox is changed by using the Text property, it makes the cursor jump back.
How can I keep the cursor in the same position or move it along with the edited text?
Thanks
You can store the cursor position before making the change, and then restore it afterwards:
int i = richTextBox1.SelectionStart;
richTextBox1.Text += "foo";
richTextBox1.SelectionStart = i;
You might also want to do the same with SelectionLength if you don't want to remove the highlight. Note that this might cause strange behaviour if the inserted text is inside the selection. Then you will need to extend the selection to include the length of the inserted text.
Be careful, if someone refreshes or changes totally the RichTextBox content, the focus method must be invoqued previously in order to move the caret:
richTextBox1.Focus();
int i = richTextBox1.SelectionStart;
richTextBox1.Text = strPreviousBuffer;
richTextBox1.SelectionStart = i;
here's a smaller one, that has the same effect. this.richTextBox1.Select(this.richTextBox1.Text.Length, 0);
That marks 0 chars at the end of the text and sets the cursor to end
Probably not double buffering but I'm trying to make a highlighter (pure amusement) using a RichTextBox. The problem I have is that, when there are a lot of highlighted words, programmer-made flickering appear and even see the textbox scroll.
I don't think that RichTextBox has DoubleBuffered property, and even if it had, it wouldn't word, the flickering is my fault.
int pos = myTextBox.SelectionStart;
RichTextBox buffer = new RichTextBox();
buffer.Rtf = myRichTextBox.Rtf;
//Do whatever you wanna do in buffer
myTextBox.Rtf = buffer.Rtf;
myTextBox.SelectionStart = pos;
myTextBox.SelectionLength = 0;
Tho, I still have a problem because, no matter what I do, myTextBox.ZoomFactor seems to be deleted.
Just use LockWindowUpdate on your RichTextBox before changing the color.