程序开发 > C# > Winform > 正文

C# Richtextbox 创建、设置字体颜色、添加删除读取行、每行显示指定字数、修改选中文字颜色、用红色标出行

亮术网 2020-02-24 本网原创

Richtextbox 是 C# 中的富文本编辑框,用于编辑内容比较多的文本,当然也可以用它显示文本,只要把它的背景颜色设置为与它所在控件的背景一致。Richtextbox 创建有两种方法,一种为用控件创建,另一种为用代码创建。它有很多属性,设置或修改它们既可在“属性”窗口又可用代码,本文主要探讨后者。

设置或修改 Richtextbox 字体颜色,既可用具体的颜色名称又可用RGB。Richtextbox 显示的行数与换行符分隔的行数不是一个概念,它的属性 lines 是指后者,而添加删除读取行和每行显示指定字数都是指前者。若要突出显示选中文字,可以用高亮的颜色或大的字体显示,也可以同时用两者;除可标出一行或几行外,还可标出某个指定词组。

 

一、C# Winform Richtextbox 的创建

1、从“工具箱”创建。把“工具箱”中的 Richtextbox 拖到窗体就创建了一个 Richtextbox 控件。

 

2、用代码创建。

创建一个 Richtextbox 控件,同时定义几个属性,然后把它添加到现有窗体,代码如下:

using System.Drawing;
  using System.Windows.Forms;

private void CreateRichTextBox()
  {
    RichTextBox richTextBox1 = new RichTextBox
    {
      Dock = DockStyle.None,// 不填充,若要填整个窗体,用 Dock = DockStyle.Fill
      Font = new Font("Cambria", 10),
      ForeColor = Color.Gray,
      Size = new Size(600, 400)
     };
     richTextBox1.Text = "创建一个 richTextBox 控件";
     richTextBox1.Location = new Point(10, 10);
     this.Controls.Add(richTextBox1);
  }

如果要把创建的 Richtextbox 控件添加到一个新建的窗体,只需把 this.Controls.Add(richTextBox1); 改为如下代码:

Form frm = new Form { Controls = { richTextBox1 } };
  frm.Width = 670;
  frm.Height = 520;
  frm.ShowDialog();

在窗体构造函数中调用:

public richtext()
  {
    InitializeComponent();
    CreateRichTextBox();
  }

 

二、C# Winform Richtextbox 的属性设置

1、Richtextbox 字体颜色

创建 Richtextbox 时可以定义字体颜色,如以上的 ForeColor = Color.Gray;也可以创建 Richtextbox 后定义,代码如下:

richTextBox1.ForeColor = Color.DimGray;

richTextBox1.ForeColor = Color.FromArgb(255, 108, 105, 105);

FromArgb 的第一个参数为 alpha(透明度),后三个参数为 R、G、B(红、绿、蓝)。

 

2、Richtextbox 字体大小

Font f = new Font("宋体", 10F, FontStyle.Regular, GraphicsUnit.Point);
  richTextBox1.Font = f;

如果要设置为粗体,只需把 FontStyle.Regular 改为 FontStyle.Bold,即:

Font f = new Font("宋体", 10F, FontStyle.Bold, GraphicsUnit.Point);

 

3、Richtextbox 的比例因子 ZoomFactor

修改 ZoomFactor,文字和行高会自动增大,例如把它的值改为 1.2,见如下代码:

richTextBox1.ZoomFactor = (float)1.2;

效果如图1所示:

C# Winform Richtextbox 字体颜色

图1

 

 

三、C# Winform Richtextbox 行

(一)Richtextbox 添加和插入新行

1、添加新行到最后

(1)只添加空行

richTextBox1.AppendText( Environment.NewLine); 或 richTextBox1.AppendText("\r\n");

 

(2)添加一行文字

richTextBox1.AppendText("Richtextbox 添加新行\r\n");

\r\n 为换行符,放在后表示在文字后换行;如果要在文字前换行,把它放到文字前即可。

 

2、插入新行

插入新行到第一行:

richTextBox1.Text = richTextBox1.Text.Insert(0, "插入新行到第一行\r\n");

