web-dev-qa-db-ja.com

C#のコードでテキストボックスを下にスクロールする方法

私はwinformsを使用していて、テキストボックスをときどき更新しています(メッセージを表示しています)。ただし、テキストがボックスの最後に到達すると、スクロールバーが生成され、一番下までスクロールする方法がわかりません。私が目にするのはScrollToCaretだけですが、キャレットはテキストの先頭にあります。スクロールするコマンドは何ですか?

25
Nefzen

これを行うには、ScrollToCaretという関数を使用します。最初にキャレット位置をテキストボックスの末尾に設定する必要があります。次にスクロールできます。方法は次のとおりです。

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

これは少し古い質問ですが、提案された回答はどれも機能しませんでした(ScrollToCaret()は、TextBoxにフォーカスがある場合にのみ機能します)。それで、これがいつかこれを検索する必要がある場合は、私が解決策であることがわかったものを共有したいと思いました:

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

ソリューションのクレジットは、bytes.comのこの投稿に移動する必要があります。 http://bytes.com/topic/c-sharp/answers/248500-scroll-bottom-textbox#post1005377

27
Julian

TextboxのAppendText()メソッドを使用する場合、テキストは既存のテキストの下部に追加され、コントロールはスクロールして表示します。

14
Metro

テキストの最後にキャレットを設定する必要があります:

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

C#Windows API(user32.dll)で上下にスクロール

まず、定数値を定義する必要があります。

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

次に、user32.dllの2つの外部メソッドを宣言する必要があります。

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

最後に、これらのメソッドを使用して実際のことを行います。

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

できた!シンプルで簡単!テスト済み! 元の投稿

2
Toxig

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

(未試験)

0
Thomas Levesque

フォーカスがある場合とない場合、および水平方向と垂直方向の両方で機能する正当なソリューションを検索して見つけなかった後、機能する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);
        }
    }
}

複数行のテキストボックス(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);
0
Joe