Как синхронизировать прокрутку в двух RichTextBox, сохраняя соотношение? - PullRequest
1 голос
/ 13 апреля 2019

Я узнал код онлайн здесь, в самом StackOverflow: Как синхронизировать прокрутку двух многострочных текстовых полей?

Работает нормально, но я хочу пропорциональную прокрутку. Это означает, что если у меня есть два RichTextBoxes, RichTextBox1 с 10 строками и RichTextBox2 с 100 строками, то при прокрутке RichTextBox1 он будет прыгать на 10 строк RichTextBox2 на каждую 1 строку прокрутки и если я прокручиваю RichTextBox2, то прокручивает 1 строку в RichTextBox1 для каждых 10 строк в RichTextBox2.

Я думаю, что это возможно.

1 Ответ

1 голос
/ 14 апреля 2019

Конечно, есть лучшие способы сделать это (не вмешиваясь в выбор), но это, кажется, работает:

class myRTB : RichTextBox
{
    public myRTB()
    {
        this.Multiline = true;
        this.ScrollBars = RichTextBoxScrollBars.Vertical;
    }

    public myRTB Buddy { get; set; }

    private static bool scrolling;   // In case buddy tries to scroll us
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        // Trap WM_VSCROLL message and pass to buddy
        if (m.Msg == 0x115 && !scrolling && Buddy != null && Buddy.IsHandleCreated)
        {
            scrolling = true;
            synchTopLineRel(Buddy);
            scrolling = false;
        }
    }

    void synchTopLineRel(RichTextBox rtb)
    {
        int i0 = GetCharIndexFromPosition(Point.Empty);
        int i1 = GetLineFromCharIndex(i0);
        int i2 = (int)(i1 * Buddy.Lines.Length / Lines.Length);
        // the rest scrolls to line # i2..:
        int bss = Buddy.SelectionStart;
        int bsl = Buddy.SelectionLength;
        Buddy.SelectionStart = Buddy.GetFirstCharIndexFromLine(i2);
        Buddy.ScrollToCaret();
        Buddy.SelectionStart = bss;
        Buddy.SelectionLength = bsl;
    }
}

Обратите внимание, что в нем нет проверок на ошибки, и он сделает очень простой расчет. Это не будет хорошо работать с:

  • RTB с разными шрифтами
  • RTB с различными размерами

Особенно, если вам нужно закодировать событие ScelectionChanged, вы предпочтете заменить прокрутку соответствующим вызовом SetScrollPos . Возможный пример

...