简体   繁体   English

如何通过C#中的代码向下滚动文本框

[英]How to scroll down in a textbox by code in C#

I am using winforms, and I update a text box once in a while (showing messages). 我正在使用winforms,我偶尔会更新一个文本框(显示消息)。 however, when the text reaches the end of the box it produces scrollbars and I don't know how to scroll down to the bottom. 但是,当文本到达框的末尾时,它会生成滚动条,我不知道如何向下滚动到底部。 The only thing I see is ScrollToCaret, but Caret is at the beginning of the text. 我唯一看到的是ScrollToCaret,但Caret正处于文本的开头。 What is the command to scroll? 滚动的命令是什么?

You can do this by making use of a function called ScrollToCaret. 您可以通过使用名为ScrollToCaret的函数来完成此操作。 You need to first set the caret position to the end of the text box, then you can scroll to it. 您需要先将插入位置设置到文本框的末尾,然后滚动到它。 Here's how to do it: 这是怎么做的:

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

This is a bit of an old question, but none of the suggested answers worked for me (ScrollToCaret() only works when the TextBox has focus). 这是一个古老的问题,但没有一个建议的答案对我有效(ScrollToCaret()仅在TextBox具有焦点时才有效)。 So in case any more should be searching for this at some point, I thought I'd share what I found to be the 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);
    }
}

Credit for the solution should go to this post at bytes.com: http://bytes.com/topic/c-sharp/answers/248500-scroll-bottom-textbox#post1005377 该解决方案应该归功于bytes.com上的这篇文章: http ://bytes.com/topic/c-sharp/answers/248500-scroll-bottom-textbox#post1005377

如果使用文本框的AppendText()方法,则文本将添加到任何现有文本的底部,控件将滚动以显示它。

You need to set your caret at the end of your text: 您需要在文本末尾设置插入符号:

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

C# Use Scroll Up/Down by Windows API (user32.dll) C#使用Windows API向上/向下滚动(user32.dll)

First, we have to define a constant value: 首先,我们必须定义一个常量值:

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

Then, we have to declare two external methods of user32.dll: 然后,我们必须声明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);

Finally, use these methods to do the real thing: 最后,使用这些方法来做真实的事情:

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

Done! 完成! Simple and easy! 简单易行! Tested! 经测试! original post 原帖

You can use the SetScrollPos API : 您可以使用SetScrollPos API:

[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);
    }
}

(untested) (另)

After searching and never finding a legitimate solution that works with and without focus as well as horizontally and vertically, I stumbled across an API solution that works (at least for my platform - Win7 / .Net4 WinForms). 在搜索并且从未找到一个合法的解决方案,无论是否有焦点以及水平和垂直方式,我偶然发现了一个有效的API解决方案(至少对我的平台来说 - 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);
        }
    }
}

With a multiline textbox (tbx_main) use like: 使用多行文本框(tbx_main)使用如下:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM