[C#] 여러 줄 텍스트 상자의 맨 아래로 자동 스크롤하는 방법

.Multiline 속성이 true로 설정된 텍스트 상자가 있습니다. 정기적으로 새로운 줄의 텍스트를 추가하고 있습니다. 새 줄이 추가 될 때마다 텍스트 상자가 가장 맨 아래 항목 (가장 최신 항목)으로 자동 스크롤되도록하고 싶습니다. 어떻게하면 되나요?



답변

정기적으로 새로운 줄의 텍스트를 추가하고 있습니다. 새 줄이 추가 될 때마다 텍스트 상자가 가장 맨 아래 항목 (가장 최신 항목)으로 자동 스크롤되도록하고 싶습니다.

를 사용 TextBox.AppendText(string text)하면 새로 추가 된 텍스트의 끝으로 자동 스크롤됩니다. 루프에서 호출하면 깜박이는 스크롤 막대를 피할 수 있습니다.

또한 .Text속성에 연결하는 것보다 훨씬 빠릅니다 . 그것은 당신이 그것을 얼마나 자주 부르는지에 달려 있습니다. 나는 단단한 루프로 테스트하고있었습니다.


텍스트 상자가 표시되기 전에 호출되거나 텍스트 상자가 표시되지 않는 경우 (예 : TabPanel의 다른 탭에서) 스크롤되지 않습니다. 자동 스크롤이 아닌 TextBox.AppendText ()를 참조하십시오 . 사용자가 텍스트 상자를 볼 수 없을 때 자동 스크롤이 필요한지 여부에 따라 중요하거나 중요하지 않을 수 있습니다.

이 경우 다른 답변의 대체 방법도 작동하지 않는 것 같습니다. 한 가지 방법은 VisibleChanged이벤트 에서 추가 스크롤을 수행하는 것입니다 .

textBox.VisibleChanged += (sender, e) =>
{
    if (textBox.Visible)
    {
        textBox.SelectionStart = textBox.TextLength;
        textBox.ScrollToCaret();
    }
};

내부적으로 AppendText다음과 같은 작업을 수행합니다.

textBox.Select(textBox.TextLength + 1, 0);
textBox.SelectedText = textToAppend;

그러나 수동으로 할 이유가 없습니다.

(직접 디 컴파일하면 더 효율적인 내부 메소드를 사용하고 사소한 특수한 경우가 있음을 알 수 있습니다.)


답변

다음 코드 스 니펫을 사용할 수 있습니다.

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

자동으로 끝까지 스크롤됩니다.


답변

.NET 4.0 에서 인터페이스가 변경된 것 같습니다 . 위의 모든 것을 달성 하는 다음과 같은 방법 이 있습니다. Tommy Engebretsen이 제안했듯이 TextChanged 이벤트 핸들러에 넣으면 자동으로 만들어집니다.

textBox1.ScrollToEnd();


답변

TextChanged 이벤트에 제안 된 코드를 추가하십시오.

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


답변

textBox1.Focus()
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();

나를 위해 작동하지 않았습니다 (이유가 무엇이든 Windows 8.1).
그리고 여전히 .NET 2.0을 사용하고 있기 때문에 ScrollToEnd를 사용할 수 없습니다.

그러나 이것은 작동합니다.

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


답변

새로 고침을 추가해야했습니다.

textBox1.SelectionStart = textBox1.Text.Length;
textBox1.ScrollToCaret();
textBox1.Refresh();


답변

이 스레드에서 해결되지 않은 간단한 차이점을 발견했습니다.

ScrollToCarat()양식 Load()이벤트 의 일부로 모든 통화를 수행하면 작동하지 않습니다. 방금 ScrollToCarat()양식의 Activated()이벤트에 전화를 추가 했는데 정상적으로 작동합니다.

편집하다

양식의 Activated이벤트가 처음 실행될 때 (이후 활성화 시가 아님) 에만이 스크롤을 수행 하거나 양식이 활성화 마다 스크롤하는 것이 중요합니다 .

따라서 Activated()프로그램이로드 될 때 텍스트를 스크롤하기 위해 이벤트를 잡는 경우 이벤트 핸들러 자체의 이벤트를 구독 취소하면됩니다.

Activated -= new System.EventHandler(this.Form1_Activated);

양식이 활성화 될 때마다 수행해야 할 다른 작업이있는 경우 이벤트가 bool처음 Activated()발생할 때 a 를 true로 설정하여 후속 활성화를 스크롤하지는 않지만 필요한 다른 작업을 계속 수행 할 수 있습니다. 하다.

귀하의 경우에도 TextBox탭에이되지 않는 SelectedTab, ScrollToCarat()아무런 영향을주지 않습니다. 따라서 스크롤하는 동안 적어도 선택된 탭으로 만들어야합니다. 이 작업을 수행 할 때 양식이 깜박이면 코드를 a YourTab.SuspendLayout();및 랩으로 묶을 수 있습니다 YourTab.ResumeLayout(false);.

편집 종료

도움이 되었기를 바랍니다!