轉帖|其它|編輯:郝浩|2011-06-13 15:19:22.000|閱讀 2358 次
概述:出于項目的需要,本來想直接將內容寫在RichTextBox中,不過考慮到靈活性,我想,不管是誰,都會想把內容寫在一個文件里,然后去讀取它以實現這個效果。我也是這么想的,而且這個問題怎么想都不算是個難題,代碼量也不大,出于對WPF的不夠了解,這個問題居然還真的難倒我了。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
出于項目的需要,本來想直接將內容寫在RichTextBox中,不過考慮到靈活性,我想,不管是誰,都會想把內容寫在一個文件里,然后去讀取它以實現這個效果。我也是這么想的,而且這個問題怎么想都不算是個難題,代碼量也不大,出于對WPF的不夠了解,這個問題居然還真的難倒我了。
習慣winform的朋友,看到這個題,是不是也會和我一樣揮筆疾書寫下如下一段代碼呢:
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "文本文件(*.txt)|*.txt|(*.rtf)|*.rtf";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
StreamReader sr =
new StreamReader(openFileDialog1.FileName, Encoding.Default);
richTextBox1.Text = sr.ReadToEnd();
sr.Close();
}
}
這段代碼看上去其實并沒有什么異議,可是,它放錯了地方,是的,它放在了WPF的代碼頁里面,很多人會說,這又如何,不管是WPF,還是winform,甚至asp.net或者別的什么地方,代碼是不會有什么差別的吧。是的,我也一直是這么認為的,可是,編譯器報錯了,除了OpenFileDialog需要引用一個叫Microsoft.Win32的命名空間以外,還出了其他問題:
這個錯誤讓我覺得不可思議,看著熟悉的DialogResult.OK的OK和richTextBox1.Text的Text下面的紅色波浪線,我怎么都想不到還缺少什么程序集引用。這才發現,WPF中的RichTextBox居然沒有Text屬性。好吧,我投降了,這個問題我確實不會解決,上網去搜了好些代碼,包括有這么一段代碼:
private void 打開文本文件ToolStripMenuItem_Click(object sender, EventArgs e)
{
string Filename;
pictureBox1.Visible = false;
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
Filename = openFileDialog1.FileName;
if (Filename != "")
{
this.textBox1.Text = Filename;
this.richTextBox1.LoadFile(@Filename, RichTextBoxStreamType.PlainText);
}
}
}
在寫Demo的時候,一樣出錯了,this.richTextBox1.LoadFile的LoadFile下面多了紅色的波浪線,還是提示缺少程序集引用。
正是因為只顧著搜尋代碼,一心只想得到代碼的最終答案,忽視了相對來說重要的問題。既然RichTextBox沒有Text的屬性,那么也就是說,它必然會有其他的屬性來替代Text屬性的工作,一個個屬性看過去,居然發現有一個屬性叫Document,Document是文檔的意思,那么我們要讀取的也是文檔,會不會就是它呢?去MSDN里面看了看,里面有一段話這么說的:
屬性值
類型:System.Windows.Documents.FlowDocument
一個 FlowDocument 對象,表示 RichTextBox 的內容。
默認情況下,此屬性設置為空 FlowDocument。 具體地說,此空 FlowDocument 包含一個 Paragraph,而后者包含一個不包括任何文本的 Run。
很顯然,我們要的就是RichTextBox的內容,當然,要讀取的話,需要的是FlowDocument,流文檔?參考MSDN中的做法:
// Create a simple FlowDocument to serve as content.
FlowDocument flowDoc =
new FlowDocument(new Paragraph
(new Run("Simple FlowDocument")));
// Create an empty, default RichTextBox.
RichTextBox rtb = new RichTextBox();
// This call sets the contents of the RichTextBox to the specified FlowDocument.
rtb.Document = flowDoc;
//
This call gets a FlowDocument representing the contents of the RichTextBox.
FlowDocument rtbContents = rtb.Document;
這樣的話好像不是讀取電腦上已存在的txt文件,那么該怎么改變呢?我繼續在網絡中遨游。
網絡果然是很強大的,雖然網絡上幾乎沒有直接讀取txt文檔的文章,不過倒是有不少讀取rtf的文章,都是文檔,應該差別不大才對,找了不到一小會,就找到破浪的博客園里的一篇文章,和我想要的答案看似不同卻很類似://www.cnblogs.com/whitewolf/archive/2011/01/09/1931290.html
public static void LoadFromRTF(this RichTextBox richTextBox, string rtf)
{
if (string.IsNullOrEmpty(rtf))
{
throw new ArgumentNullException();
}
TextRange textRange = new TextRange
(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
using (MemoryStream ms = new MemoryStream())
{
using (StreamWriter sw = new StreamWriter(ms))
{
sw.Write(rtf);
sw.Flush();
ms.Seek(0, SeekOrigin.Begin);
textRange.Load(ms, DataFormats.Rtf);
}
}
}
在這段代碼中,我見到了一個對我來說陌生的朋友,TextRange,看到這段代碼,我突然像是找到了救星,沒錯,我要的就是它,雖然加載的是rtf,但是閉著眼睛也應該可以改成txt了,這個不費多少力氣:
public void LoadText()
{
string textFile = @ "\Win\WPFDemo\WPFDemo\Resource\test.txt";
FileStream fs;
if (File.Exists(textFile))
{
fs = new FileStream(textFile, FileMode.Open, FileAccess.Read);
using (fs)
{
TextRange text = new TextRange
(richTextBox1.Document.ContentStart, richTextBox1.Document.ContentEnd);
text.Load(fs, DataFormats.Text);
}
}
}
寫出代碼雖開心,但運行成功才是王道,很興奮的等待運行結果,居然是亂碼:
亂碼就亂碼,沒什么了不起的,停止運行后,在程序中添加一句話:StreamReader streamReader = new StreamReader(fs, System.Text.Encoding.UTF8);看你還亂碼不?哼哼~
結果居然讓我失望,果然還是亂碼,這究竟是怎么回事啊?思量了好久,沒找到原因,網絡上的方法也幾乎沒效果,找啊找,就在自己覺得絕望的時候,突然一個念頭閃過:也許不是代碼問題,可是,不是代碼問題,莫非是文本文檔的格式問題?打開文本文檔,選擇另存為,果然,問題一目了然了:
原來默認編碼是ANSI,將它改成UTF-8之后保存文件,那行代碼加不加結果都能如期運行了:
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客園