2

我正在用 C# 开发一个文本编辑器,我正在尝试计算行数。

    private void updateNumberLabel()
    {
        Point pos = new Point(0, 0);
        int firstIndex = Document.GetCharIndexFromPosition(pos);
        int firstLine = Document.GetLineFromCharIndex(firstIndex);

        pos.X = ClientRectangle.Width;
        pos.Y = ClientRectangle.Height;

        int lastIndex = Document.GetCharIndexFromPosition(pos);
        int lastLine = Document.GetLineFromCharIndex(lastIndex);

        int actualLine = Document.GetLineFromCharIndex(actualPos);
        pos = Document.GetPositionFromCharIndex(lastIndex);

        if (lastLine != actualLine)
        {
            numberLabel.Text = "";
            for (int i = firstLine; i <= lastLine + 1; i++)
            {
                numberLabel.Text += i + 1 + "\n";
            }
        }
    }

它工作正常,并在您编写它们时添加行数,但如果您删除一个,它只会在您删除或添加一行时更新。

我想让它瞬间完成。如果删除一个,计数将立即减少。

4

6 回答 6

4

也许这太容易了,但那又如何:

private void richTextBox1_TextChanged(object sender, EventArgs e)
{
  var lineCount = richTextBox.Lines.Count();
  numberLabel.Text = lineCount.ToString();
}

确保将其分配给TextChanged事件。

如果这不是您所需要的,请添加更多您想要实现的信息。

于 2013-07-08T07:00:14.197 回答
1

我找到了一个开源并将其应用于这个问题。

我已经确认它运行良好并已实施。

RichTextBox 列和行

简单代码(该链接有演示源。):

this.rtb.CursorPositionChanged += 
    new System.EventHandler(this.rtb_CursorPositionChanged);
this.rtb.SelectionChanged += 
    new System.EventHandler(this.rtb_SelectionChanged);
.
.
.
private void rtb_CursorPositionChanged(object sender, System.EventArgs e)
{
    int line = rtb.CurrentLine;
    int col = rtb.CurrentColumn;
    int pos = rtb.CurrentPosition;

    statusBar.Text = "Line " + line + ", Col " + col + 
                     ", Position " + pos;
}

private void rtb_SelectionChanged(object sender, System.EventArgs e)
{
    int start = rtb.SelectionStart;
    int end = rtb.SelectionEnd;
    int length = rtb.SelectionLength;

    statusBar.Text = "Start " + start + ", End " + end + 
                     ", Length " + length;
}

namespace Nik.UserControls
{
    public class RicherTextBox2 : System.Windows.Forms.RichTextBox
    {
        public event EventHandler CursorPositionChanged;

        protected virtual void OnCursorPositionChanged( EventArgs e )
        {
            if ( CursorPositionChanged != null )
                CursorPositionChanged( this, e );
        }

        protected override void OnSelectionChanged( EventArgs e )
        {
            if ( SelectionLength == 0 )
                OnCursorPositionChanged( e );
            else
                base.OnSelectionChanged( e );
        }

        public int CurrentColumn
        {
            get { return CursorPosition.Column( this, SelectionStart ); }
        }

        public int CurrentLine
        {
            get { return CursorPosition.Line( this, SelectionStart ); }
        }

        public int CurrentPosition
        {
            get { return this.SelectionStart; }
        }

        public int SelectionEnd
        {
            get { return SelectionStart + SelectionLength; }
        }
    }

    internal class CursorPosition
    {
        [System.Runtime.InteropServices.DllImport("user32")] 
        public static extern int GetCaretPos(ref Point lpPoint);

        private static int GetCorrection(RichTextBox e, int index)
        {
            Point pt1 = Point.Empty;
            GetCaretPos(ref pt1);
            Point pt2 = e.GetPositionFromCharIndex(index);

            if ( pt1 != pt2 )
                return 1;
            else
                return 0;
        }

        public static int Line( RichTextBox e, int index )
        {
             int correction = GetCorrection( e, index );
             return e.GetLineFromCharIndex( index ) - correction + 1;
        }

        public static int Column( RichTextBox e, int index1 )
        {
             int correction = GetCorrection( e, index1 );
             Point p = e.GetPositionFromCharIndex( index1 - correction );

             if ( p.X == 1 )
                 return 1;

             p.X = 0;
             int index2 = e.GetCharIndexFromPosition( p );

             int col = index1 - index2 + 1;

             return col;
         }
    }
}
于 2019-07-05T02:38:02.167 回答
1

我真的迟到了,但 Lines 是一个字符串数组。只求长度。

richTexBox.Lines.Length.ToString();
于 2017-08-16T18:12:02.617 回答
0

洛杉矶799

抱歉回答“有点”晚了,我刚才看到了这个问题。但如果问题仍然存在,这里有一个简单的计算行数的方法,只需使用 foreach 循环:

int CountOfLines = 1;//1 because min 1 line is always in a text of a control, that has a Text property
foreach (char c in YourText)
            {
                if (c == '\r' | c == '\n')//these are all equal the ENTER key
                {
                    CountOfLines++;
                }
            }

您也可以使用 foreach 来计算字符数,但是使用 foreach 您可以选择不希望被计入字符数的字符。例如:

int CountOfCharacters = 0;//0 because by default there are no characters in a textbox or label.
foreach (char c in YourText)
            {
                if (c != '\t' & c != '\n' & c != '\r')//in this example I want to count only the characters that are not an ENTER or a TAB.
                {
                    CountOfCharacters++;
                }
            }

希望这对您和正在阅读本文的其他所有人有所帮助,即使答案有点晚。:)

于 2014-02-25T13:34:03.170 回答
-1

与其尝试使用默认的富文本框,不如尝试制作自己的控件,以便完全控制文本格式?

毕竟,如果您正在开发自己的文本编辑器,那么以对您(开发人员)有意义的方式存储和管理文本是有意义的,而不是尝试使用为稍微不同的目的而设计的格式。

于 2013-07-08T07:06:28.503 回答
-1

针对 WPF 应用程序的此问题的较新解决方案 DOK1 是 WPF 流文档 TX1 是 TextBox 控件 TX1.Text = DOK1.Blocks.Count.ToString();

于 2021-01-17T08:27:39.543 回答