详解C#之WinForm版利用RichTextBox 制作文本编辑器【附源码】

在Windows应用程序开发中,刚刚介绍了WPF版的利用RichTextBox实现文本编辑器,今天继续推出WinForm版的利用RichTextBox实现文本编辑器。本文利用一个简单的小例子,简述如何在WinForm开发中,利用RichTextBox开发文本编辑器,以及RichTextBox的用法,仅供学习分享使用,如有不足之处,还请指正。

图片

Windows窗体中的RichTextBox控件用于显示,输入和操作格式化的文本,RichTextBox除了拥有TextBox控件的所有功能外,还可以显示字体,颜色,链接,从文件中读取和加载图像,以及查找指定的字符。RichTextBox控件通常用于提供类似字体处理程序(如Microsoft Word)的文本操作和显示功能。RichTextBox控件可以显示滚动条,且默认根据需要进行显示。

涉及知识点

在本示例中,涉及知识点如下所示:

  • SelectionFont 获取或设置当前选定文本或插入点的字体。

  • FontStyle 指定应用到文本的字形信息。

  • SelectionAlignment  获取或设置应用到当前选定内容或插入点的对齐方式。

  • SelectionIndent 获取或设置所选内容开始行的缩进距离(以像素为单位)。

  • SelectionCharOffset 获取或设置控件中的文本是显示在基线上、作为上标还是作为基线下方的下标。

  • SelectionColor 获取或设置当前选定文本或插入点的文本颜色。

  • SelectionBackColor   获取或设置在 System.Windows.Forms.RichTextBox 控件中选中文本时文本的颜色。

  • SelectionBullet 获取或设置一个值,通过该值指示项目符号样式是否应用到当前选定内容或插入点。

  • Clipboard Paste 粘贴指定剪贴板格式的剪贴板内容【插入图片时使用】。

  • Find 在对搜索应用特定选项的情况下,在 System.Windows.Forms.RichTextBox 控件的文本中搜索位于控件内特定位置的字符串。

核心代码

1. 定义接口

为了规范和统一,定义实现样式接口IRichFormat,如下所示:

namespace DemoRichText.Model
{/// <summary>/// 富文本框格式/// </summary>public interface IRichFormat{void SetFormat(RichTextBox rtbInfo);}
}

2. 实现样式基类

定义一个接口的默认实现基类BaseRichFormat,此基类是抽象类,如下所示:

namespace DemoRichText.Model
{public abstract class BaseRichFormat : IRichFormat{public abstract void SetFormat(RichTextBox rtbInfo);}
}

3. 具体实现方法

具体到每一个功能样式设置,均继承自BaseRichFormat,如下所示:

