Ich habe ein Textfeld mit der Eigenschaft "Multiline" auf "true" gesetzt. In regelmäßigen Abständen füge ich neue Textzeilen hinzu. Ich möchte, dass das Textfeld automatisch zum untersten Eintrag (dem neuesten) blättert, wenn eine neue Zeile hinzugefügt wird. Wie kann ich das erreichen?
Antworten
Zu viele Anzeigen?In regelmäßigen Abständen füge ich neue Textzeilen hinzu. Ich möchte, dass das Textfeld automatisch zum untersten Eintrag (dem neuesten) blättert, wenn eine neue Zeile hinzugefügt wird.
Wenn Sie TextBox.AppendText(string text)
drücken, wird automatisch bis zum Ende des neu hinzugefügten Textes geblättert. Dadurch wird die flackernde Bildlaufleiste vermieden, wenn Sie die Funktion in einer Schleife aufrufen.
Es ist auch um eine Größenordnung schneller als die Verkettung mit dem .Text
Eigentum. Obwohl das könnte davon abhängen, wie oft Sie es aufrufen; Ich war mit einer engen Schleife testen.
Es wird nicht gescrollt, wenn es aufgerufen wird, bevor das Textfeld angezeigt wird, oder wenn das Textfeld anderweitig nicht sichtbar ist (z.B. in einer anderen Registerkarte eines TabPanels). Siehe TextBox.AppendText() scrollt nicht automatisch . Dies kann wichtig oder unwichtig sein, je nachdem, ob Sie einen automatischen Bildlauf benötigen, wenn der Benutzer das Textfeld nicht sehen kann.
Es scheint, dass die alternative Methode aus den anderen Antworten auch in diesem Fall nicht funktioniert. Eine Möglichkeit, das Problem zu umgehen, ist die Durchführung eines zusätzlichen Bildlaufs auf der VisibleChanged
Veranstaltung:
textBox.VisibleChanged += (sender, e) =>
{
if (textBox.Visible)
{
textBox.SelectionStart = textBox.TextLength;
textBox.ScrollToCaret();
}
};
Intern, AppendText
funktioniert in etwa so:
textBox.Select(textBox.TextLength + 1, 0);
textBox.SelectedText = textToAppend;
Aber es sollte keinen Grund geben, dies manuell zu tun.
(Wenn Sie es selbst dekompilieren, werden Sie sehen, dass es einige möglicherweise effizientere interne Methoden verwendet und einen scheinbar unbedeutenden Sonderfall hat).
textBox1.Focus()
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
funktionierte bei mir nicht (Windows 8.1, warum auch immer).
Und da ich noch mit .NET 2.0 arbeite, kann ich ScrollToEnd nicht verwenden.
Aber das funktioniert:
public class Utils
{
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern int SendMessage(System.IntPtr hWnd, int wMsg, System.IntPtr wParam, System.IntPtr lParam);
private const int WM_VSCROLL = 0x115;
private const int SB_BOTTOM = 7;
/// <summary>
/// Scrolls the vertical scroll bar of a multi-line text box to the bottom.
/// </summary>
/// <param name="tb">The text box to scroll</param>
public static void ScrollToBottom(System.Windows.Forms.TextBox tb)
{
if(System.Environment.OSVersion.Platform != System.PlatformID.Unix)
SendMessage(tb.Handle, WM_VSCROLL, new System.IntPtr(SB_BOTTOM), System.IntPtr.Zero);
}
}
VB.NET:
Public Class Utils
<System.Runtime.InteropServices.DllImport("user32.dll", CharSet := System.Runtime.InteropServices.CharSet.Auto)> _
Private Shared Function SendMessage(hWnd As System.IntPtr, wMsg As Integer, wParam As System.IntPtr, lParam As System.IntPtr) As Integer
End Function
Private Const WM_VSCROLL As Integer = &H115
Private Const SB_BOTTOM As Integer = 7
''' <summary>
''' Scrolls the vertical scroll bar of a multi-line text box to the bottom.
''' </summary>
''' <param name="tb">The text box to scroll</param>
Public Shared Sub ScrollToBottom(tb As System.Windows.Forms.TextBox)
If System.Environment.OSVersion.Platform <> System.PlatformID.Unix Then
SendMessage(tb.Handle, WM_VSCROLL, New System.IntPtr(SB_BOTTOM), System.IntPtr.Zero)
End If
End Sub
End Class
- See previous answers
- Weitere Antworten anzeigen