364 Stimmen

Wie kann ich in einem mehrzeiligen Textfeld automatisch zum unteren Rand blättern?

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?

519voto

Bob Punkte 13881

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).

169voto

GWLlosa Punkte 23282

Sie können den folgenden Codeschnipsel verwenden:

myTextBox.SelectionStart = myTextBox.Text.Length;
myTextBox.ScrollToCaret();

und blättert automatisch bis zum Ende.

43voto

JohnDRoach Punkte 694

Anscheinend hat sich die Schnittstelle in .NET 4.0. Es gibt die folgenden méthode die alle oben genannten Punkte erfüllt. Wie Tommy Engebretsen vorgeschlagen, setzen es in einem TextChanged Event-Handler macht es automatisch.

textBox1.ScrollToEnd();

18voto

Versuchen Sie, den vorgeschlagenen Code zum TextChanged-Ereignis hinzuzufügen:

private void textBox1_TextChanged(object sender, EventArgs e)
{
  textBox1.SelectionStart = textBox1.Text.Length;
  textBox1.ScrollToCaret();
}

16voto

Stefan Steiger Punkte 72861
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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X