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.
Related
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.
I've written an application that has a richtextbox in it with a black background. Therefore I have to write in it using white text. That all works fine by setting the fore color to white. If I however copy text from Word that is black into my textbox, that text remains black.
I need to change the color of that text. So this is what i've tried so far: (the textbox is named txtMessage)
txtMessage.ForeColor = Color.White;
That doesn't have any effect on the existing black text though.
Then I tried this:
private void txtMessage_TextChanged(object sender, EventArgs e)
{
int s = txtMessage.SelectionStart;
txtMessage.SelectAll();
txtMessage.SelectionColor = Color.White;
txtMessage.Select(s, 0);
}
It in principle works fine but of course every time I edit the text in the textbox (not copying something in there, but simply typing) the whole thing is executed with every letter I type resulting in a flickering ( I guess because all is selected and then deselected every single time).
So does anyone have a suggestion how to fix this elegantly?
Thank you very much.
If you are typing in the box an the colour is set to white, there is no need to run the code.
You only need to run it when you add text that you haven't typed (eg copy/paste from your example).
Therefore, use that code in the TextChanged event, but perform a check before running it as to whether the user has typed the text or added it another way
EDIT: Check the answer to this question: Detecting a paste into a RichTextBox, it might help you
I've created Windows forms and I'm using the textbox control for input, but I like to use it without border and other layout for textbox etc. I just want to use a underscore line and blinking cursor.
I played with the borderStyle (Fixed3D, None), backcolor=InactiveBorder etc. But I still do net get the underline... like this-> _____________ result like this: This is underline______________
I think Backcolor=InactiveBorder and BorderStyle=None is ok to use, but how to get the underline and blinking cursor?
Requirement:
blinking cursor and underline. (The doesn't blink by default, I just see a vertical line))
To fake this, you could add a label below the text box with the content being _____________________. My preferred solution would be to create a simple custom control that just draws a line.
Doesn't the caret on your system blink by default? It does on my system if the focus is on the text box.
If the caret doesn't blink by default, go to the Windows Control Panel and check your Keyboard Settings there - this is the place where you can adjust the caret blink rate.
For creating a underline for your textbox you can do like this,
First add a panel which is in the height of text box's height + underline's height.
Now add your textbox inside of that panel and set its dock to TOP.
Then set the textbox's border to none.
Now set the backcolor of the panel, according to the color need of underline.
Update:
This is VB code, i hope that you can easily convert it into c#
[ Concept: You just need to set the border for all of your textboxes as none.then In forms paint event track those text boxes and draw a line under it. ]
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Me.Paint
Using xPen As Pen = New Pen(Color.Blue)
' Here we are using LINQ to filter the controls.
' If you don't want it, you just check all the controls by using typeof
' inside the For Each loop.
For Each xTxtBox In Me.Controls.OfType(Of TextBox)()
e.Graphics.DrawLine(xPen,
xTxtBox.Location.X,
xTxtBox.Location.Y + xTxtBox.Height,
xTxtBox.Location.X + xTxtBox.Width,
xTxtBox.Location.Y + xTxtBox.Height)
Next
End Using
End Sub
Use Masked TextBox and set Focus , e.g. maskedtextbox1.Focus(); <== this is for the blinking cursor and the masked textbox to the underline !
try :
To set logical focus to an input control
FocusManager.SetFocusedElement(this, textboxJack);
To set keyboard focus to an input control
Keyboard.Focus(textboxJill);
and for the masked textbox you can set a mask that will not be changed when you delete the text from it not like the simple textbox :)
Good luck
To do this, I would recommend creating a custom control (which is accomplished in the WinForms world by inheriting from one of the provided control classes). That custom control would then:
Provide its own drawing logic (by overriding OnPaint) in order to draw the underline and skip drawing anything else you don't want to see (e.g., the borders of the control).
Create its own caret when it receives the focus, and destroy that caret when it loses the focus. You'll find all the details on how to do this in my answer here.
You can also configure the blink rate of the caret by calling the SetCaretBlinkTime function. But note that this is not recommended, as it changes the global system setting and therefore affects other applications. It is best to do as Thorsten suggests and modify the setting on your machine if you wish to see something different. You should always respect a user's settings. There's a reason that they (or someone else) set up their system to not blink the caret.
Naturally, you will need to use P/Invoke to call these Win32 API functions related to caret management from a C# application. That shouldn't be too difficult if you know what you're doing. If you need a complete solution, consider setting a bounty on this question to persuade me to write one up for you.
I faced the same issue and built something that works fine:
public class TextBox : System.Windows.Forms.TextBox
{
public TextBox()
{
BorderStyle = BorderStyle.None;
Text = "__________"; //Sometime this doesn't work while creating the control in design mode ; don't know why
}
//protected override void OnFontChanged(EventArgs e)
//{
// base.OnFontChanged(e);
// RefreshHeight();
//}
bool loaded = false;
protected override void OnCreateControl()
{
if(!loaded)
RefreshHeight();
base.OnCreateControl();
}
private void RefreshHeight()
{
loaded = true;
Multiline = true;
Size s = TextRenderer.MeasureText(Text, Font, Size.Empty, TextFormatFlags.TextBoxControl);
MinimumSize = new Size(0, s.Height + 1);
Multiline = false;
}
}
I used bool loaded = false to avoid the app to crash in a loop because of OnCreateControl. TextBox control doesn't have OnLoad event (I'm open to another approach).
OnFontChanged can be uncommented if your app change the font size in run time
MinimumSize = new Size(0, s.Height + 1); I added 1 to avoid any error of MeasureText
I've implemented "ChangeCase" keyboard shortcut (like Shift+F3 in MS WORD) for RichTextBox, which changes the text either selected by mouse, or the last word before caret's position. The problem is, it SOMETIMES loses the selection, or moves the caret one word left.
Once it changes the textcase without this changing of caret position, then it never changes the caret position (propably some WPF's internal caching.), so it can only happen the first time i run this function to a portion of text.
The code used is the solution mentioned in here WPF Flowdocument "change case" feature .
One problematic section of code is certainly
end = this.CaretPosition;
EditingCommands.MoveLeftByWord.Execute(null, this);
start = this.CaretPosition;
this.CaretPosition = end;
However I have no idea why it only occurs sometimes and how to fix this.
I thing it has something to do with the execution speed of this Execute() method and some side effects, because at my WPF app it only happens sometimes, but when hosting this WPF control in Winforms, moving the caret one word left happens all the time (if I hold Shift+F3, the cursor moves word by word to the very beginning of the document)
Other problem can be related with changing text of a TextRange, which is resulting in losing the selection? But again, it doesnt happen all the time and I have no clue how to fix it.
Any ideas?
I ended up with 2 options, ignoring this error or implementing the
MoveLeftByWord
logic manully without touching the
CaretPosition
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