namespace DemoRichText.Model
{public class DefaultRickFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){}}/// <summary>/// 加粗格式/// </summary>public class BoldRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){Font oldFont = rtbInfo.SelectionFont;Font newFont;if (oldFont.Bold){newFont = new Font(oldFont, oldFont.Style & ~FontStyle.Bold);//支持位于运算}else{newFont = new Font(oldFont, oldFont.Style | FontStyle.Bold);}rtbInfo.SelectionFont = newFont;}}/// <summary>/// 斜体/// </summary>public class ItalicRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){Font oldFont = rtbInfo.SelectionFont;Font newFont;if (oldFont.Italic){newFont = new Font(oldFont, oldFont.Style & ~FontStyle.Italic);}else{newFont = new Font(oldFont, oldFont.Style | FontStyle.Italic);}rtbInfo.SelectionFont = newFont;rtbInfo.Focus();}}/// <summary>/// 下划线/// </summary>public class UnderLineRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){Font oldFont = rtbInfo.SelectionFont;Font newFont;if (oldFont.Underline){newFont = new Font(oldFont, oldFont.Style & ~FontStyle.Underline);}else{newFont = new Font(oldFont, oldFont.Style | FontStyle.Underline);}rtbInfo.SelectionFont = newFont;rtbInfo.Focus();}}/// <summary>/// 删除线/// </summary>public class StrikeLineRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){Font oldFont = rtbInfo.SelectionFont;Font newFont;if (oldFont.Underline){newFont = new Font(oldFont, oldFont.Style & ~FontStyle.Strikeout);}else{newFont = new Font(oldFont, oldFont.Style | FontStyle.Strikeout);}rtbInfo.SelectionFont = newFont;rtbInfo.Focus();}}/// <summary>/// 左对齐/// </summary>public class LeftRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){rtbInfo.SelectionAlignment = HorizontalAlignment.Left;rtbInfo.Focus();}}/// <summary>/// 居中对齐/// </summary>public class CenterRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){if (rtbInfo.SelectionAlignment == HorizontalAlignment.Center){rtbInfo.SelectionAlignment = HorizontalAlignment.Left;}else{rtbInfo.SelectionAlignment = HorizontalAlignment.Center;}rtbInfo.Focus();}}/// <summary>/// 右对齐/// </summary>public class RightRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){if (rtbInfo.SelectionAlignment == HorizontalAlignment.Right){rtbInfo.SelectionAlignment = HorizontalAlignment.Left;}else{rtbInfo.SelectionAlignment = HorizontalAlignment.Right;}rtbInfo.Focus();}}/// <summary>/// 缩进对齐/// </summary>public class IndentRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){//每次以10个像素进行缩进rtbInfo.SelectionIndent = rtbInfo.SelectionIndent + 10;rtbInfo.Focus();}}/// <summary>/// 缩进对齐/// </summary>public class OutIndentRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){//每次以10个像素进行缩进rtbInfo.SelectionIndent = rtbInfo.SelectionIndent - 10;rtbInfo.Focus();}}/// <summary>/// 下标/// </summary>public class SubScriptRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){if (rtbInfo.SelectionCharOffset < 0){rtbInfo.SelectionCharOffset = 0;}else {rtbInfo.SelectionCharOffset = -5;}rtbInfo.Focus();}}/// <summary>/// 上标/// </summary>public class SuperScriptRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){if (rtbInfo.SelectionCharOffset > 0){rtbInfo.SelectionCharOffset = 0;}else {rtbInfo.SelectionCharOffset = 5;}rtbInfo.Focus();}}/// <summary>/// 字体/// </summary>public class FontRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){FontDialog f = new FontDialog();if (f.ShowDialog() == DialogResult.OK){FontFamily family = f.Font.FontFamily;rtbInfo.SelectionFont = new Font(family, rtbInfo.SelectionFont.Size, rtbInfo.SelectionFont.Style);}rtbInfo.Focus();}}/// <summary>/// 文本颜色/// </summary>public class ForeColorRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){ColorDialog f = new ColorDialog();if (f.ShowDialog() == DialogResult.OK){rtbInfo.SelectionColor = f.Color;}rtbInfo.Focus();}}/// <summary>/// 文本背景颜色/// </summary>public class BgColorRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){ColorDialog f = new ColorDialog();if (f.ShowDialog() == DialogResult.OK){rtbInfo.SelectionBackColor = f.Color;}rtbInfo.Focus();}}/// <summary>/// UL列表,项目符号样式/// </summary>public class UlRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){if (rtbInfo.SelectionBullet){rtbInfo.SelectionBullet = false;}else {rtbInfo.SelectionBullet = true;rtbInfo.BulletIndent = 10;}rtbInfo.Focus();}}/// <summary>/// 图片插入/// </summary>public class PicRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){OpenFileDialog o = new OpenFileDialog();o.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;o.Title = "请选择图片";o.Filter = "jpeg|*.jpeg|jpg|*.jpg|png|*.png|gif|*.gif";if (o.ShowDialog() == DialogResult.OK) {string fileName = o.FileName;try{Image bmp = Image.FromFile(fileName);Clipboard.SetDataObject(bmp);DataFormats.Format dataFormat = DataFormats.GetFormat(DataFormats.Bitmap);if (rtbInfo.CanPaste(dataFormat)){rtbInfo.Paste(dataFormat);}}catch (Exception exc){MessageBox.Show("图片插入失败。" + exc.Message, "提示",MessageBoxButtons.OK, MessageBoxIcon.Information);}}rtbInfo.Focus();}}/// <summary>/// 删除/// </summary>public class DelRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){rtbInfo.SelectedText = "";rtbInfo.Focus();}}/// <summary>/// 查找/// </summary>public class SearchRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){string find = rtbInfo.Tag.ToString();int index=  rtbInfo.Find(find, 0,RichTextBoxFinds.None);int startPos = index;int nextIndex = 0;while (nextIndex != startPos)//循环查找字符串,并用蓝色加粗12号Times New Roman标记之{rtbInfo.SelectionStart = index;rtbInfo.SelectionLength = find.Length;rtbInfo.SelectionColor = Color.Blue;rtbInfo.SelectionFont = new Font("Times New Roman", (float)12, FontStyle.Bold);rtbInfo.Focus();nextIndex = rtbInfo.Find(find, index + find.Length, RichTextBoxFinds.None);if (nextIndex == -1)//若查到文件末尾,则充值nextIndex为初始位置的值,使其达到初始位置,顺利结束循环,否则会有异常。{nextIndex = startPos;}index = nextIndex;}rtbInfo.Focus();}}/// <summary>/// 打印/// </summary>public class PrintRichFormat : BaseRichFormat{private RichTextBox richTextbox;public override void SetFormat(RichTextBox rtbInfo){this.richTextbox = rtbInfo;PrintDocument pd = new PrintDocument();pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);// 打印文档pd.Print();}private void pd_PrintPage(object sender, PrintPageEventArgs ev){//ev.Graphics.DrawString(richTextbox.Text);//ev.HasMorePages = true;}}/// <summary>/// 字体大小/// </summary>public class FontSizeRichFormat : BaseRichFormat{public override void SetFormat(RichTextBox rtbInfo){string fontSize = rtbInfo.Tag.ToString();float fsize = 0.0f;if (float.TryParse(fontSize, out fsize)) {rtbInfo.SelectionFont = new Font(rtbInfo.Font.FontFamily, fsize, rtbInfo.SelectionFont.Style);}rtbInfo.Focus();}}
}

