Formant RichTextBox automatycznie przewija do bieżącego wyboru, jeśli zaznaczenie nie jest ukryte. RichTextBox.AppendText(), oprócz dołączania tekstu, modyfikuje również bieżący wybór, a więc pośrednio uruchamia zachowanie "autoskradania". Zauważ, że jeśli RichTextBox.HideSelection jest ustawione na true, to wybór będzie ukryty, gdy kontrola nie będzie fokusowana; to wyjaśnia opisane zachowanie, w którym automatyczne przewijanie występuje tylko wtedy, gdy użytkownik kliknie kontrolkę. (Tym samym dając mu skupić) Aby temu zapobiec, należy wykonać następujące czynności podczas dopisywania tekstu:
- zapasowa wstępnej selekcji
- unfocus kontrola
- wybór Hide (poprzez wiadomości w systemie Windows)
- appendText
- przywrócenia pierwotnego wyboru wybór
- Unhide
- przeorientowania sterowania
Można również sprawdzić, czy zaznaczenie znajduje się już na końcu tekstu, i zezwolić na automatyczne przewijanie, jeśli tak - to zasadniczo emuluje zachowanie okna wyjściowego programu Visual Studio. Na przykład: rozwiązanie
[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();
}
}
Twoje rozwiązanie działa jak urok! Próbowałem wielu innych podejść, aby uniemożliwić przewijanie RichTextBox po wprowadzeniu zmian formatowania i tylko on działał. Początkowo wydawało się zawiłe, ale zadziałało :) –