c# - word - textbox vba enter




Como faço para rolar automaticamente para a parte inferior de uma caixa de texto de múltiplas linhas? (8)

Em intervalos regulares, estou adicionando novas linhas de texto a ele. Eu gostaria que a caixa de texto fosse automaticamente rolada para a entrada mais abaixo (a mais nova) sempre que uma nova linha fosse adicionada.

Se você usar TextBox.AppendText(string text) , ele rolará automaticamente até o final do texto recém-adicionado. Isso evita a barra de rolagem se você estiver chamando em um loop.

Também acontece de ser uma ordem de grandeza mais rápida do que concatenar na propriedade .Text . Embora isso possa depender de quantas vezes você está ligando; Eu estava testando com um loop apertado.

Isso não rolará se for chamado antes da exibição da caixa de texto ou se a caixa de texto não estiver visível (por exemplo, em uma guia diferente de um TabPanel). Veja TextBox.AppendText () não autoscrolling . Isso pode ou não ser importante, dependendo se você precisar de autoscroll quando o usuário não pode ver a caixa de texto.

Parece que o método alternativo das outras respostas também não funciona nesse caso. Uma maneira de contornar isso é realizar rolagem adicional no evento VisibleChanged :

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

Internamente, o AppendText faz algo assim:

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

Mas não deve haver razão para fazê-lo manualmente.

(Se você mesmo descompilar, verá que ele usa alguns métodos internos possivelmente mais eficientes e tem o que parece ser um caso especial menor).

Eu tenho uma caixa de texto com a propriedade .Multiline definida como true. Em intervalos regulares, estou adicionando novas linhas de texto a ele. Eu gostaria que a caixa de texto fosse automaticamente rolada para a entrada mais abaixo (a mais nova) sempre que uma nova linha fosse adicionada. Como faço isso?


Eu encontrei uma diferença simples que não foi abordada neste tópico.

Se você estiver fazendo todas as chamadas ScrollToCarat() como parte do evento Load() do seu formulário, isso não funcionará. Acabei de adicionar minha chamada ScrollToCarat() ao evento Activated() meu formulário e ele funciona bem.

Editar

É importante fazer somente essa rolagem na primeira vez que o evento Activated do formulário é acionado (não em ativações subsequentes), ou ele rolará toda vez que o formulário for ativado, o que é algo que você provavelmente não deseja.

Portanto, se você estiver apenas interceptando o evento Activated() para rolar o texto quando o programa for carregado, será possível cancelar a inscrição no evento dentro do próprio manipulador de eventos, assim:

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

Se você tiver outras coisas que precisa fazer toda vez que seu formulário for ativado, você pode definir um bool como true na primeira vez que seu evento de Activated() for disparado, para que você não role em ativações subsequentes, mas ainda possa fazer o outro. coisas que você precisa fazer.

Além disso, se seu TextBox estiver em uma guia que não é a SelectedTab , ScrollToCarat() não terá efeito. Então você precisa pelo menos torná-lo a aba selecionada enquanto você está rolando. Você pode quebrar o código em um YourTab.SuspendLayout(); e YourTab.ResumeLayout(false); par se seu formulário piscar quando você fizer isso.

Fim da edição

Espero que isto ajude!


Eu uso uma função para isso:

private void Log (string s) {
    TB1.AppendText(Environment.NewLine + s);
    TB1.ScrollToCaret();
}

Isso rolará até o final da caixa de texto quando o texto for alterado, mas ainda permitirá ao usuário rolar para cima

outbox.SelectionStart = outbox.Text.Length;
outbox.ScrollToEnd();

testado no Visual Studio Enterprise 2017


Para qualquer outra pessoa que esteja chegando aqui esperando ver uma implementação de webforms, você deseja usar o manipulador de eventos endRequest do Gerenciador de Solicitação de Página ( https://.com/a/1388170/1830512 ). Aqui está o que eu fiz para o meu TextBox em uma página de conteúdo de uma página mestra, por favor, ignore o fato de que eu não usei uma variável para o controle:

var prm = Sys.WebForms.PageRequestManager.getInstance();

function EndRequestHandler() {
    if ($get('<%= ((TextBox)StatusWindow.FindControl("StatusTxtBox")).ClientID %>') != null) {
        $get('<%= ((TextBox)StatusWindow.FindControl("StatusTxtBox")).ClientID %>').scrollTop = 
        $get('<%= ((TextBox)StatusWindow.FindControl("StatusTxtBox")).ClientID %>').scrollHeight;
    }
}

prm.add_endRequest(EndRequestHandler);

Parece que a interface mudou no .NET 4.0. Existe o seguinte method que atinge todos os itens acima. Como Tommy Engebretsen sugeriu, colocá-lo em um manipulador de eventos TextChanged torna isso automático.

textBox1.ScrollToEnd();

Você pode usar o seguinte trecho de código:

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

que irá automaticamente rolar para o final.


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

não funcionou para mim (Windows 8.1, seja qual for o motivo).
E como ainda estou no .NET 2.0, não posso usar ScrollToEnd.

Mas isso funciona:

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






scroll