0 表示插入到第一行,如果要插入到其它行,把 0 改为相应行号,例如插入到第 6 行,把 0 改为 6 即可。

 

3、如果 RichTextBox 的内容为空,添加到第一行,否则添加末尾,代码如下:

private void AddTextIntoRichTextBox(string text)
  {
    if (String.IsNullOrEmpty(richTextBox1.Text))
      richTextBox1.AppendText(text);
    else
      richTextBox1.AppendText( Environment.NewLine + text);

  richTextBox1.ScrollToCaret();//把控件内容滚动到当前插入符号位置
  }

 

(二)C# Winform Richtextbox 添加新行且文字为彩色

假如要把一行文字显示为三种颜色。添加文本仍用 AppendText 方法,但默认方法没有此功能,需要重载扩展,代码如下:

using System;
  using System.Windows.Forms;
  using System.Drawing;

namespace PublicClass
  {
    public static class RichTextBoxColorExtensions
    {
      public static void AppendText(this RichTextBox rtb, string text, Color color, Font font, bool isNewLine = false)
      {
        rtb.SuspendLayout();
        rtb.SelectionStart = rtb.TextLength;
        rtb.SelectionLength = 0;

      rtb.SelectionColor = color;
        rtb.SelectionFont = font;
        rtb.AppendText(isNewLine ? $"{text}{ Environment.NewLine}" : text);
        rtb.SelectionColor = rtb.ForeColor;
        rtb.ScrollToCaret();
        rtb.ResumeLayout();
      }
    }
  }

// 添加新行且文字为彩色
  private void DifferentColorRichTextBox()
  {
    string text = "沙糖桔|6元/斤|2050千克||龙眼|5元/斤|685千克||香蕉|4.5元/斤|1258千克";
    string[] arr = text.Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries);
    Font font = new Font("宋体", 12);
    string[] subArr;

  for (int i = 0; i < arr.Length; i++)
    {
      subArr = arr[i].Split('|');
      richTextBox1.AppendText(subArr[0], Color.Fuchsia, font);
      richTextBox1.AppendText(":");
      richTextBox1.AppendText(subArr[1], Color.Green, font);
      richTextBox1.AppendText(" ");
      richTextBox1.AppendText(subArr[2], Color.Blue, font, true);
    }
  }

在窗体构造函数中调用:

public richtext()
  {
    InitializeComponent();
    DifferentColorRichTextBox();
  }

效果如图2所示:

C# Winform Richtextbox 添加新行且文字为彩色

图2

 

(三)C# Winform Richtextbox 滚动到最后一行

richTextBox1.SelectionStart = richTextBox1.TextLength;//或 richTextBox1.Select(richTextBox1.TextLength, 0);
  richTextBox1.ScrollToCaret();
  richTextBox1.AppendText(richTextBox1.Text);

 

(四)C# Winform Richtextbox 行数

1、RichTextBox.Lines 含义

RichTextBox.Lines 是指“属性”窗口中 Text 右边的文字行数,不是指窗体中的文字行数。假如在 RichTextBox1 中有两行文字,如图3所示:

C# Winform Richtextbox 行数

图3

用代码:

int n = richTextBox1.Lines.Length;
  AddTextIntoRichTextBox(n.ToString());//调用上面的方法

显示它的行数,结果显示 2,如图4所示:

C# Winform RichTextBox.Lines

图4

 

2、逐行读取 RichTextBox.Lines 文本

private void ReadTextInRichTextBox()
  { 
     foreach(string l in richTextBox1.Lines)
     {
       MessageBox.Show(l);
     }
  }

 

3、读取指定行

假如要读取包含 Winform 的行,代码如下:

 private string ReadSpecificLineInRichTextBox(string specificText)
   {
    // 查找指定文字所在的位置
    int pos = richTextBox1.Find(specificText, RichTextBoxFinds.MatchCase);
    if (pos != -1)
    {
      // 根据指定文字所在的位置返回行号
      int lineNum = richTextBox1.GetLineFromCharIndex(pos);
      string text = richTextBox1.Lines.ElementAt(lineNum);
      return text;
     }
     return null;
   }

