Элемент управления RichTextBox автоматически прокручивается до текущего выделения, если оно не скрыто. RichTextBox.AppendText (), помимо добавления текста, также изменяет текущее выделение и, таким образом, косвенно вызывает поведение «автопрокрутки». Обратите внимание, что если для RichTextBox.HideSelection установлено значение true, то выбор будет скрыт, когда элемент управления не в фокусе; это объясняет поведение, которое вы описали, когда автоматическая прокрутка происходит только тогда, когда пользователь щелкает элемент управления. (тем самым придавая этому фокус)
Чтобы предотвратить это, вам нужно сделать следующее при добавлении текста:
- Резервное копирование начального выбора
- Расфокусировать управление
- Скрыть выбор (через сообщение Windows)
- AppendText
- Восстановить начальный выбор
- Показать выборку
- Перефокусировка управления
Вы можете также захотеть проверить, находится ли выделение уже в конце текста, и разрешить поведение автопрокрутки, если оно есть - это по сути эмулирует поведение окна вывода Visual Studio. Например:
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
const int WM_USER = 0x400;
const int EM_HIDESELECTION = WM_USER + 63;
void OnAppend(string text)
{
bool focused = richTextBox1.Focused;
//backup initial selection
int selection = richTextBox1.SelectionStart;
int length = richTextBox1.SelectionLength;
//allow autoscroll if selection is at end of text
bool autoscroll = (selection==richTextBox1.Text.Length);
if (!autoscroll)
{
//shift focus from RichTextBox to some other control
if (focused) textBox1.Focus();
//hide selection
SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 1, 0);
}
richTextBox1.AppendText(text);
if (!autoscroll)
{
//restore initial selection
richTextBox1.SelectionStart = selection;
richTextBox1.SelectionLength = length;
//unhide selection
SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 0, 0);
//restore focus to RichTextBox
if(focused) richTextBox1.Focus();
}
}