4. 实现工厂模式

因为所有实现都基于同一个接口,所以进一步封装样式设置的实现类,如下所示:

​​​​​​​

namespace DemoRichText.Model
{public class RichFormatFactory{public static IRichFormat CreateRichFormat(BTNType btnType){IRichFormat richFormat;switch (btnType){case BTNType.Bold:richFormat = new BoldRichFormat();break;case BTNType.BGColor:richFormat = new BgColorRichFormat();break;case BTNType.Center:richFormat = new CenterRichFormat();break;case BTNType.Del:richFormat = new DelRichFormat();break;case BTNType.Font:richFormat = new FontRichFormat();break;case BTNType.ForeColor:richFormat = new ForeColorRichFormat();break;case BTNType.FontSize:richFormat = new FontSizeRichFormat();break;case BTNType.Indent:richFormat = new IndentRichFormat();break;case BTNType.Italic:richFormat = new ItalicRichFormat();break;case BTNType.Left:richFormat = new LeftRichFormat();break;case BTNType.OutIndent:richFormat = new OutIndentRichFormat();break;case BTNType.Pic:richFormat = new PicRichFormat();break;case BTNType.Print:richFormat = new PrintRichFormat();break;case BTNType.Right:richFormat = new RightRichFormat();break;case BTNType.Search:richFormat = new SearchRichFormat();break;case BTNType.StrikeLine:richFormat = new StrikeLineRichFormat();break;case BTNType.SubScript:richFormat = new SubScriptRichFormat();break;case BTNType.SuperScript:richFormat = new SuperScriptRichFormat();break;case BTNType.Ul:richFormat = new UlRichFormat();break;case BTNType.UnderLine:richFormat = new UnderLineRichFormat();break;default:richFormat = new DefaultRickFormat();break;}return richFormat;}}
}

5. UI页面代码

由于实现了代码封装,所有页面代码较少,如下所示:

