web-dev-qa-db-fra.com

Comment faire défiler dans une zone de texte par code en C #

J'utilise winforms, et je mets à jour une zone de texte de temps en temps (affichant des messages). Cependant, lorsque le texte atteint la fin de la zone, il produit des barres de défilement et je ne sais pas comment faire défiler l'écran vers le bas. le fond. La seule chose que je vois est ScrollToCaret, mais Caret est au début du texte. Quelle est la commande pour faire défiler?

24
Nefzen

Vous pouvez le faire en utilisant une fonction appelée ScrollToCaret. Vous devez d’abord définir la position du curseur à la fin de la zone de texte, puis vous pouvez y accéder. Voici comment le faire: 

        //move the caret to the end of the text
        textBox.SelectionStart = textBox.TextLength;
        //scroll to the caret
        textBox.ScrollToCaret();
34
Doctor Jones

C'est une question un peu ancienne, mais aucune des réponses suggérées n'a fonctionné pour moi (ScrollToCaret () ne fonctionne que lorsque la zone de texte a le focus). Donc, au cas où plus de personnes chercheraient cela à un moment donné, j'ai pensé partager ce que j'ai trouvé être la solution:

public class Utils
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, 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(TextBox tb)
    {
        SendMessage(tb.Handle, WM_VSCROLL, (IntPtr)SB_BOTTOM, IntPtr.Zero);
    }
}

Le crédit pour la solution devrait aller à ce message à bytes.com: http://bytes.com/topic/c-sharp/answers/248500-scroll-bottom-textbox#post1005377

27
Julian

Si vous utilisez la méthode AppendText () de la zone de texte, le texte sera ajouté au bas de tout texte existant et le contrôle défilera pour l'afficher.

14
Metro

Vous devez définir votre signe à la fin de votre texte:

textBox1.Text += "your new text";
textBox1.Select(textBox1.Text.Length - 1, 0);
textBox1.ScrollToCaret();
4
Francis B.

C # Utiliser Scroll Up/Down par Windows API (user32.dll)

Tout d'abord, nous devons définir une valeur constante:

const int EM_LINESCROLL = 0x00B6;
const int SB_HORZ = 0;
const int SB_VERT = 1;

Ensuite, nous devons déclarer deux méthodes externes de user32.dll:

[DllImport("user32.dll")]
static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);

Enfin, utilisez ces méthodes pour faire la vraie chose:

SetScrollPos(myTextBox.Handle,SB_VERT,myTextBox.Lines.Length-1,true);
SendMessage(myTextBox.Handle,EM_LINESCROLL,0,myTextBox.Lines.Length-1);

Terminé! Simple et facile! Testé! message original

2
Toxig

Vous pouvez utiliser l'API SetScrollPos:

[DllImport("user32.dll")]
static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

[DllImport("user32.dll")]
static extern bool GetScrollRange(IntPtr hWnd, int nBar, out int lpMinPos, out int lpMaxPos);

const int SB_HORZ = 0;
const int SB_VERT = 1;
const int SB_CTL = 2;


...

void ScrollToBottom(Control ctl)
{
    int min;
    int max;
    if (GetScrollRange(ctl.Handle, SB_VERT, out min, out max))
    {
        SetScrollPos(ctl.Handle, SB_VERT, max, true);
    }
}

(non testé)

0
Thomas Levesque

Après avoir cherché et jamais trouvé une solution légitime qui fonctionne avec et sans focus, horizontalement et verticalement, je suis tombé sur une solution API qui fonctionne (du moins pour ma plate-forme - Win7/.Net4 WinForms).

using System;
using System.Runtime.InteropServices;

namespace WindowsNative
{
    /// <summary>
    /// Provides scroll commands for things like Multiline Textboxes, UserControls, etc.
    /// </summary>
    public static class ScrollAPIs
    {
        [DllImport("user32.dll")]
        internal static extern int GetScrollPos(IntPtr hWnd, int nBar);

        [DllImport("user32.dll")]
        internal static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

        [DllImport("user32.dll")]
        internal static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

        public enum ScrollbarDirection
        {
            Horizontal = 0,
            Vertical = 1,
        }

        private enum Messages
        {
            WM_HSCROLL = 0x0114,
            WM_VSCROLL = 0x0115
        }

        public static int GetScrollPosition(IntPtr hWnd, ScrollbarDirection direction)
        {
            return GetScrollPos(hWnd, (int)direction);
        }

        public static void GetScrollPosition(IntPtr hWnd, out int horizontalPosition, out int verticalPosition)
        {
            horizontalPosition = GetScrollPos(hWnd, (int)ScrollbarDirection.Horizontal);
            verticalPosition = GetScrollPos(hWnd, (int)ScrollbarDirection.Vertical);
        }

        public static void SetScrollPosition(IntPtr hwnd, int hozizontalPosition, int verticalPosition)
        {
            SetScrollPosition(hwnd, ScrollbarDirection.Horizontal, hozizontalPosition);
            SetScrollPosition(hwnd, ScrollbarDirection.Vertical, verticalPosition);
        }

        public static void SetScrollPosition(IntPtr hwnd, ScrollbarDirection direction, int position)
        {
            //move the scroll bar
            SetScrollPos(hwnd, (int)direction, position, true);

            //convert the position to the windows message equivalent
            IntPtr msgPosition = new IntPtr((position << 16) + 4);
            Messages msg = (direction == ScrollbarDirection.Horizontal) ? Messages.WM_HSCROLL : Messages.WM_VSCROLL;
            SendMessage(hwnd, (int)msg, msgPosition, IntPtr.Zero);
        }
    }
}

Avec une zone de texte multiligne (tbx_main), utilisez comme suit:

        int horzPos, vertPos;
        ScrollAPIs.GetScrollPosition(tbx_main.Handle, out horzPos, out vertPos);

        //make your changes
        //something like the following where m_buffer is a string[]
        tbx_main.Text = string.Join(Environment.NewLine, m_buffer);

        tbx_main.SelectionStart = 0;
        tbx_main.SelectionLength = 0;

        ScrollAPIs.SetScrollPosition(tbx_main.Handle, horzPos, vertPos);
0
Joe