「干货分享」DevExpress常用控件——RichEditControl使用指南

发布时间:2026/10/20 10:46:26

「干货分享」DevExpress常用控件——RichEditControl使用指南 做WinForms的一般都知道传统.NET界面有一个RichTextBox控件这个是一个富文本控件可以存储图片文字等内容它有自己的文件格式RTF在DevExpress控件组里面也有一个同等的控件他的名字是RichEditControl这个控件功能很强大它可以做邮件编辑器实现图文并茂的邮件的功能如下所示。本文主要介绍如何一步步使用这个控件实现自己需要的功能和界面。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序无论是Office风格的界面还是分析处理大批量的业务数据它都能轻松胜任DevExpress新旧版本帮助文档获取可点击这篇文章查看——《界面控件DevExpress v26.1帮助文档大全CHM版本》但是默认它没有任何工具栏全部是需要自己添加上去。如何创建带工具栏的RichEditControl控件为了使得控件更加通用我做了一个自定义控件用来实现通用文本编辑器的功能首先我们创建一个自定义控件如下所示。这样我们会看到一个空白的自定义控件界面然后再往里面添加一个RichEditControl进去设置DockFill,让RichEditControl控件铺满整个自定义控件界面如下所示。设置器ActiveViewTypeSimple让控件显示的更紧凑一些。如下所示。从上面我们看到它默认是没有任何工具栏的比较简单那么我们要添加向上面邮件界面的功能如何实现呢很简单选中RichEditControl,然后再右上角的三角符号上单击可以看到有一些功能菜单如下所示。单击Create BarManager然后可以进一步看到更多的工具栏菜单了如下所示。你可以悬着Create All Bar来创建所有工具栏然后删除多余的就可以了。这样就可以把所有的工具栏全部列出来了很多很多。但是一般我们不需要那么多精简一些重要的功能即可这些多余的最好删除否则很凌乱。这些功能按钮默认都已经带有事件的处理就是不需要额外的代码就可以实现各种标准的功能了这些很方便类似​​​​​​​DevExpress这方面做得很好如打印预览控件也是一样基本上不需要编写代码了选择需要的功能多余的删除即可这样就可以精简到我本文开头的那个邮件编辑器界面了。如何实现自定义的按钮功能刚才说到里面的按钮可以随意删除也可以随意组合到一个工具栏里面当然这个控件的工具栏除了内置的按钮外还可以增加自己的按钮和事件相应这样就更加完美和强大了。如上面的按钮就是我用来截图的一个功能自定义的内置的没有这样的功能这样添加按钮及图片后实现按钮的事件就可以了和自己创建的按钮一样。这个截图的功能利用了我的共用类库里面的一个截图类实现代码如下所示。ScreenCaptureWindow captureWindow null; private void barCapture_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { if (this.ParentForm.Owner ! null) { this.ParentForm.Owner.Hide(); } this.ParentForm.Hide(); if (captureWindow ! null) { captureWindow.BitmapCropped - new EventHandler(captureWindow_BitmapCropped); captureWindow.Dispose(); captureWindow null; } if (captureWindow null) { captureWindow new ScreenCaptureWindow(); captureWindow.BitmapCropped new EventHandler(captureWindow_BitmapCropped); } captureWindow.Show(); captureWindow.TopMost true; captureWindow.TopMost false; } void captureWindow_BitmapCropped(object sender, EventArgs e) { try { if (captureWindow.DragStop ! captureWindow.DragStart) { RichEditControl control this.richEditControl1; control.Document.InsertImage(control.Document.CaretPosition, DocumentImageSource.FromImage(captureWindow.BitmapCache)); } } finally { if (this.ParentForm.Owner ! null) { this.ParentForm.Owner.Show(); } this.ParentForm.Show(); } }这个截图直接就是把Image插入到RichEditControl里面不需要另外存储图片到文件里的这就是RichEditControl控件方便之处如果我们要实现插入图片和加载文档的方法除了使用内置按钮推荐外其实自己也可以写事件来实现的如下代码就是实现这两个简单的功能一般不需要。private void barInsertImg_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { string selectImage FileDialogHelper.OpenImage(true, ); if (!string.IsNullOrEmpty(selectImage)) { foreach (string file in selectImage.Split(new char[] { ,, ;, , })) { if (File.Exists(file)) { try { RichEditControl control this.richEditControl1; control.Document.InsertImage(control.Document.CaretPosition, DocumentImageSource.FromFile(file)); } catch { } } } } } private void barLoadFile_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { string filter Word2003(*.doc)|*.doc|Word2007(*.docx)|*.docx|RTF(*.rtf)|*.rtf|HTM(*.htm)|*.htm|HTML(*.html)|*.html|All File(*.*)|*.*; string file FileDialogHelper.Open(打开文件, filter); if (!string.IsNullOrEmpty(file)) { //string htmlContent File.ReadAllText(file, Encoding.Default); //this.richEditControl1.HtmlText htmlContent; string path Path.GetFullPath(file); string extension Path.GetExtension(file); switch (extension.ToLower()) { case .htm: case .html: this.richEditControl1.Document.LoadDocument(file, DocumentFormat.Html, path); break; case .doc: this.richEditControl1.Document.LoadDocument(file, DocumentFormat.Doc, path); break; case .docx: this.richEditControl1.Document.LoadDocument(file, DocumentFormat.OpenXml, path); break; case .rtf: this.richEditControl1.Document.LoadDocument(file, DocumentFormat.Rtf, path); break; default: this.richEditControl1.Document.LoadDocument(file, DocumentFormat.PlainText, path); break; } //DocumentRange range richEditControl1.Document.Range; //CharacterProperties cp this.richEditControl1.Document.BeginUpdateCharacters(range); //cp.FontName 新宋体; //cp.FontSize 12; //this.richEditControl1.Document.EndUpdateCharacters(cp); } }RichEditControl的特殊操作1. 文档字体修正RichEditControl控件功能是强大不过一般也需要处理一些特殊的情况由于该控件加载的时候默认好像字体都是方正姚体的字体因此感觉很不好看那么我们就要在文档加载的时候把它的字体修改下操作如下所示修改为新宋体的字体比方正姚体的好看很多。public MyRichEdit() { InitializeComponent(); this.richEditControl1.DocumentLoaded new EventHandler(richEditControl1_DocumentLoaded); } void richEditControl1_DocumentLoaded(object sender, EventArgs e) { DocumentRange range richEditControl1.Document.Range; CharacterProperties cp this.richEditControl1.Document.BeginUpdateCharacters(range); cp.FontName 新宋体; //cp.FontSize 12; this.richEditControl1.Document.EndUpdateCharacters(cp); }2. RichEditControl内置图片资源的解析RichEditControl控件支持把图片作为内嵌资源存储在里面如果我们要把他作为邮件发送我们知道邮件内容虽然是HTML的但是图片资源需要独立取出来放到LinkedResource对象作为邮件发送才能显示否则不能显示图片的。而RichEditControl默认转换出来的HTML内容是把图片作为Base64码写到文档里面文档比较大的。为了实现把图片独立提取出来我们需要一个该控件的解析类RichMailExporter代码如下所示。/// summary /// 把RichEditControl里面的内容导出为HTML和嵌入图片资源的辅助函数 /// /summary public class RichMailExporter : IUriProvider { int imageId; readonly RichEditControl control; ListLinkedAttachementInfo attachments; public RichMailExporter(RichEditControl control) { Guard.ArgumentNotNull(control, control); this.control control; } /// summary /// 导出内容和嵌入资源 /// /summary /// param namehtmlBodyHTML内容/param /// param nameattach附件资源/param public virtual void Export(out string htmlBody, out ListLinkedAttachementInfo attach) { this.attachments new ListLinkedAttachementInfo(); control.BeforeExport OnBeforeExport; htmlBody control.Document.GetHtmlText(control.Document.Range, this); control.BeforeExport - OnBeforeExport; attach this.attachments; } void OnBeforeExport(object sender, BeforeExportEventArgs e) { HtmlDocumentExporterOptions options e.Options as HtmlDocumentExporterOptions; if (options ! null) { options.Encoding Encoding.UTF8; } } #region IUriProvider Members public string CreateCssUri(string rootUri, string styleText, string relativeUri) { return String.Empty; } public string CreateImageUri(string rootUri, RichEditImage image, string relativeUri) { string imageName String.Format(image{0}, imageId); imageId; RichEditImageFormat imageFormat GetActualImageFormat(image.RawFormat); Stream stream new MemoryStream(image.GetImageBytes(imageFormat)); string mediaContentType RichEditImage.GetContentType(imageFormat); LinkedAttachementInfo info new LinkedAttachementInfo(stream, mediaContentType, imageName); attachments.Add(info); return cid: imageName; } private RichEditImageFormat GetActualImageFormat(RichEditImageFormat _RichEditImageFormat) { if (_RichEditImageFormat RichEditImageFormat.Exif || _RichEditImageFormat RichEditImageFormat.MemoryBmp) return RichEditImageFormat.Png; else return _RichEditImageFormat; } #endregion }/// summary /// 用来传递附件信息 /// /summary [Serializable] public class LinkedAttachementInfo { private Stream stream; private string mimeType; private string contentId; /// summary /// 参数构造函数 /// /summary /// param namestream附件流内容/param /// param namemimeType附件类型/param /// param namecontentId内容ID/param public LinkedAttachementInfo(Stream stream, string mimeType, string contentId) { this.stream stream; this.mimeType mimeType; this.contentId contentId; } /// summary /// 附件流内容 /// /summarypublic Stream Stream { get { return stream; } } /// summary /// 附件类型 /// /summarypublic string MimeType { get { return mimeType; } } /// summary /// 内容ID /// /summarypublic string ContentId { get { return contentId; } } }这样我们在获取编辑控件里面的HTML的同时也把里面的附件提取出来了方便我们发送邮件使用如下代码就是获取HTML内容和附件列表的其中LinkedAttachementInfo是以Stream和相关信息存在的一个实体类。string html ; ListLinkedAttachementInfo linkList new ListLinkedAttachementInfo(); RichMailExporter exporter new RichMailExporter(this.txtBody.richEditControl1); exporter.Export(out html, out linkList); MailInfo info new MailInfo(); info.Subject this.txtSubject.Text; info.Body html; info.IsBodyHtml true; info.EmbedObjects.AddRange(linkList);//添加嵌入资源 info.ToEmail this.txtRecipient.Text;//收件人这样我们发送邮件的时候写入附件数据就可以了如下代码所示。//嵌入资源的发送操作 AlternateView view AlternateView.CreateAlternateViewFromString(mailInfo.Body, Encoding.UTF8, MediaTypeNames.Text.Html); foreach (LinkedAttachementInfo link in mailInfo.EmbedObjects) { LinkedResource resource new LinkedResource(link.Stream, link.MimeType); resource.ContentId link.ContentId; view.LinkedResources.Add(resource); } mail.AlternateViews.Add(view);发送成功后我们就会看到图文并茂的邮件了。3. 内容支持搜索的操作邮件保存的时候我们可以把RichEditControl的内容作为RTF格式进行保存这样图片的资源就作为代码进行保存了这样恢复显示也很方便唯一不好的就是这些内容不好搜索建议如果要支持搜索可以通过增加另外一个文本字段把内容转换为纯文本进行保存这样加载就以RTF内容加载搜索的时候就搜索纯文本就可以了。以上就是我在使用​​​​​​​DevExpress的RichEditControl过程中碰到和解决问题的过程希望对大家有帮助共同提高。本文转载自博客园 - 伍华聪
延伸阅读

更多相关文章

2026/10/19 10:41:08

shell编程---替换运算符

替换运算符1、{: }运算符规则:1、若未定义该变量或者该变量值为空,则将用运算符后面的值赋值给该变量2、变量值不为空,不更新变量值。#! /bin/bash PRINT"Remind some import things" echo $PRINTecho ${STRING1:hello}…

2026/10/18 4:32:08

CH9102与CP2102应用注意事项

文章目录概述应用差异说明驱动说明GPIO使用说明硬件差异说明CH9102F VS CP2102N-GQFN24CH9102X VS CP2102CH9102X VS CP2102N-GQFN28其他说明CH9102资料链接概述 CH9102(WCH)与CP2102的不同子型号之间可实现pintopin兼容,可以在不更改硬件设…

2026/10/20 10:43:03

HC32F460驱动库实战:从例程到二次开发

简介:这份资源面向嵌入式开发工程师、单片机学习者及高校电子相关专业学生,提供华大HC32F460系列Cortex-M4内核单片机的完整驱动开发库与配套例程。HC32F460内置浮点运算单元,外设涵盖UART、SPI、I2C、CAN、ADC、DAC、PWM等,资源可…

2026/10/20 10:43:03

如何 5 步把游戏手柄映射为键盘鼠标?AntiMicroX 完整指南

如何 5 步把游戏手柄映射为键盘鼠标?AntiMicroX 完整指南 【免费下载链接】antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. 项目地址: https://gitcode.com/Gi…

2026/10/20 10:43:03

M5 Max上184 tok/s!Mac与Apple Silicon运行LFM2.5-24B-A2B完全指南

大模型基础模型推理模型本地部署模型量化 【免费下载链接】LFM2.5-24B-A2B-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/unsloth/LFM2.5-24B-A2B-GGUF 点击查看 免费下载 LFM2.5-24B-A2B 是 Liquid AI 推出的 240 亿参数(激活仅 20 亿&#xff0…

2026/10/20 10:38:03

多行文本溢出省略:从CSS原理到工程实践的完整指南

1. 文本截断这件事,远比想象中复杂做前端这些年,被问得最多的问题里,“怎么让文字只显示两行,多了就点点点”绝对排得进前十。看起来是个小需求,但真动手写的时候,你会发现坑一个接一个:单行截断…

2026/10/19 18:06:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/20 1:05:37

单片机C运行时从启动到多任务:中断安全与共享资源冲突

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:05:37

GCC编译四步详解:预处理、编译、汇编、链接实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:05:37

FIW线是什么?FEP注塑线与普通氟塑料线的区别及应用指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