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