c# RichTextBox是.net中一个非常不错的控件,它支持格式化文本,图片,表格,加载第三方控件的功能,但是很多时候它并不能满足我们的需求,所以我们需要对它的功能进行调整或重写
RichTextBox拖拽功能背景介绍
默认情况下RichTextBox的属性面板中有一个EnableAutoDragDrop属性
当其设置为true的时候,RichTextBox就支持拖拽的功能。当将图片/文本/表格拖拽到上方时,它就会在对应的位置加载出来
RichTextBox控件拖拽功能存在的不足
但是对于文件的拖拽规则有点不是很令人满意,拖拽之后 会将文件的图标显示出来,点击图标,系统就会调用默认的应用程序打开图片
提出问题
我想修改拖拽文件的逻辑,让其能够直接显示图片或文本的内容
解决过程
百度上的人说可以设置空间的AllowDrop属性和DragEnter、DragDrop来控制拖拽逻辑,但是找半天都没有发现RichTextBox面板上有AllowDrop属性
后来经过调试发现RichTextBox有一个AllowDrop属性,我才意识到系统并没有将RichTextBox的AllowDrop属性和拖拽时间开放到属性/事件调整面板上
经过一番周折,最后知道了需要通过程序来设置AllowDrop属性,并且以事件委托的方式来重写拖拽逻辑
public Form1()
{
InitializeComponent();
//属性面板上没有AllowDrop属性,需要通过程序写
richTextBox1.AllowDrop = true;
//事件面板上没有richTextBox拖放事件,需要通过程序写事件委托
richTextBox1.DragEnter += new DragEventHandler(richTextBox1_DragEnter);
richTextBox1.DragDrop += new DragEventHandler(richTextBox1_DragDrop);
FileProcess.checkSubFolder(Application.StartupPath, "LOG");
RichTextPath = FileProcess.getFullpathByExtension(Application.StartupPath + "\\LOG\\", FileProcess.Entension.RTF);
if (RichTextPath != "")
{
this.richTextBox1.LoadFile(RichTextPath);
}
ResultRichText = new RichTextProcess(this.richTextBox2);
//QrCode.addData("saf&号");
//QrCode qrCode = new QrCode("请");
}
private void richTextBox1_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files)
{
if (Path.GetExtension(file) == ".txt") //判断文件类型,只接受txt文件
{
StreamReader sr = new StreamReader(file, System.Text.Encoding.Default);
ResultRichText.appendTitle("拖拽处理--拖拽文本日志:");
ResultRichText.appendLine(file);
ResultRichText.appendLine(sr.ReadToEnd());
sr.Close();
}
if (Path.GetExtension(file) == ".png") //判断文件类型,只接受txt文件
{
StreamReader sr = new StreamReader(file, System.Text.Encoding.Default);
ResultRichText.appendTitle("拖拽处理--拖拽图片日志:");
ResultRichText.appendLine(file);
ResultRichText.appendLine(Image.FromStream(sr.BaseStream));
sr.Close();
}
}
}
private void richTextBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
//e.Effect = DragDropEffects.Copy;
e.Effect = DragDropEffects.Link;
}
else
{
e.Effect = DragDropEffects.None;
}
}
注意:此时必须将EnableAutoDragDrop设置为false,不然系统就会将图标再次加载进来
效果展示
优化结果
RichTextBox还可以设置段落格式
可以通过以下3个属性来控制,这三个属性在调整面板上也看不到,需要通过调试来发现
SelectionHangingIndent int 设置段落文本左侧的缩进偏移量
SelectionIndent int 设置段落文本首行的缩进
SelectionRightIndent int 设置段落文本右侧的缩进
一张图可以能容易理解该3个属性的含义
注意该三个属性以像素为单位
现在就让我们来快乐的编写代码吧
希望在将文本文件拖入RichTextBox中时能对文本文件内容进行缩进展示
修改代码
private void richTextBox1_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files)
{
if (Path.GetExtension(file) == ".txt") //判断文件类型,只接受txt文件
{
StreamReader sr = new StreamReader(file, System.Text.Encoding.Default);
ResultRichText.appendTitle("拖拽处理--拖拽文本日志:");
ResultRichText.appendLine(file);
//ResultRichText.appendLine(sr.ReadToEnd());
ResultRichText.appendContent(sr.ReadToEnd());
sr.Close();
}
if (Path.GetExtension(file) == ".png") //判断文件类型,只接受txt文件
{
StreamReader sr = new StreamReader(file, System.Text.Encoding.Default);
ResultRichText.appendTitle("拖拽处理--拖拽图片日志:");
ResultRichText.appendLine(file);
ResultRichText.appendLine(Image.FromStream(sr.BaseStream));
sr.Close();
}
}
}
其中将appendLine方法修改成appendContent方法
appendContent方法内容如下
public void appendContent(string content)
{
this.richTextBox.SelectionStart = this.richTextBox.TextLength;
this.richTextBox.SelectedText = "\r\n";
this.richTextBox.SelectionIndent = 60;
this.richTextBox.SelectionHangingIndent = -20;
this.richTextBox.SelectionRightIndent = 40;
this.richTextBox.SelectionAlignment = HorizontalAlignment.Left;
this.richTextBox.SelectedText = content;
this.richTextBox.SelectionStart = this.richTextBox.TextLength;
this.richTextBox.SelectedText = "\r\n";
this.richTextBox.SelectionIndent = 0;
this.richTextBox.SelectionHangingIndent = 0;
this.richTextBox.SelectionRightIndent = 0;
}
效果展示
拖拽HTML文件展示内容在RichTextBox中
HTML文件展示在RTF中,最简单的方法是将HTML发送到剪贴板,然后从剪贴板拷贝到RichTextBox中,但是发现RTF不支持默认一些HTML剪贴板格式粘贴,但是Word,OneNote支持,所以解决办法是通过OLE方式,先将拖拽的流数据拷贝到一个后台Word对象中,调用宏命令将剪贴板数据拷贝到临时Word文件,然后将全部的文件内容复制到剪贴板,关闭Word,粘贴剪贴板数据到RichTextBox中
private void richTextBox1_DragDrop(object sender, DragEventArgs e)
{
StreamReader sr;
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files)
{
switch (Path.GetExtension(file))
{
case ".txt"://判断文件类型为txt文件
sr = new StreamReader(file, System.Text.Encoding.Default);
ResultRichText.appendTitle("拖拽处理--拖拽文本文件日志:");
ResultRichText.appendLine(file);
//ResultRichText.appendLine(sr.ReadToEnd());
ResultRichText.appendContent(sr.ReadToEnd());
sr.Close();
break;
case ".png":
case ".jpg": //判断文件类型为png文件
case ".bmp":
sr = new StreamReader(file, System.Text.Encoding.Default);
ResultRichText.appendTitle("拖拽处理--拖拽图片文件日志:");
ResultRichText.appendLine(file);
ResultRichText.appendLine(Image.FromStream(sr.BaseStream));
sr.Close();
break;
case ".html": //判断文件类型为html文件
sr = new StreamReader(file, System.Text.Encoding.UTF8);
ResultRichText.appendTitle("拖拽处理--拖拽网页文件日志:");
ResultRichText.appendLine(file);
ResultRichText.appendHTML(sr.ReadToEnd());
sr.Close();
break;
default:
break;
}
}
}
其中appendHTML方法是将HTML文本复制到剪贴板,粘贴到RichTextBox中,内容为
internal void appendHTML(string htmlstring)
{
WFtext.ClipboardProcess.putHTML(htmlstring);
this.append("\r\n");
this.richTextBox.SelectionStart = this.richTextBox.TextLength;
this.richTextBox.Paste();
}
其中putHTML方法是将标准的HTML文本转换为可粘贴的HTML格式到剪贴板
public static void putHTML(string data)
{
string htmlstring;
htmlstring = HtmlProcess.data2html(data);//将数据转换为html
System.Windows.Forms.Clipboard.SetData(DataFormats.Html, htmlstring);
GetHTMLformDoc();
}
其中GetHTMLformDoc方法是将剪贴板数据拷贝到Word中,并将Word内容拷贝到剪贴板上 , 内容为
private static void GetHTMLformDoc(){
MSWord.Application wordApp; //Word应用程序变量
MSWord.Document wordDoc; //Word文档变量
wordApp = new MSWord.Application(); //初始化
wordApp.Visible = false;//使文档可见
//由于使用的是COM库,因此有许多变量需要用Missing.Value代替
Object Nothing = Missing.Value;
wordDoc = wordApp.Documents.Add(ref Nothing, ref Nothing, ref Nothing, ref Nothing);
//写入普通文本
wordDoc.Paragraphs.Last.Range.Text = "该文本通过Doc生成\n";
wordDoc.Paragraphs.Last.Range.Paste();
//wordDoc.SelectAllEditableRanges(Nothing);
wordDoc.ActiveWindow.Selection.WholeStory();
wordDoc.ActiveWindow.Selection.Copy();
//Word不保存关闭
object saveOption = MSWord.WdSaveOptions.wdDoNotSaveChanges;
object originalFormat = MSWord.WdOriginalFormat.wdOriginalDocumentFormat;
object routeDocument = false;
wordDoc.Close(ref saveOption, ref originalFormat, ref routeDocument);
//wordApp.Quit(ref Nothing, ref Nothing, ref Nothing);
Thread.Sleep(100);
}
效果展示
首先写一个HTML文件
预览文件内容
https://sandbox.runjs.cn/show/ut3phvlr
拷贝到本地后缀名为.html纯文本格式
拖拽HTML文件到RichTextBox中
效果展示