namespace DemoRichText
{public partial class MainForm : Form{public MainForm(){InitializeComponent();}public void btnButtonClick(object sender, EventArgs e) {Button btn = (Button)sender;BTNType btnType;if (Enum.TryParse<BTNType>(btn.Tag.ToString(), out btnType)) {if (btnType == BTNType.Search) {if (!string.IsNullOrEmpty(this.txtSearch.Text.Trim())){this.rtbInfo.Tag = this.txtSearch.Text.Trim();}else {return;}}IRichFormat richFomat = RichFormatFactory.CreateRichFormat(btnType);richFomat.SetFormat(this.rtbInfo);}}private void combFontSize_SelectedIndexChanged(object sender, EventArgs e){float fsize = 12.0f;if (combFontSize.SelectedIndex > -1) {if (float.TryParse(combFontSize.SelectedItem.ToString(), out fsize)) {rtbInfo.Tag = fsize.ToString();IRichFormat richFomat = RichFormatFactory.CreateRichFormat(BTNType.FontSize);richFomat.SetFormat(this.rtbInfo);}return;}}}
}

示例效果图

设置文本对应的格式,具体如下所示:

图片

源码下载

关于源码下载,可关注公众号,并回复关键字WINRICH即可,如下所示:

图片

以上就是【详解C#之WinForm版利用RichTextBox 制作文本编辑器】的全部内容,关于更多详细内容,可参考官方文档。希望能够一起学习,共同进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/722572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数电票又增新票种 百望云率先推出机动车数电票解决方案

经过两年多的试点推广&#xff0c;数电票工程已经覆盖全国大部分省区市&#xff08;含计划单列市&#xff09;&#xff0c;随着系统建设的深入&#xff0c;不仅是应用功能逐渐完善&#xff0c;对票种的支持也走向全面。 2023年11月天津市正式开启机动车数电票的开具功能&#x…

SpringBoot自定义注解+反射实现 excel 导入的数据组装及字段校验

在前段时间的开发工作中&#xff0c;接手了一个很简单&#xff0c;很普通的开发任务。 要求实现一个单表的基础数据的批量导入功能。 评估下来&#xff0c;用户每次批量导入的数据量也就几千条&#xff0c;也不大。 是不是很简单&#xff0c;没有骗你们吧。但是呢&#xff0…

TB-03F-Kit 基础AT指令的使用

文章目录 前言一、使用前准备1. 确保TB-03F-Kit已经连接到电脑&#xff0c;并且已经烧录好固件。2. 准备号调试助手&#xff0c;并且电脑上已经安装好了串口驱动3. 打开串口调试助手并复位模组 二、指令介绍三、基础指令1. 准备测试2. AT 测试指令3. ATHELP 查看指令4. ATRST 模…

阻塞队列介绍

阻塞队列 kafka是目前来说性能最好的消息队列服务器&#xff0c;能处理TB级别的数据 作用:点赞、评论时&#xff0c;服务器会自动给某个用户发送通知 kafka是个框架&#xff0c;如果不用框架还要解决类似问题&#xff0c;就要用到阻塞队列 BlockingQueue 阻塞队列就是一个…

AI加速引擎PAI-TorchAcc:整体介绍与性能概述

作者&#xff1a;沈雯婷、黄奕桐、艾宝乐、王昂、李永 1、简介 PAI-TorchAcc(Torch Accelerator)是阿里云人工智能平台开发的Pytorch上的大模型训练加速框架。 PAI-TorchAcc提供了一套基于Pytorch的简洁、易用的接口&#xff0c;无需进行模型转换就可以无缝地接入HuggingFac…

Vue+OpenLayers7入门到实战目录

前言 本篇作为《VueOpenLayers7入门到实战》所有文章的二合一汇总目录&#xff0c;方便查找。 本专栏源码是由OpenLayers7.x版本结合Vue框架编写。 本专栏从Vue搭建脚手架到如何引入OpenLayers7依赖的每一步详细新手教程&#xff0c;再到通过各种入门案例和综合性的实战案例&a…

基于springboot+vue的体育馆管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

已经连接过github远程库,如何再次推送及删除远程库的内容

基于上次将文件推送到已经建好的github远程库上&#xff0c;此篇文章主要介绍如何再次推送文件去直接已经连接过的远程库&#xff0c;以此如何删除远程库中不想要的文件。 一、推送文件到远程库 1.将所需推送的文件拉入本地库所建的文件夹下&#xff1a;{ex&#xff1a;JVM相…

