How can I append text to a textbox without scrolling and maintaining the current caret position AppendText() always scrolls to the bottom, and setting the Text property scrolls to the top.
The standard way would be to call BeginUpdate/EndUpdate but unfortunately the edit control is too old to support this. The RichTextBox might provide better behavior for you. Alternatively you could derive a new class from TextBox and override the OnPaint method. Within OnPaint check to see if you are in the middle of an append (a flag you'd set when appending text). If so then ignore the paint request. It's a hack and it might not work but it is a thought.
Yes, unfortunately the .NET TextBox control doesn't work quite the way we'd like. You could probably hack together a solution that uses SelectionStart/SelectionLength to reselect the appropriate text after the append but then you'll need to worry about getting the selection back into focus. Keep in mind that the .NET version doesn't provide any way to determine the first visible character in the text box which is what you'd need to ensure that the box didn't jump.
The better option might just be to call out to unmanaged code to do the work. The message EM_REPLACESEL is used to replace the existing selection in an edit control and/or insert text at the current caret position. You could save off the current selection, set the caret to the end of the control, send the message and then reset the selection. Provided you don't use the .NET methods to move the caret the edit control probably won't jump.
I have played already with EM_REPLACESEL, unfortunately it jumps. The "remember position - append text - restore position" approach works, but the whole control is flickering. Is there an easy way to remove the flicker Like to disable control update for a while.
pinvoke LockWindowUpdate should do the trick. Save the current position then "lock" the window, make your append then move back the the saved position then call LockWindowUpdate again with a null or a intptr.zero to unlock the window. Im using it to get around some nasty paint problems with the TextBox and it seems to work.
<DllImport(
"user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _ Public Shared Function LockWindowUpdate(ByVal hWnd As IntPtr) As Boolean End Function
Append text to textbox without scrolling
kmax
The standard way would be to call BeginUpdate/EndUpdate but unfortunately the edit control is too old to support this. The RichTextBox might provide better behavior for you. Alternatively you could derive a new class from TextBox and override the OnPaint method. Within OnPaint check to see if you are in the middle of an append (a flag you'd set when appending text). If so then ignore the paint request. It's a hack and it might not work but it is a thought.
Michael Taylor - 1/25/06
Dens
Howard Yu
mokeefe
Yes, unfortunately the .NET TextBox control doesn't work quite the way we'd like. You could probably hack together a solution that uses SelectionStart/SelectionLength to reselect the appropriate text after the append but then you'll need to worry about getting the selection back into focus. Keep in mind that the .NET version doesn't provide any way to determine the first visible character in the text box which is what you'd need to ensure that the box didn't jump.
The better option might just be to call out to unmanaged code to do the work. The message EM_REPLACESEL is used to replace the existing selection in an edit control and/or insert text at the current caret position. You could save off the current selection, set the caret to the end of the control, send the message and then reset the selection. Provided you don't use the .NET methods to move the caret the edit control probably won't jump.
Michael Taylor - 1/25/06
loosie
Shelly
Arthur Knight
pinvoke LockWindowUpdate should do the trick. Save the current position then "lock" the window, make your append then move back the the saved position then call LockWindowUpdate again with a null or a intptr.zero to unlock the window. Im using it to get around some nasty paint problems with the TextBox and it seems to work.
<DllImport(
"user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _Public Shared Function LockWindowUpdate(ByVal hWnd As IntPtr) As Boolean
End Function
LockWindowUpdate(me.Handle)
do the work...
LockWindowUpdate(IntPtr.Zero)