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中
效果展示