调用:

ReadSpecificLineInRichTextBox("Winform");

 

也可以用兰姆达表达式(Lambda)实现,代码如下:

private string ReadSpecificLineInRichTextBox(string specificText)
  {
    return richTextBox1.Lines.FirstOrDefault(l => l.Contains(specificText));
  }

 

4、RichTextBox 仅显示前 n 行

(1)显示前 n 行,不能指定每行字数

private void RichTextBoxDisplayNLines(int lineNum)
  {
    richTextBox1.Lines = richTextBox1.Lines.Take(lineNum).ToArray();
  }

调用(仅显示前 5 行):

RichTextBoxDisplayNLines(5);

 

(2)显示前 n 行,能指定每行字数

using System.Text.RegularExpressions;

/// <summary>
  /// 仅显示前 n 行且能指定每行字数
  /// </summary>
  /// <param name="text">文本</param>
  /// <param name="lineNum">显示行数</param>
  /// <param name="numEachLine">每行字数</param>
  /// <param name="replaceLineBreak">是否取代文本中的换行符;如果取代,所有行变一行,然后再分行;如果不取代,把原来的每行分为多行</param>
  /// <returns>每行指定字数的指定行数的文本</returns>

  private string RichTextBoxDisplayNLines(string text, int lineNum, int numEachLine, bool replaceLineBreak = false)
  {
    if (string.IsNullOrEmpty(text) || lineNum <= 0 || numEachLine <= 0)
      return null;
    if (text.Length <= numEachLine)
      return text;//当文本字数小于每行要求的字数时,返回原文本

  string lineBreak = Environment.NewLine;
    int realLen = 0;//文本以汉字为单位的长度
    int lastLen = 0;//每行实际长度
    if (replaceLineBreak)
    {
      text = Regex.Replace(text, "["[\\s]]{2,}", " ");//去掉空格
      text = Regex.Replace(text, "("[\\s]*&[n|N][b|B][s|S][p|P];"[\\s]*)+", " ");//去掉 &nbsp;
      text = text.Trim().Replace("\n", "").Replace("\r", "");
      realLen = GetTextRealLenght(ref text);
      int n = realLen / numEachLine;
      if (realLen % numEachLine > 0)
        n++;

    if (n > lineNum)
        n = lineNum;
     
      //把换行符插到每行指定字数后
      for (int i = 0; i < n; i++)
      {
        lastLen += GetTextRealLenght(ref text, numEachLine * 2, lastLen);
        if (i == 0)
        {
          if (i == n - 1)//只显示一行
            text = text.Substring(0, lastLen);
          else
            text = text.Insert(lastLen, lineBreak);
          lastLen += lineBreak.Length;
        }
        else
        {
          if (i != n - 1)//最后一行不插换行符
          {
            text = text.Insert(lastLen, lineBreak);
            lastLen += lineBreak.Length;
          }
          else
          {
            //如果原文本长度大于指定行数,只显示指定行数
            if (text.Length >= lastLen)
              text = text.Substring(0, lastLen);
          }
        }
      }
    }
    else
    {
    string[] arr = text.Split( Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
    int currLineNum = 0;
    text = string.Empty;
    bool flag = false;//最后一次是否插入过换行符
    for (int i = 0; i < arr.Length && currLineNum < lineNum; i++)
    {
      if (!string.IsNullOrEmpty(arr[i]))
      {
        realLen = GetTextRealLenght(ref arr[i]);
        int n = realLen / numEachLine;
        if (realLen % numEachLine > 0)
          n++;
        if (n == 0)
          n = 1;

      for (int j = 0; j < n && currLineNum < lineNum; j++)
        {
          lastLen += GetTextRealLenght(ref arr[i], numEachLine * 2, lastLen);

        //只有原文本的每行字数大于指定的每行字数时才重新拆分为多行
          if (realLen > numEachLine)
          {
            if (j == 0)
            {
              if (currLineNum == lineNum - 1)
              {
                arr[i] = arr[i].Substring(0, lastLen);//只显示一行
                flag = true;
              }
              else
                arr[i] = arr[i].Insert(lastLen, lineBreak);
              lastLen += lineBreak.Length;
            }
            else
            {
              //每隔每行指定个字插入一个换行符
              if (j != n - 1 && currLineNum != lineNum - 1)
              {
                arr[i] = arr[i].Insert(lastLen, lineBreak);
              }
              else
              {
                if (currLineNum == lineNum - 1 && lastLen < realLen + (j + 1) * lineBreak.Length)
                {
                  arr[i] = arr[i].Insert(lastLen, lineBreak);
                  flag = true;
                }
              }
              // 从原文本当前行截取到最后一行
              if (currLineNum == lineNum - 1 && flag)
                arr[i] = arr[i].Substring(0, arr[i].LastIndexOf(lineBreak));
              lastLen += lineBreak.Length;
            }
          }
          currLineNum++;
        }
        lastLen = 0;
        text += arr[i];
        if (currLineNum != lineNum)//不是最后一行,每段后加一个换行符
          stext += lineBreak;
      }
    }
  }
  return text;
}

//统计以汉字为单位字符个数
  private int GetTextRealLenght(ref string text)
  {
    int len = text.Length, cnNum = 0, enNum = 0;
    GetTextRealLenght(ref text, text.Length * 2, 0, ref cnNum, ref enNum);
    int enLen = enNum / 2;
    if (enNum % 2 > 0)
      enLen++;
    return cnNum + enLen;
  }

/// <summary>
  /// 统计汉字和字母个数,一个汉字或字母都算一个
  /// </summary>
  /// <param name="text">文本</param>
  /// <param name="num">指定字数</param>
  /// <param name="i">开始统计位置</param>
  /// <returns>满足条件的汉字和字母个数</returns>

  private int GetTextRealLenght(ref string text, int num, int i)
  {
    int len = text.Length, cnNum = 0, enNum = 0;
    return GetTextRealLenght(ref text, num, i, ref cnNum, ref enNum);
  }

/// <summary>
  /// 统计汉字和字母个数,一个汉字或字母都算一个
  /// </summary>
  /// <param name="text">文本</param>
  /// <param name="num">指定字数</param>
  /// <param name="i">开始统计位置</param>
  /// <param name="cnNum">汉字个数</param>
  /// <param name="enNum">字母个数</param>
  /// <returns>满足条件的汉字和字母个数</returns>

  private int GetTextRealLenght(ref string text, int num, int i, ref int cnNum, ref int enNum)
  {
    int len = text.Length;
    for (; i < len && 2 * cnNum + enNum < num; i++)
    {
      if ((int)text[i] > 128)
        cnNum++;
      else
        enNum++;
    }
    return cnNum + enNum;
  }

 

调用:

//取代原文本中的换行符:
  richTextBox1.Text = RichTextBoxDisplayNLines(richTextBox1.Text, 12, 42, true);

//不取代原文本中的换行符:
  richTextBox1.Text = RichTextBoxDisplayNLines(richTextBox1.Text, 12, 42);

效果如图5所示:

C# WinForm RichTextBox 仅显示前 n 行

图5

 

(五)C# Winform Richtextbox 删除行

1、清空 RichTextBox

richTextBox1.Clear();

 

2、删除任意指定行

/// <summary>
  /// 删除任意指定行
  /// </summary>
  /// <param name="startLineNum">开始行号</param>
  /// <param name="endLineNum">结束行号</param>

  private void DelSpecialLines(int startLineNum, int endLineNum)
  {
    //获取指定行的第一行的第一个字符的索引
    int start = richTextBox1.GetFirstCharIndexFromLine(startLineNum - 1);

  //获取指定行的最后一行的第一个字符的索引
    int end = richTextBox1.GetFirstCharIndexFromLine(endLineNum);
    richTextBox1.Select(start, end - start);//选中指定行
    richTextBox1.SelectedText = "";//设置选择行的内容为空
  }

调用:

DelSpecialLines(1, 1);//删除第 1 行

DelSpecialLines(6, 6);//删除第 6 行

DelSpecialLines(2, 4);//删除第 2 至 4 行

 

3、删除最后一行

richTextBox1.Text = richTextBox1.Text.Remove(richTextBox1.Text.Length - 1);

 

 

四、C# Winform richtextbox 修改选择文字的字体或颜色

1、右键 richtextbox,在弹出的菜单中选择“属性”,打开“属性”窗口,选择“事件”选项卡,在 SelectionChanged 右边添加 richTextBox1_SelectionChanged,然后按回车,则 richtextbox 添加选择事件,如图6所示:

C# Winform richtextbox 修改选择文字的字体或颜色

图6

 

2、然后添加如下代码:

private void richTextBox1_SelectionChanged(object sender, EventArgs e)
  {
    if (richTextBox1.SelectedText.Length > 0)
    {
      richTextBox1.SelectionFont = new Font("楷体", 14);
      richTextBox1.SelectionColor = Color.Red;
    }
  }

 

五、C# Winform richtextbox 修改文字的颜色

1、把包含指定文字的行修改为指定颜色

假如要把包含 Label 的行修改为指定颜色(如“红色”),代码如下:

private void ChangeColorForSpecialText(string specialText, Color color)
  {
    if (string.IsNullOrEmpty(specialText))
      return;

  int pos = 0;
    int lineNum;
    List<int> lst = new List<int>();
    do
    {
      if (pos != 0 && pos + specialText.Length < richTextBox1.Text.Length)
        pos += specialText.Length;//跳过要查找文字继续找

    //查找指定文本的位置
      pos = richTextBox1.Find(specialText, pos, RichTextBoxFinds.None);

    if (pos > 0)
      {
        //根据文本位置返回它所在的行号
        lineNum = richTextBox1.GetLineFromCharIndex(pos);
        lst.Add(lineNum);
      }
      if (pos + specialText.Length > richTextBox1.Text.Length - 1)
        break;
    }while (pos >= 0 && pos < richTextBox1.Text.Length);

  for (int i = 0; i < lst.Count; i++)
    {
      SelectLine(lst[i]);
      richTextBox1.SelectionColor = color;
    }
  }

//选中一行,lineNum 为行号
  private void SelectLine(int lineNum)
  {
    if (lineNum < 0)
      return;

  //根据行号返回该行第一个字符的索引
    int start = this.richTextBox1.GetFirstCharIndexFromLine(lineNum);
    int end = this.richTextBox1.GetFirstCharIndexFromLine(++lineNum);
    if (start == -1)
      return;
    else if (end == -1)//如果 end 超出文本长度,则用文本长度 - start
      end = this.richTextBox1.TextLength - start;
    else
      end = end - start;
    this.richTextBox1.Select(start, end);
  }

调用:

ChangeColorForSpecialText("Label", Color.Red);

效果如图7所示:

C# Winform richtextbox 修改文字的颜色

图7

 

2、把指定文字修改为指定颜色

private void ChangeColorForSpecialWord(string specialWord, Color color)
  {
    if (string.IsNullOrEmpty(specialWord))
      return;

  int pos = 0;
    do
    {
      if (pos != 0 && pos + specialWord.Length < richTextBox1.Text.Length)
        pos += specialWord.Length;//跳过要查找词继续找

      //查找指定词的位置
      pos = richTextBox1.Find(specialWord, pos, RichTextBoxFinds.None);
      if (pos > 0)
      {
        richTextBox1.Select(pos, specialWord.Length);
        richTextBox1.SelectionColor = color;
      }
      if (pos + specialWord.Length > richTextBox1.Text.Length - 1)
        break;
    } while (pos >= 0 && pos < richTextBox1.Text.Length);
  }

调用:

ChangeColorForSpecialWord("Panel", Color.Red);// Panel 用红色标示

效果如图8所示:

C# Richtextbox 把指定文字修改为指定颜色

图8

 

ChangeColorForSpecialWord("所示:\r4", Color.Red);// 用红色标示跨行的词(跨行查找)

效果如图9所示:

C# Richtextbox 用红色标示跨行的词(跨行查找)

图9