Le contrôle RichTextBox défile automatiquement jusqu'à la sélection en cours, si la sélection n'est pas masquée. RichTextBox.AppendText(), en plus de l'ajout de texte, modifie également la sélection en cours, et déclenche donc indirectement le comportement "autoscrolling". Notez que si RichTextBox.HideSelection est défini sur true, la sélection sera masquée lorsque le contrôle n'est pas actif; cela explique le comportement que vous avez décrit, où le défilement automatique se produit uniquement lorsque l'utilisateur clique sur le contrôle. (Ce qui lui confère mise au point) Pour éviter cela, vous devez faire ce qui suit lors de l'ajout du texte:
- Sauvegarde de la sélection initiale
- Unfocus le contrôle
- Cacher la sélection (par un message Windows)
- AppendText
- Restaurer la sélection initiale
- Unhide sélection
- Recentrer le contrôle
Vous pouvez également vérifier si la sélection est déjà à la fin du texte et autoriser le comportement de défilement automatique s'il est - cela émule essentiellement le comportement de la fenêtre Sortie de Visual Studio. Par exemple:
[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();
}
}
Votre solution fonctionne comme un charme! J'ai essayé tant d'autres approches pour empêcher mon RichTextBox de défiler après avoir apporté des changements de mise en forme, et c'était le seul qui fonctionnait. Cela semblait alambiqué au début, mais ça a marché :) –