當(dāng)前位置:
首頁 >
Winform中使用用户控件实现带行数和标尺的RichTextBox(附代码下载)
發(fā)布時(shí)間:2025/3/19
44
豆豆
生活随笔
收集整理的這篇文章主要介紹了
Winform中使用用户控件实现带行数和标尺的RichTextBox(附代码下载)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
場(chǎng)景
RichTextBox控件允許用戶輸入和編輯文本的同時(shí)提供了比普通的TextBox控件更高級(jí)的格式特征。
效果
?
注:
博客主頁:
https://blog.csdn.net/badao_liumang_qizhi
關(guān)注公眾號(hào)
霸道的程序猿
獲取編程相關(guān)電子書、教程推送與免費(fèi)下載。
實(shí)現(xiàn)
新建一個(gè)用戶控件GuageRichTextBox。
編輯用戶控件,相當(dāng)于自己定義了一個(gè)控件,和其他控件一樣在窗體中使用,是一個(gè)類。
?
然后打開其設(shè)計(jì)頁面,放置一個(gè)RichTextBox
?
然后進(jìn)入其代碼
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms;namespace 帶行數(shù)和標(biāo)尺的RichTextBox {public partial class GuageRichTextBox : UserControl{public GuageRichTextBox(){InitializeComponent();richTextBox1.WordWrap = false;richTextBox1.Top = Distance_X;richTextBox1.Left = Distance_Y;richTextBox1.Width = this.Width - Distance_X - 2;richTextBox1.Height = this.Height - Distance_Y - 2;}#region 變量及常量const int Distance_X = 30;//設(shè)置RichTextBox控件的X位置const int Distance_Y = 30;//設(shè)置RichTextBox控件的Y位置const int SpaceBetween = 3;//設(shè)置標(biāo)尺的間距public static float thisleft = 0;//設(shè)置控件的左邊距public static float StartBitH = 0;//記錄橫向滾動(dòng)條的位置public static float StartBitV = 0;//記錄縱向滾動(dòng)條的位置const int Scale1 = 3;//設(shè)置刻度最短的線長(zhǎng)const int Scale5 = 6;//設(shè)置刻度為5時(shí)的線長(zhǎng)const int Scale10 = 9;//設(shè)置刻度為10是垢線長(zhǎng)public static float Degree = 0;//度數(shù)public static float CodeSize = 1;//代碼編號(hào)的寬度#endregion#region 屬性[Browsable(true), Category("設(shè)置標(biāo)尺控件"), Description("設(shè)置RichTextBox控件的相關(guān)屬性")] //在“屬性”窗口中顯示DataStyle屬性public RichTextBox NRichTextBox{get { return richTextBox1; }}public enum Ruler{Graduation = 0,//刻度Rule = 1,//尺子}private bool TCodeShow = false;[Browsable(true), Category("設(shè)置標(biāo)尺控件"), Description("是否在RichTextBox控件的前面添加代碼的行號(hào)")] //在“屬性”窗口中顯示DataStyle屬性public bool CodeShow{get { return TCodeShow; }set{TCodeShow = value;this.Invalidate();}}private Ruler TRulerStyle = Ruler.Graduation;[Browsable(true), Category("設(shè)置標(biāo)尺控件"), Description("設(shè)置標(biāo)尺樣式:\nGraduation為刻度\nRule為尺子")] //在“屬性”窗口中顯示DataStyle屬性public Ruler RulerStyle{get { return TRulerStyle; }set{TRulerStyle = value;this.Invalidate();}}public enum Unit{Cm = 0,//厘米Pels = 1,//像素}private Unit TUnitStyle = Unit.Cm;[Browsable(true), Category("設(shè)置標(biāo)尺控件"), Description("設(shè)置標(biāo)尺的單位:\nCm為厘米\nPels為像素")] //在“屬性”窗口中顯示DataStyle屬性public Unit UnitStyle{get { return TUnitStyle; }set{TUnitStyle = value;this.Invalidate();}}#endregion#region 事件private void GuageRichTextBox_Paint(object sender, PaintEventArgs e){e.Graphics.DrawRectangle(new Pen(Color.DarkGray), 0, 0, this.Width - 1, this.Height - 1);//繪制外邊框if (CodeShow)//如查在文本框左邊添加行號(hào){//獲取行號(hào)的寬度float tem_code = (float)StringSize((Convert.ToInt32(CodeSize+(float)(richTextBox1.Height / (StringSize(CodeSize.ToString(), richTextBox1.Font, false))))).ToString(),this.Font, true);richTextBox1.Top = Distance_X;//設(shè)置控件的頂端距離richTextBox1.Left = Distance_Y + (int)Math.Ceiling(tem_code);//設(shè)置控件的左端距離richTextBox1.Width = this.Width - Distance_X - 2 - (int)Math.Ceiling(tem_code);//設(shè)置控件的寬度richTextBox1.Height = this.Height - Distance_Y - 2;//設(shè)置控件高度thisleft = Distance_Y + tem_code;//設(shè)置標(biāo)尺的左端位置}else{richTextBox1.Top = Distance_X;//設(shè)置控件的頂端距離richTextBox1.Left = Distance_Y;//設(shè)置控件的左端距離richTextBox1.Width = this.Width - Distance_X - 2;//設(shè)置控件的寬度richTextBox1.Height = this.Height - Distance_Y - 2;//設(shè)置控件高度thisleft = Distance_Y;//設(shè)置標(biāo)尺的左端位置}//繪制文本框的邊框e.Graphics.DrawRectangle(new Pen(Color.LightSteelBlue), richTextBox1.Location.X - 1, thisleft - 1, richTextBox1.Width + 1, richTextBox1.Height + 1);e.Graphics.FillRectangle(new SolidBrush(Color.Silver), 1, 1, this.Width - 2, Distance_Y - 2);//文本框的上邊框e.Graphics.FillRectangle(new SolidBrush(Color.Silver), 1, 1, Distance_X - 2, this.Height - 2);//文本框的左邊框e.Graphics.FillRectangle(new SolidBrush(Color.Gray), 3, 3, Distance_X - 7, Distance_Y - 8);//繪制左上角的方塊邊框e.Graphics.DrawRectangle(new Pen(SystemColors.Control), 3, 3, Distance_X - 8, Distance_Y - 8);//繪制左上角的方塊if (RulerStyle == Ruler.Rule)//標(biāo)尺{//繪制上邊的標(biāo)尺背景e.Graphics.FillRectangle(new SolidBrush(Color.Gray), thisleft - 3, 3, this.Width - (thisleft - 2) , Distance_Y - 9);//繪制左上角的方塊邊框e.Graphics.DrawLine(new Pen(SystemColors.Control), thisleft - 3, 3, this.Width - 2, 3);//繪制方塊的上邊線e.Graphics.DrawLine(new Pen(SystemColors.Control), thisleft - 3, Distance_Y - 5, this.Width - 2, Distance_Y - 5);//繪制方塊的下邊線e.Graphics.FillRectangle(new SolidBrush(Color.WhiteSmoke), thisleft - 2, 9, this.Width - (thisleft - 2) - 1, Distance_Y - 19);//繪制方塊的中間塊//繪制左邊的標(biāo)尺背景e.Graphics.FillRectangle(new SolidBrush(Color.Gray), 3, Distance_Y - 3, Distance_X - 7, this.Height - (Distance_Y - 3) - 2);//繪制左邊的方塊e.Graphics.DrawLine(new Pen(SystemColors.Control), 3, Distance_Y - 3, 3, this.Height - 2);//繪制方塊的左邊線e.Graphics.DrawLine(new Pen(SystemColors.Control), Distance_X - 5, Distance_Y - 3, Distance_X - 5, this.Height - 2);//繪制方塊的右邊線e.Graphics.FillRectangle(new SolidBrush(Color.WhiteSmoke), 9, Distance_Y - 3, Distance_X - 19, this.Height - (Distance_Y - 3) - 2);//繪制方塊的中間塊}int tem_temHeight = 0;string tem_value = "";int tem_n = 0;int divide = 5;Pen tem_p = new Pen(new SolidBrush(Color.Black));//橫向刻度的設(shè)置if (UnitStyle == Unit.Cm)//如果刻度的單位是厘米Degree = e.Graphics.DpiX / 25.4F;//將像素轉(zhuǎn)換成毫米if (UnitStyle == Unit.Pels)//如果刻度的單位是像素Degree = 10;//設(shè)置10像素為一個(gè)刻度int tem_width = this.Width - 3;tem_n = (int)StartBitH;//記錄橫向滾動(dòng)條的位置if (tem_n != StartBitH)//如果橫向滾動(dòng)條的位置值為小數(shù)StartBitH = (int)StartBitH;//對(duì)橫向滾動(dòng)條的位置進(jìn)行取整for (float i = 0; i < tem_width; )//在文本框的項(xiàng)端繪制標(biāo)尺{tem_temHeight = Scale1;//設(shè)置刻度線的最小長(zhǎng)度float j = (i + (int)StartBitH) / Degree;//獲取刻度值tem_value = "";j = (int)j;//對(duì)刻度值進(jìn)行取整if (j % (divide * 2) == 0)//如果刻度值是10進(jìn)位{tem_temHeight = Scale10;//設(shè)置最長(zhǎng)的刻度線if (UnitStyle == Unit.Cm)//如果刻度的單位為厘米tem_value = Convert.ToString(j / 10);//記錄刻度值if (UnitStyle == Unit.Pels)//如果刻度的單位為像素tem_value = Convert.ToString((int)j * 10);//記錄刻度值}else if (j % divide == 0)//如果刻度值的進(jìn)位為5{tem_temHeight = Scale5;//設(shè)置刻度線為中等}tem_p.Width = 1;if (RulerStyle == Ruler.Graduation)//如果是以刻度值進(jìn)行測(cè)量{//繪制刻度線e.Graphics.DrawLine(tem_p, i + 1 + thisleft, SpaceBetween, i + 1 + thisleft, SpaceBetween + tem_temHeight);if (tem_value.Length > 0)//如果有刻度值//繪制刻度值ProtractString(e.Graphics, tem_value.Trim(), i + 1 + thisleft, SpaceBetween, i + 1 + thisleft, SpaceBetween + tem_temHeight, 0);}if (RulerStyle == Ruler.Rule)//如果是以標(biāo)尺進(jìn)行測(cè)量{if (tem_value.Length > 0)//如果有刻度值{e.Graphics.DrawLine(tem_p, i + 1 + thisleft, 4, i + 1 + thisleft, 7);//繪制頂端的刻度線e.Graphics.DrawLine(tem_p, i + 1 + thisleft, Distance_Y - 9, i + 1 + thisleft, Distance_Y - 7);//繪制底端的刻度線float tem_space = 3 + (Distance_X - 19F - 9F - StringSize(tem_value.Trim(),this.Font, false)) / 2F;//設(shè)置文本的橫向位置//繪制文本ProtractString(e.Graphics, tem_value.Trim(), i + 1 + thisleft, (float)Math.Ceiling(tem_space), i + 1 + thisleft, (float)Math.Ceiling(tem_space) + tem_temHeight, 0);}}i += Degree;//累加刻度的寬度}//縱向刻度的設(shè)置if (UnitStyle == Unit.Cm)//如果刻度的單位是厘米Degree = e.Graphics.DpiX / 25.4F;//將像素轉(zhuǎn)換成毫米if (UnitStyle == Unit.Pels)//如果刻度的單位是像素Degree = 10;//刻度值設(shè)為10像素int tem_height = this.Height - 3;tem_n = (int)StartBitV;//記錄縱向滾動(dòng)條的位置if (tem_n != StartBitV)//如果縱向滾動(dòng)條的位置為小數(shù)StartBitV = (int)StartBitV;//對(duì)其進(jìn)行取整for (float i = 0; i < tem_height; )//在文本框的左端繪制標(biāo)尺{tem_temHeight = Scale1;//設(shè)置刻度線的最小值float j = (i + (int)StartBitV) / Degree;//獲取當(dāng)前的刻度值tem_value = "";j = (int)j;//對(duì)刻度值進(jìn)行取整if (j % 10 == 0)//如果刻度值是10進(jìn)位{tem_temHeight = Scale10;//設(shè)置刻度線的長(zhǎng)度為最長(zhǎng)if (UnitStyle == Unit.Cm)//如果刻度的單位是厘米tem_value = Convert.ToString(j / 10);//獲取厘米的刻度值if (UnitStyle == Unit.Pels)//如果刻度的單位是像素tem_value = Convert.ToString((int)j * 10);//獲取像素的刻度值}else if (j % 5 == 0)//如果刻度值是5進(jìn)位{tem_temHeight = Scale5;//設(shè)置刻度線的長(zhǎng)度為中等}tem_p.Width = 1;if (RulerStyle == Ruler.Graduation)//如果是以刻度值進(jìn)行測(cè)量{//繪制刻度線e.Graphics.DrawLine(tem_p, SpaceBetween, i + 1 + Distance_Y, SpaceBetween + tem_temHeight, i + 1 + Distance_Y);if (tem_value.Length > 0)//如果有刻度值//繪制刻度值ProtractString(e.Graphics, tem_value.Trim(), SpaceBetween, i + 1 + Distance_Y, SpaceBetween + tem_temHeight, i + 1 + Distance_Y, 1);}if (RulerStyle == Ruler.Rule)//如果是以標(biāo)尺進(jìn)行測(cè)量{if (tem_value.Length > 0)//如果有刻度值{e.Graphics.DrawLine(tem_p, 4, i + 1 + Distance_Y, 7, i + 1 + Distance_Y);//繪制左端刻度線e.Graphics.DrawLine(tem_p, Distance_Y - 9, i + 1 + Distance_Y, Distance_Y - 7, i + 1 + Distance_Y);//繪制右端刻度線float tem_space = 3 + (Distance_X - 19F - 9F - StringSize(tem_value.Trim(),this.Font, false)) / 2F;//設(shè)置文本的縱向位置//繪制文本ProtractString(e.Graphics, tem_value.Trim(), (float)Math.Floor(tem_space), i + 1 + Distance_Y, (float)Math.Floor(tem_space) + tem_temHeight, i + 1 + Distance_Y, 1);}}i += Degree;//累加刻度值}if (CodeShow)//如果顯示行號(hào){//設(shè)置文本的高度float tem_FontHeight = (float)(richTextBox1.Height / (StringSize(CodeSize.ToString(), richTextBox1.Font, false)));float tem_tep = richTextBox1.Top;//獲取文本框的頂端位置int tem_mark = 0;for (int i = 0; i < (int)tem_FontHeight; i++)//繪制行號(hào){tem_mark = i + (int)CodeSize;//設(shè)置代碼編號(hào)的寬度//繪制行號(hào)e.Graphics.DrawString(tem_mark.ToString(), this.Font, new SolidBrush(Color.Red), new PointF(richTextBox1.Left - StringSize(tem_mark.ToString(), this.Font, true) - 2, tem_tep));tem_tep = tem_tep + StringSize("懂", richTextBox1.Font, false);//設(shè)置下一個(gè)行號(hào)的X坐標(biāo)值}}}private void GuageRichTextBox_Resize(object sender, EventArgs e){richTextBox1.Top = Distance_X;//設(shè)置控件的頂端位置richTextBox1.Left = Distance_Y;//設(shè)置控件的左端位置richTextBox1.Width = this.Width - Distance_X - 2;//設(shè)置控件的寬度richTextBox1.Height = this.Height - Distance_Y - 2;//設(shè)置控件的高度this.Invalidate();}private void richTextBox1_HScroll(object sender, EventArgs e){StartBitH = (int)(Math.Abs((float)richTextBox1.GetPositionFromCharIndex(0).X - 1));//檢索控件橫向內(nèi)指定字符索引處的位置this.Invalidate();}private void richTextBox1_VScroll(object sender, EventArgs e){StartBitV = (int)(Math.Abs((float)richTextBox1.GetPositionFromCharIndex(0).Y - 1));//檢索控件縱向內(nèi)指定字符索引處的位置if (CodeShow)//如果顯示行號(hào)CodeSize = (int)Math.Abs((richTextBox1.GetPositionFromCharIndex(0).Y / StringSize("懂", richTextBox1.Font, false)));//設(shè)置行號(hào)的高度this.Invalidate();}#endregion#region 方法/// <summary>/// 在指定的位置繪制文本信息/// </summary>/// <param e="Graphics">封裝一個(gè)繪圖的類對(duì)象</param>/// <param str="string">文本信息</param>/// <param x1="float">左上角x坐標(biāo)</param>/// <param y1="float">左上角y坐標(biāo)</param>/// <param x2="float">右下角x坐標(biāo)</param>/// <param y2="float">右下角y坐標(biāo)</param>/// <param n="float">標(biāo)識(shí),判斷是在橫向標(biāo)尺上繪制文字還是在縱向標(biāo)尺上繪制文字</param>public void ProtractString(Graphics e, string str, float x1, float y1, float x2, float y2, float n){float TitWidth = StringSize(str,this.Font, true);//獲取字符串的寬度if (n == 0)//在橫向標(biāo)尺上繪制文字e.DrawString(str, this.Font, new SolidBrush(Color.Black), new PointF(x2 - TitWidth / 2, y2 + 1));else//在縱向標(biāo)尺上繪制文字{StringFormat drawFormat = new StringFormat();//實(shí)例化StringFormat類drawFormat.FormatFlags = StringFormatFlags.DirectionVertical;//設(shè)置文本為垂直對(duì)齊//繪制指定的文本e.DrawString(str, this.Font, new SolidBrush(Color.Black), new PointF(x2 + 1, y2 - TitWidth / 2), drawFormat);}}/// <summary>/// 獲取文本的高度或?qū)挾?// </summary>/// <param str="string">文本信息</param>/// <param font="Font">字體樣式</param>/// <param n="bool">標(biāo)識(shí),判斷返回的是高度還是寬度</param>public float StringSize(string str,Font font,bool n)//n==true為width{Graphics TitG = this.CreateGraphics();//創(chuàng)建Graphics類對(duì)象SizeF TitSize = TitG.MeasureString(str, font);//將繪制的字符串進(jìn)行格式化float TitWidth = TitSize.Width;//獲取字符串的寬度float TitHeight = TitSize.Height;//獲取字符串的高度if (n)return TitWidth;//返回文本信息的寬度elsereturn TitHeight;//返回文本信息的高度}#endregion} }右擊項(xiàng)目,生成一下,就可以看到窗體的工具箱上面多了一組工具,可以看到我們定義的控件
?
代碼下載
https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/12240495
總結(jié)
以上是生活随笔為你收集整理的Winform中使用用户控件实现带行数和标尺的RichTextBox(附代码下载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Winform中实现右下角Popuo弹窗
- 下一篇: Winform中实现自定义水晶按钮控件(