java面试(消息队列MQ)

MQ有什么用&#xff1f;有哪些场景&#xff1f; MQ&#xff08;MessageQueue&#xff09;消息队列。队列&#xff08;FIFO&#xff09;先进先出的数据结构&#xff0c;消息由生产者发送到MQ&#xff0c;后由消费者对消息进行处理。QQ&#xff0c;微信就是MQ场景。 MQ作用&…

搜索准确性提升 20%,Jina Reranker 成为 RAG 优化的新标杆!

在整合大型语言模型&#xff08;LLM&#xff09;到业务流程时&#xff0c;企业经常会遇到一些头疼的问题&#xff0c;比如怎样保持数据时效性、避免幻觉现象&#xff0c;以及如何保护数据安全等等。为了解决这些问题&#xff0c;检索增强生成&#xff08;RAG&#xff09;技术应…

盘点国内大厂的10个AI创作工具,看看你都用过哪些?

国内大厂的 AI 创作工具&#xff0c;目前已经非常多了&#xff0c;而且有很多都是大家耳熟能详的。 下面整理了一些&#xff0c;包含 AI 绘画、AI 视频、AI 智能体、AI 大模型等多个方向的国内大厂 AI 创作工具。 发现有几款 AI 工具&#xff0c;还真的非常好用。看看这些 AI…

深入浅出Redis(三):Redis数据的存储、删除以及淘汰

引言 Redis是一款基于键值对的数据结构存储系统&#xff0c;它的特点是基于内存操作、单线程处理命令、IO多路复用模型处理网络请求、键值对存储与简单丰富的数据结构等等 本篇文章不像以往文章围绕Redis某个特点来讲解&#xff0c;而是作为过渡介绍&#xff0c;来说一说Redi…

基于springboot的大型商场应急预案管理系统论文

大型商场应急预案管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了大型商场应急预案管理系统的开发全过程。通过分析大型商场应急预案管理系统管理的不足&#xff0c;创建了一个计算机管理大型商场应急…

软件测试开发环境、测试环境、准生产环境、生成环境

在一个项目开发到发布的整个过程中&#xff0c;会使用到很多个环境进行测试和运行项目。最基本的开发环境、测试环境、准生产环境、生成环境 一、开发环境 开发环境顾名思义就是我们程序猿自己把项目放到自己的电脑上&#xff0c;配置好以后&#xff0c;跑起来项目&#xff0…

如何器测试IP池的质量?代理IP是怎么在问卷调查中应用的呢?

在数字时代&#xff0c;数据收集和分析变得日益重要&#xff0c;而问卷调查作为一种常见的数据收集工具&#xff0c;其效率和准确性直接影响着研究的可信度和有效性。为了实现这一目标&#xff0c;代理IP在问卷调查中的应用变得愈发关键。本文旨在探讨如何测试IP池的质量&#…

真机测试——关于荣耀Magic UI系列HBuilder真机调试检测不到解决办法

​​​​​出现这种状况怎么办 1、开启USB调试 2、重点来了——我们要选择USB配置&#xff0c;选择音频来源 3、连接OK

vue3基础教程(2)——创建vue3+vite项目

博主个人微信小程序已经上线&#xff1a;【中二少年工具箱】。欢迎搜索试用 正文开始 专栏简介1. 前言2.node版本检测3.创建vue项目 专栏简介 本系列文章由浅入深&#xff0c;从基础知识到实战开发&#xff0c;非常适合入门同学。 零基础读者也能成功由本系列文章入门&#x…

javascript数组排序的方法

目录 基本用法 按照数字大小排序 按照降序排序 按照字符串长度排序 按照对象属性排序 在JavaScript中&#xff0c;数组排序通常使用Array.prototype.sort()方法。这个方法会按照指定的顺序对数组的元素进行排序&#xff0c;并返回排序后的数组。如果未指定比较函数&#x…

Springboot配置MySQL数据库

Springboot配置MySQL数据库 一、创建springboot项目&#xff0c;并添加如下依赖 <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope> </dependency>二、在applica…

基于springboot+vue的酒店管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…