Как показать номер строки в RichTextBox C#

Я делаю простой текстовый редактор и редактор сценариев с подсветкой кода. Для этого я использую RichTextBox. Но я не знаю, как заставить его показывать номера строк на левой стороне, как в VS или Notepad++. Есть ли решение?

6 ответов


Я попытался повторно использовать код из статей codeproject, упомянутых в другом месте, но каждый вариант, на который я смотрел, казался слишком kludgy.

поэтому я построил еще один RichTextBoxEx, который отображает номера строк.

нумерация строк может быть включена или выключена. Это быстро. Он прокручивается чисто. Вы можете выбрать цвет чисел, цвета фона для градиента, толщину границы, шрифт, использовать ли ведущие нули. Вы можете выбрать для нумерации строк " as отображается" или по жесткому строк в РТБ.

примеры:

alt текст http://i39.tinypic.com/13zcoz6.jpg

alt текст http://i43.tinypic.com/wml2z9.jpg

alt текст http://i39.tinypic.com/25i4x3o.jpg

Он имеет ограничения: он отображает только цифры слева. Вы можете изменить это без особых усилий, если вам не все равно.

код разработан как C# проект. Хотя это часть большего "решения" (инструмент визуализации XPath), пользовательский RichTextBox упакован как разделяемая сборка и готов к использованию в ваших новых проектах. В Visual Studio просто добавьте ссылку на DLL, и вы можете перетащить ее на поверхность разработки. Вы можете просто отбросить другой код из более крупного решения.

код


Я бы сохранил каждую строку в классе, который имеет методы для публикации в richtextbox. В этом методе вы можете добавить номер строки на основе его позиции в классе.

например (очень грубо):

class myText
{
    public List<string> Lines;

    public string GetList()
    {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        foreach (string s in Lines)
        {
            sb.AppendFormat("{0}: {1}", i, s).AppendLine();
            i++;
        }
        return sb.ToString();
    }
}

Scintilla.Net http://scintillanet.codeplex.com/ смогло быть самым возможным решением для ваших потребностей. Но для моего проекта я использовал решение, предложенное Cheeso (RichTextBoxEx от XPath visualizer). Это просто и достаточно быстро для не очень больших документов. Все остальные компоненты .net из интернета были невероятно медленными.


самый простой способ:

Dim myArray = RichTextBox1.Text.Split()

Dim cnt As Integer = 0
RichTextBox1.Clear()

Do While cnt < myArray.Count
  RichTextBox1.AppendText(cnt & ":" & myArray(cnt) & vbNewLine)
  cnt = cnt + 1
Loop

    public int getWidth()
    {
        int w = 25;
        // get total lines of richTextBox1
        int line = richTextBox1.Lines.Length;

        if (line <= 99)
        {
            w = 20 + (int)richTextBox1.Font.Size;
        }
        else if (line <= 999)
        {
            w = 30 + (int)richTextBox1.Font.Size;
        }
        else
        {
            w = 50 + (int)richTextBox1.Font.Size;
        }

        return w;
    }

    public void AddLineNumbers()
    {
        // create & set Point pt to (0,0)
        Point pt = new Point(0, 0);
        // get First Index & First Line from richTextBox1
        int First_Index = richTextBox1.GetCharIndexFromPosition(pt);
        int First_Line = richTextBox1.GetLineFromCharIndex(First_Index);
        // set X & Y coordinates of Point pt to ClientRectangle Width & Height respectively
        pt.X = ClientRectangle.Width;
        pt.Y = ClientRectangle.Height;
        // get Last Index & Last Line from richTextBox1
        int Last_Index = richTextBox1.GetCharIndexFromPosition(pt);
        int Last_Line = richTextBox1.GetLineFromCharIndex(Last_Index);
        // set Center alignment to LineNumberTextBox
        LineNumberTextBox.SelectionAlignment = HorizontalAlignment.Center;
        // set LineNumberTextBox text to null & width to getWidth() function value
        LineNumberTextBox.Text = "";
        LineNumberTextBox.Width = getWidth();
        // now add each line number to LineNumberTextBox upto last line
        for (int i = First_Line; i <= Last_Line + 2; i++)
        {
            LineNumberTextBox.Text += i + 1 + "\n";
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        LineNumberTextBox.Font = richTextBox1.Font;
        richTextBox1.Select();
        AddLineNumbers();
    }

    private void richTextBox1_SelectionChanged(object sender, EventArgs e)
    {
        Point pt = richTextBox1.GetPositionFromCharIndex(richTextBox1.SelectionStart);
        if (pt.X == 1)
        {
            AddLineNumbers();
        }
    }

    private void richTextBox1_VScroll(object sender, EventArgs e)
    {
        LineNumberTextBox.Text = "";
        AddLineNumbers();
        LineNumberTextBox.Invalidate();
    }

    private void richTextBox1_TextChanged(object sender, EventArgs e)
    {
        if (richTextBox1.Text == "")
        {
            AddLineNumbers();
        }
    }

    private void richTextBox1_FontChanged(object sender, EventArgs e)
    {
        LineNumberTextBox.Font = richTextBox1.Font;
        richTextBox1.Select();
        AddLineNumbers();
    }

    private void LineNumberTextBox_MouseDown(object sender, MouseEventArgs e)
    {
        richTextBox1.Select();
        LineNumberTextBox.DeselectAll();
    }

    private void Form1_Resize(object sender, EventArgs e)
    {
        AddLineNumbers();
    }

вы можете добиться этого, рисуя свой собственный контроль. Вот пример, как нарисовать себя ссылке