How can I scroll to a specified line in a WinForms

2019-01-25 07:00发布

问题:

How can I scroll to a specified line in a WinForms TextBox using C#?

Thanks

回答1:

Here's how you scroll to the selection:

textBox.ScrollToCaret();

To scroll to a specified line, you could loop through the TextBox.Lines property, total their lengths to find the start of the specified line and then set TextBox.SelectionStart to position the caret.

Something along the lines of this (untested code):

int position = 0;

for (int i = 0; i < lineToGoto; i++)
{
    position += textBox.Lines[i].Length;
}

textBox.SelectionStart = position;

textBox.ScrollToCaret();


回答2:

    private void MoveCaretToLine(TextBox txtBox, int lineNumber)
    {
        txtBox.HideSelection = false;
        txtBox.SelectionStart = txtBox.GetFirstCharIndexFromLine(lineNumber - 1);
        txtBox.SelectionLength = txtBox.Lines[lineNumber - 1].Length;
        txtBox.ScrollToCaret();
    }


回答3:

This is the best solution I found:

const int EM_GETFIRSTVISIBLELINE = 0x00CE;
const int EM_LINESCROLL = 0x00B6;

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

void SetLineIndex(TextBox tbx, int lineIndex)
{
  int currentLine = SendMessage(textBox1.Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
  SendMessage(tbx.Handle, EM_LINESCROLL, 0, lineIndex - currentLine);
}

It has the benefit, that the selection and caret position is not changed.



回答4:

The looping answer to find the proper caret position has a couple of problems. First, for large text boxes, it's slow. Second, tab characters seem to confuse it. A more direct route is to use the text on the line that you want.

String textIWantShown = "Something on this line.";
int position = textBox.Text.IndexOf(textIWantShown);
textBox.SelectionStart = position;
textBox.ScrollToCaret();

This text must be unique, of course, but you can obtain it from the textBox.Lines array. In my case, I had prepended line numbers to the text I was displaying, so this made life easier.